一.布局
Flutter 里面有100多个控件,核心就是一切皆组件。
flutter常用的布局widget 有Container、Padding、Center、Row、Colum、ListView、GridView
Container
定位、调整大小的widget
主要属性:
decoration:设置布局背景颜色或者边框颜色属性。
alignment: 控制child的对齐方式,属性只会在parent 大于child的时候才会生效。
height、width:设置容器宽高
Center
控制child 在 parent 中的显示位置
Padding
设置child 到parent 边缘间距
Row |Colum
类似android 线性布局,继承 flex,多child 控件,横向|竖向 排列数据
crossAxisAlignment:
子组件沿着 横 轴(在 Row 中是纵轴)的摆放,其实就是子组件对齐方式,可选值有:
CrossAxisAlignment.start:子组件在 Row 中顶部对齐
CrossAxisAlignment.end:子组件在 Row 中底部对
CrossAxisAlignment.center:子组件在 Row 中居中对齐
CrossAxisAlignment.stretch:拉伸填充满父布局
CrossAxisAlignment.baseline:在 Row 组件中会报错
mainAxisAlignment:
子组件沿着 纵轴(在 Row 中是横轴)如何摆放,其实就是子组件排列方式,可选值有:
MainAxisAlignment.start:靠左排列
MainAxisAlignment.end:靠右排列
MainAxisAlignment.center:居中排列
MainAxisAlignment.spaceAround:每个子组件左右间隔相等,也就是 margin 相等MainAxisAlignment.spaceBetween:两端对齐,也就是第一个子组件靠左,最后一个子组件靠右,剩余组件在中间平均分散排列
MainAxisAlignment.spaceEvenly:每个子组件平均分散排列,也就是宽度相等
*控件不支持滚动 ,子View超出布局之后显示异常提示
ListView |GridView
列表控件分为,垂直列表,垂直图文列表,水平列表,动态列表,矩阵式列表
主要属性:
scrollDirection : Axis.horizontal 设置列表水平展示 Axis.vertical 列表垂直展示
padding : 设置列表内边距
resolve : 设置反向排序
children :List
ps:ListView 直接嵌套ListView 会报错
Stack 层叠组件
类似android 的framelayout和RelativeLayout
主要属性: alignment 配置所有子元素的显示位置,ps:属性也可以按比例配置。 Alignment(double,double)
children 子组件
Stack 配合Align控件可以给内部子控件指定位置 alignment
statck 配合Positioned也可以实现Align相同的效果 left,top,right,bottom,width,height
AspectRatio
AspectRatio用来设置调整子元素child 的宽高比,
Card
带有投影的组件 效果类似android 里面 cardView
Wrap 自动换行
流式布局 ,可调节spacing,runSpacing 横纵方向间距 ,
可调节alignment,runAlignment 相对父控件的位置
可配置列表元素展示方向 direction
Divider 分割线
indent: 起点缩进距离
endIndent: 终点缩进距离
color: 分割线颜色
height: 分割线区域的高度,并非分割线的高度
thickness: 分割线的厚度,真正的分割线的高度
二.状态
StatelessWidget 和 StatefulWidget组件
自定义一个组件就需要继承 StatelessWidget 或者 StatefulWidget
StatelessWidget :无状态组件,状态不可以发生改变的widget
StatefullWidget :有状态组件,持有的状态可能在widget 生命周期改变 ,可以通过setState类更新UI在需要更新页面的时
候调用setState方法 组件内部的widget build 方法会重新执行达到刷新界面的效果
调用流程:setState() -- element.markNeedsBuild() -- BuildOwner 类 scheduleBuildFor()
-- SchedulerBinding类ensureVisualUpdate() -- scheduleFrame() --
*调用setState()是至关重要的,因为这告诉框架,widget的状态已经改变,应该重绘
三.页面交互
1.GestureDetector
许多组件是没有onPressed 方法,还是实现交互可以使用这个类,上面中,onTap相当于onPressed方法,响应点击事件,而被GestureDetector包裹的可以是图片或者Column,或者其他的组件
onTapDown :在特定的位置轻触手势接触了屏¬幕
onTap:单击操作
onTapUp:在特定的位置产生了一个轻触手势并且停止接触屏幕
onTapCancel:触发了onTapDown,但是没有触发onTap
onDoubleTap:双击
onLongPress:长按事件
2.页面跳转路由设置
1.直接跳转通过 Navigator.push
eg: Navigator.push(context, MaterialPageRoute(builder: (context) {
return ParentWidget();
}));
退出页面:Navigator.pop
2.通过MaterialApp中“routes”设置页面路由,initRoute 设置默认加载页面。
eg:Navigator.pushNamed(context,"/test");
跳转传值:
eg: Navigator.pushNamed(context, "/test3",arguments: {
"data":"跳转带参数的界面,拿到了数据"
});
四.platform channel 交互
Flutter提供三种platform和dart端的消息通信方式:
BasicMessageChannel:用于传递字符串和半结构化的信息,可双向传递,有返回值。
MethodChannel:用于传递方法调用(method invocation),可双向传递,有返回值。
EventChannel: 用于数据流(event streams)的通信,仅单向传递,无返回值。
MethodChannel:使用定义key和方法要一致,android 端 ios端需要独立编写。
以下为Android端与dart端的MethodChannel示交互例代码。
使用总结:
Platform Channel 的代码在Flutter app侧的代码运行在UI Task Runner 线程中,而在android 和ios平台上运行在主线程上。因此 ,不应该在Platform端的Handler 中处理好使操作。
Platform Channel 并非线程安全的,因此在将Platform端的消息处理结果回传到Flutter端时,需要确保回调函数是在Platform Thread(就是Android 和IOS 的主线程)中执行
Platform Channel 是支持大内存数据块的传递。当需要传递大内存数据块时,需要使用BasicMessageChannel以及BinaryCodec
*以上结论来自咸鱼团队分享《深入理解Flutter Platform Channel》