Flutter不常用组件(二)
ColoredBox
一般我们想要一个带有背景颜色的组件我们会使用哪个组件?当然第一个想到的就是Container
。其实在 Flutter 中还要一个专门用来设置颜色的组件ColoredBox
。
该组件有以下几个属性:
Key? key
:标识键Color color
:颜色Widget? child
:子组件
const ColoredBox(
color: Colors.blue,
child: SizedBox.expand(),
),
ColorFiltered
颜色滤镜。
该组件有以下几个属性:
Key? key
:标识键ColorFilter colorFilter
:颜色滤镜Widget? child
:子元素
ColorFiltered(
colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.color),
child: Image.asset("assets/images/hmbb.png", fit: BoxFit.cover),
),
CompositedTransformFollower 和 CompositedTransformTarget
可以让CompositedTransformFollower
组件跟随 CompositedTransformTarget
组件移动
关于这两个组件的用法可以查看
文章:Flutter 组件 | 手牵手,一起走 CompositedTransformFollower 与 CompositedTransformTarget
视频:Flutter:如何使用Layer Link(CompositedTransformFollower、CompositedTransformTarget)
GridPaper
绘制1px宽的直线网格
Key? key
:标识键Color color
:网格线条的颜色。默认值为Color(0x7FC3E8F3)double interval
:网格中主线之间的距离,以逻辑像素为单位int divisions = 2
:每个主网格单元内的主要分区数。默认值为2int subdivisions = 5
:默认值为5Widget? child
:子组件
const SizedBox.expand(
child: GridPaper(
color: Colors.blue,
interval: 100.0,
divisions: 2,
subdivisions: 5,
child: Text("Hello World 你好世界"),
),
),
GridTile
一个带有 header 和 footer 的组件,一般放在GridView中使用,当然也可以单独使用。
Key? key
:标识键Widget? header
:头部的组件Widget? footer
:尾部的组件Widget child
:子组件(中间的组件)
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
),
itemBuilder: (context, index) {
return GridTile(
header: Align(
alignment: Alignment.topLeft,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 4),
margin: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(Radius.circular(2)),
),
child: const Text(
"Hot",
style: TextStyle(color: Colors.white, fontSize: 12),
),
),
),
footer: Container(
color: Colors.white.withOpacity(.8),
alignment: Alignment.center,
child: Text("第$index个"),
),
child: Image.asset("assets/images/sxt.jpg", fit: BoxFit.cover),
);
},
)
GridTileBar
用在GridTile
中实现AppBar
样式的组件
Key? key
:标识键Color? backgroundColor
:背景色Widget? leading
:最左边的最近Widget? title
:标题Widget? subtitle
:副标题Widget? trailing
:最右边的组件
Scaffold(
body: SafeArea(
child: GridTile(
header: GridTileBar(
backgroundColor: null,
leading: const BackButton(),
title: const Text("Favorite"),
subtitle: const Text("最近更新:今天"),
trailing: IconButton( icon: const Icon(Icons.share), onPressed: () {}),
),
footer: ButtonBar(
alignment: MainAxisAlignment.center,
children: List.generate(
5,
(index) => Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.white.withOpacity(index == _index ? 1 : .5),
borderRadius: const BorderRadius.all(Radius.circular(100)),
),
),
),
),
child: PageView.builder(
itemCount: 5,
onPageChanged: (index) {
_index = index;
setState(() {});
},
itemBuilder: (context, index) =>
Image.asset("assets/images/sxt.jpg", fit: BoxFit.cover),
),
),
),
);
IgnorePointer
IgnorePointer
和AbsorbPointer
功能一样,都能让子元素不再触发命中测试/事件。
该组件有以下几个属性:
Key? key
:标识键bool ignoring
:是否会在命中测试中吸收指针。默认为trueWidget? child
:子组件bool? ignoringSemantics
:编译语义树时是否忽略此渲染对象的语义
我们来看看这两个组件的区别:
Column(
children: [
Expanded(
child: Stack(
children: [
GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("穿过了AbsorbPointer")),
);
},
child: Container(color: Colors.blue),
),
Align(
alignment: Alignment.center,
child: AbsorbPointer(
child: ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("点击了AbsorbPointer")),
);
},
child: const Text("AbsorbPointer"),
),
),
)
],
),
),
Expanded(
child: Stack(
children: [
GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("穿过了IgnorePointer")),
);
},
child: Container(color: Colors.orange),
),
Align(
alignment: Alignment.center,
child: IgnorePointer(
child: ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("点击了IgnorePointer")),
);
},
child: const Text("IgnorePointer"),
),
),
),
],
),
),
],
)
我们可以看到,IgnorePointer
会透过自身,将点击事件传递到下一层的组件,而AbsorbPointer
并不会。
ImageFiltered
给图片增加滤镜。和BackdropFilter
使用相比更简单。
该组件有以下几个属性:
Key? key
:标识键ImageFilter imageFilter
:图片滤镜效果Widget? child
:子组件
ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 50.0, sigmaY: 50.0),
child: Image.asset("assets/images/sxt.jpg"),
),