工程中遇到的部分常用的或者必要组件记录
-
WillPopScope
class WillPopScope extends StatefulWidget {
const WillPopScope({
Key key,
@required this.child,
@required this.onWillPop,
}) : assert(child != null),
super(key: key);
参数onWillPop用来监听当用户按下返回键时child是否关闭,类型:typedef WillPopCallback = Future<bool> Function();
限定返回值的方法,可用来实现类似双击返
-
BottomNavigationBar
底部导航栏,类似TabBar
-
PageView
类ViewPage
PageView+CustomScrollView时,翻页rebuild的问题可以通过给CustomScrollView设置不同的Key来解决
其他ScrollableView应该也可以(待测试)
-
Theme常用属性
theme: new ThemeData(
primarySwatch: Colors.blue,//主色板:不需要指定颜色的空间大多使用该值,如ListView等的下拉弧线。
primaryColor: Colors.red,//原色:
primaryIconTheme: IconThemeData(color: Colors.black),//Icon的颜色,仅限自带Icons中图标
primaryTextTheme: TextTheme(title: TextStyle(color: Colors.black, fontFamily: "Aveny")),
textTheme: TextTheme(title: TextStyle(color: Colors.black))),
home: new InstaHome(),
-
Flexible
在行和列中使用该控件包裹,可以设置行和列子组件的大小比例,类似权重表示行或者列所占的比例,利用flex
属性控制行或者列中内容的收缩或者扩展模式。
-
MainAxisAlignment
如何在弹性布局中沿主轴放置子项,通常默认为MainAxisAlignment.start则通常从主轴的开始位置开始放置子组件(若为行则水平方向,列则竖直方向)。该属性不仅于Row和Column,部分其他组件亦可用。
-
CrossAxisAlignment
类MainAxisAlignment,如何在弹性布局中沿横轴放置子项。
-
MainAxisSize
主轴尺寸如min、max,常与MainAxisAlignment搭配使用
-
MediaQuery
要了解当前媒体的大小(例如,包含您应用程序的窗口),可以从MediaQuery.of:MediaQuery.of(context).size返回的MediaQueryData中读取MediaQueryData.size属性。文档入口
MediaQuery.of(context).padding.top//顶部statusBar高度
SizedBox(child: XXX(),height: deviceSize.height * 0.15, )依据屏幕比例设置组件高度
-
BoxDecoration
绘制边框。BoxDecoration类提供了多种绘制框的方法。该框具有边框,主体,并可以投射boxShadow。
BoxDecoration的形状可以是圆形或矩形。如果是矩形,则borderRadius属性控制角的圆度。
BoxDecoration的主体是分层绘制的。最底层是颜色,它填充了该框。在此之上的是渐变,渐变也填充了该框。最后是图像,其精确对齐由DecorationImage类控制。
shape或borderRadius不会修剪装饰的Container的子级。如果需要剪辑,请插入剪辑小部件(例如ClipRect,ClipRRect,ClipPath)作为Container的子级。请注意,裁剪可能会导致性能损失。也可以看看:
DecoratedBox和Container,可以使用BoxDecoration对象配置的小部件。
CustomPaint,一个小部件,可让您绘制任意图形。
Decoration,可让您定义其他装饰的基类。
-
FractionallySizedBox
child按给的比例显示大小,若给定的宽高比不一致,则依据两者中小者显示
FractionallySizedBox(
heightFactor: 0.5,
widthFactor: 0.5,
child: FlutterLogo(),
)
-
RandomContainer
背景色自由变更的Container
-
DragTarget&Draggable
拖动目标控件&拖动控件
Draggable(
child: Container(//可拖动控件原型
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.blue,
),
height: 100,
width: 100,
),
childWhenDragging: Container(//拖动时显示的Widget
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30),
color: Colors.green,
),
height: 100,
width: 100,
// color: Colors.red,
),
feedback: Container(//原控件移动之后原地丢下的Widget
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.red,
borderRadius: BorderRadius.circular(30),
),
height: 100,
width: 100,
),
)
DragTarget
DragTarget(
builder: (BuildContext context, List<dynamic> accepted, List<dynamic> rejected) => Container(
height: 200.0,
width: 200.0,
decoration: BoxDecoration(color: Colors.cyan),
child: Center(//
child: Column(children: <Widget>[Text(accpeptedData.toString()),Text(rejectData.toString())],),
),
),
onAccept: (int data) {//拖动到指定位置,且接收数据
accpeptedData = data;
},
onLeave: (int data){//拖动到指定位置之后取消
rejectData=data;
},
)
-
CircleAvatar
类似脚注或者其他注释,消息提示红点,登陆头像等。
-
Placeholder
组件占位符
-
Spacer
使用flex属性控制大小
Spacer小部件将占用任何可用空间,因此将包含Spacer的Flex容器上的Flex.mainAxisAlignment设置为MainAxisAlignment.spaceAround,MainAxisAlignment.spaceBetween或MainAxisAlignment.spaceEvenly不会产生任何可见效果:Spacer占用了所有空间 的额外空间,因此没有剩余可重新分配。
可用来调节Row、Colmun、Flex等组件
-
Visibility
visible: false控制组件是否可见
-
SearchDelegate
Scaffold中方法showSearch(),系统自带的辅助搜索功能,showSearch(context: context, delegate: DataSearch());
需要自定义Delegate继承父Delegate且实现其中的方法如下
@override
List<Widget> buildActions(BuildContext context) {
return [...];//类AppBar的Actions
}
@override
Widget buildLeading(BuildContext context) {
return ...;//头部类AppBar头部
}
@override
Widget buildResults(BuildContext context) {
return ..;//搜索结果
}
@override
Widget buildSuggestions(BuildContext context) {
return ...;//搜索提示,配合富文本之类的已输入的黑体未输入的灰体
}
-
AnimatedIcons
已实现的动画转场效果如视频播放时暂停到播放的转换,menu到arrow的转换等
_controller = AnimationController(
duration: const Duration(milliseconds: 300),
value: 1.0,
vsync: this,
);
....
AnimatedIcon(
icon: AnimatedIcons.close_menu,
semanticLabel: 'close',
progress: _controller.view,
)
progress用来控制进度,
-
RichText&TextSpan
富文本
RichText(
text: TextSpan(
text: suggestionList[index].substring(0, query.length),
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),//已输入的搜索部分
children: [
TextSpan(//未输入的部分
text: suggestionList[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
)
-
Hero
直接使用该组件包裹希望制作动画的图片或者组件(两个页面都需要),再在两个Hero组件中添加tag标签,以便Flutter规划动画的路径。
-
Align
设置相对位置
alignment: Alignment.lerp(Alignment.centerRight, Alignment.bottomRight, 0.5),)
除已经预设好的位置还可以使用上面参数自定义位置,前两参数可理解为参数,最后一个为偏移量
-
CachedNetworkImage&&Image.network
CachedNetworkImage(
imageUrl: url,
placeholder: (context,url) => CircularProgressIndicator(),//加载中View
errorWidget: (context,url,error) => new Icon(Icons.error),//加载失败的View
),
相较与Image.Network(),直接提供了加载结果的处理入口,ImageNetwork如下,跟自由度更高
Image.network(
'${Api.imgHeadHorizon}${model.backdropPath}',
height: imgHeight,
width: size.width,
fit: BoxFit.fill,
loadingBuilder: (context, widget, loadingProgress) {
if (loadingProgress != null) {//开始时为空需判断
//下面表达式中前者为当前已经下载的字节数,后者为字节总数,可通过除法获取百分比
if(loadingProgress.cumulativeBytesLoaded == loadingProgress.expectedTotalBytes){
print('(*^__^*) ');
}
}
return Container(color: Colors.cyan,);//如果没特殊要求直接返回widget就好。
},
-
Divider
分割线,对象
-
AnimatedCrossFade
AnimatedCrossFade(
firstChild: first,
secondChild: second,
firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve: const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: const Duration(milliseconds: 200),
);
两个界面的过渡,比如加载图片时默认和加载完成的过渡,或者其他叠加布局时布局切换的过渡
-
ExpansionPanelList
例子
扩展收缩的ListView或者Panel,若不是LIst可以考虑使用ExpansionTile
-
ListView&GridView滑动监听
if (controller.position.extentAfter == 0) {
}
方法二
...
-
IgnorePointer
IgnorePointer会拦截将要进入自己内部的触摸事情,并向后传递
-
Matrix4
属性如下
//scale:缩放比例
Matrix4.diagonal3Values(2, 1, 1)
Matrix4.diagonal3(v.Vector3(2, 1, 1))
Matrix4.diagonal3(v.Vector3.array([2, 1, 1]))
//transform: 移动
Matrix4.translationValues(30, 0, 0)
Matrix4.translation(v.Vector3(30, 0, 0))
Matrix4.translation(v.Vector3.array([0, -30, 0]))
//rotationZ:绕Z轴旋转
//rotationX:绕X轴旋转
//rotationY:绕Y轴旋转
Matrix4.rotationZ(pi / 6)
Matrix4(cos(pi / 6), sin(pi / 6), 0, 0,-sin(pi / 6), cos(pi / 6), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
//columns:设置一个新的矩阵
//compose:复合平移、旋转、缩放,形成新的状态
Matrix4.columns( Vector3 translation, Quaternion rotation, Vector3 scale)
//copy:复制一个4*4的张量(矩阵)
//identity:恢复初始状态,也就是4*4的单位矩阵
//inverted:取相反的矩阵,就是反着来
//outer(合并)、skew(扭曲)、skewX(x轴扭曲)、skewY(y轴扭曲)、zero(置零矩阵)、fromList(将一个16位的一维数组转换成4*4的矩阵)
-
NotificationListener(widget) 监听其子View滑动状态。子View的滚动事件并发送通知
NotificationListener<ScrollNotification>(//只接受某个子类型的通知
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: 900,
width: double.infinity,
color: Colors.red,
)
],
),
),
onNotification: (_){print('1111111');},//返回true则事件不在传递,false则继续往父控件传递
),
child通常为scrollableView
ScrollStartNotification,它指示小部件已开始滚动。通常为最先接收到的Notification
零个或多个ScrollUpdateNotifications(指示小部件已更改其滚动位置)
零个或多个ScrollUpdateNotifications与零个或多个OverscrollNotifications混合,指示小部件未更改其滚动位置,因为更改会导致其滚动位置超出其滚动范围。如滚动到最顶部或者最底部
与ScrollUpdateNotifications和OverscrollNotifications穿插的是零个或多个UserScrollNotifications,它们表示用户已更改其滚动方向。如水平滑动之后直接竖直滑动会调用UserScrollNotifications
ScrollEndNotification,它指示小部件已停止滚动。标志滚动事件结束
一个UserScrollNotification,其ScrollDirection.idle的UserScrollNotification.direction。
滑动事件从开始到结束 ScrollStartNotification--->UserScrollNotification(从无到有和从有到无都算变化)--->OverscrollNotification/ScrollUpdateNotifications--->ScrollEndNotification--->UserScrollNotificationnotification.depth=0/1/...表示监听的深度,通常处理深度为0的及多层可滚动只处理当前子控件的滚动
-
CustomScrollView
结合了ScrollView和SliverAppBar(基于SliverPersistentHeader实现)的控件
Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(//折叠头部
title: Text('SliverDemoPage'),
centerTitle: true,
expandedHeight: 300,
forceElevated: true,
pinned: true,//折叠后不消失
floating: true,// 当有下滑手势的时候,就会显示 AppBar
snap: true,// 当下滑到一定比例,会自动把 AppBar 展开
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: Image.asset(
'images/joker.jpg',
fit: BoxFit.fill,
),
),
),
SliverFillRemaining(child: Center(child: Text('填充剩余空间'),),)//填充剩余空间
],
),
);
Slivers相关
- SliverFillViewport
- SliverFillRemaining
- SliverFixedExtentList
- SliverToBoxAdapter
- SliverPadding
- SliverPersistentHeader&SliverPersistentHeaderDelegate(SliverAppBar的内部实现)
若CustomScrollView底部横向和纵向滚动的冲突目前没有解决办法
-
NestedScrollView
- SliverOverlapAbsorber
- SliverOverlapInjector
Scrollbar
AnimationController
动画的控制器。
此类可让您执行以下任务:
向前或向后播放动画,或停止动画。
将动画设置为特定值。
定义动画的upperBound和LowerBound值。
使用物理模拟创建猛冲动画效果。
默认情况下,AnimationController在给定的持续时间内线性生成的值介于0.0到1.0之间。 每当运行您的应用的设备准备显示新帧时,动画控制器都会生成一个新值(通常,此速率约为每秒60个值)。
Listenable
维护侦听器列表的对象。
侦听器通常用于通知客户端对象已更新。
此接口有两种变体:
ValueListenable,一个使用当前值的概念扩展Listenable接口的接口。
动画,一个扩展ValueListenable接口以添加方向(正向或反向)概念的接口。
Flutter API中的许多类都使用或实现这些接口。 以下子类特别相关:
ChangeNotifier,可以将其子类化或混入以创建实现Listenable接口的对象。
ValueNotifier,它使用可变值实现ValueListenable接口,该可变值在修改后会触发通知。
CurvedAnimation
将曲线应用于另一个动画的动画。
当您想对动画对象应用非线性曲线时,特别是在动画前进和后退时想要不同的曲线时,CurvedAnimation很有用。
根据给定的曲线,CurvedAnimation的输出范围可能比其输入范围大。 例如,诸如Curves.elasticIn之类的弹性曲线将大大超出或低于默认范围0.0到1.0。
Interval
直到开始时为0.0的曲线,然后从开始处的0.0弯曲到结束处的弯曲(根据曲线),然后在结束处保持1.0。
间隔可用于延迟动画。 例如,使用Interval(开始时间设置为0.5,结束时间设置为1.0)的Interval的六秒钟动画实际上将变成三秒钟的动画,该动画在三秒钟后开始。
Opacity(
opacity: CurvedAnimation(
parent: ReverseAnimation(animation),
curve: const Interval(0.5, 1.0),// Curves.***(easeInOut)
).value,
child: const Text('Select a Category'),
),
AnimatedWidget
当给定的Listenable更改值时重建的小部件。
AnimatedWidget最常与可收听的Animation对象一起使用,但可与任何Listenable(包括ChangeNotifier和ValueNotifier)一起使用。
AnimatedWidget对于否则为无状态的小部件最有用。 要使用AnimatedWidget,只需将其子类化并实现build函数。
BackDropTitle({Key key, Listenable listenable}) : super(key: key, listenable: listenable);
@override
Widget build(BuildContext context) {
//animation extends Listenable
final Animation<double> animation = listenable;
return DefaultTextStyle(
style: Theme.of(context).textTheme.title,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: Stack(
children: <Widget>[
Opacity(opacity: CurvedAnimation(parent: ReverseAnimation(animation), curve: Curves.easeInOut).value)
],
),
);
}
RotatedBox
RotatedBox(
quarterTurns: 1, //1顺时针90度,2顺时针180度,3 顺时针270度 ,4顺时针360度
child: Text("Hello world")
),
LayoutBuilder
大小不确定的布局,绘制时返回大小,可以根据大小返回不同布局
Material
const Material({
Key key,
this.type = MaterialType.canvas,
this.elevation = 0.0,
this.color,
this.shadowColor = const Color(0xFF000000),
this.textStyle,
this.borderRadius,
this.shape,
this.borderOnForeground = true,
this.clipBehavior = Clip.none,
this.animationDuration = kThemeChangeDuration,
this.child,
})
一个属性比较全的小控件,形状,圆角,裁剪等
ListTileTheme
一个继承的窗口小部件,它为该窗口小部件的子树中的ListTiles定义颜色和样式参数。
此处指定的值用于没有指定显式非null值的ListTile属性。
Drawer小部件为其子级指定一个tile主题,该主题将样式设置为ListTileStyle.drawer。
*了狗了 一万个小部件
PositionedTransition
Positioned的动画版本,采用特定的Animation <RelativeRect>在动画的整个生命周期中将孩子的位置从开始位置转换到结束位置。
仅当它是Stack的子代时才有效。
这是PositionedTransition小部件的图示,其由设置为Curves.elasticInOut的CurvedAnimation进行矩形动画处理: