常用的容器类控件有哪些(Flutter基础控件介绍)
Posted
篇首语:善行无辙迹、善言无瑕谪。本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用的容器类控件有哪些(Flutter基础控件介绍)相关的知识,希望对你有一定的参考价值。
常用的容器类控件有哪些(Flutter基础控件介绍)
StatefulWidget
动态组件,开发中需要改变状态,使用动态组件
StatelessWidget
静态组件,定义后不会再改变
组件按照功能分类
1. 基础类组件
基础组件
Text(文本),Image(图片),xxButton(按钮),TextField(输入框),Form(表单)
Text(\'Hello World\');
Form
单独说一下Form组件
实际业务中,在正式向服务器提交数据前,都会对各个输入框数据进行合法性校验,但是对每一个TextField都分别进行校验将会是一件很麻烦的事。还有,如果用户想清除一组TextField的内容,除了一个一个清除有没有什么更好的办法呢?为此,Flutter提供了一个Form widget,它可以对输入框进行分组,然后进行一些统一操作,如输入内容校验、输入框重置以及输入内容保存。
Form的子孙元素必须是FormField类型,FormField是一个抽象类,定义几个属性,FormState内部通过它们来完成操作。https://book.flutterchina.club/chapter3/input_and_form.html
2. 布局类组件
Row(水平线性布局),Column(垂直线性布局),Flex(弹性布局),Wrap|Flow(流式布局),Stack|Positioned(层叠布局)
线性布局(Row、Column)
Column( crossAxisAlignment: CrossAxisAlignment.start,//子控件对齐方式 mainAxisSize: MainAxisSize.max, //自身大小 children: <Widget>[], //子控件)
弹性布局(Flex)
Flex( direction: Axis.horizontal, children: <Widget>[ Expanded( child: Container( height: 30, color: Colors.red,), flex: 1,), Expanded( child: Container( height: 30, color: Colors.blue,), flex: 2, ),],),
Flex里面的两个Expanded按照1:2平分。
流式布局(Wrap、Flow)
- Wrap直接使用,超过屏幕自动换行
- Flow需要自己算,性能较好,换行规则自己定
Flow因为计算复杂使用较少,优先考虑Wrap是否能实现
https://book.flutterchina.club/chapter4/wrap_and_flow.html
层叠布局(Stack、Positioned)
- Stack类似Android中的FrameLayout,子Widget根据到四个角的位置来确定本身的位置,允许子Widget堆叠。
- Flutter中联合使用Stack和Positioned来实现绝对定位,Stack允许子Widget堆叠,Positioned可以给子Widget定位。
依据Flutter中的万物皆Widget,所以Positioned这个Widget是一个设置位置的Widget,目的只是给子Widget设置位置。
3. 容器类组件
Padding(添加补白),ConstrainedBox|SizedBox(限制类容器),DecoratedBox(装饰类容器),Transform(变换),Container,其他
布局类Widget和容器类Widget的区别
- 布局类Widget一般接收一个Widget数组(children),直接或间接继承自(包含)MultiChildRenderObjectWidget,容器类Widget一般只需要接收一个Widget(child),直接或间接继承自(包含)SingleChildRenderObjectWidget;
- 布局类Widget是按照一定的排列方式来对其子Widget进行排列;而容器类Widget一般只是包装其子Widget,对其添加一些修饰(补白或背景色等)、变换(旋转或剪裁等)、或限制(大小等)。
Padding
可以给子节点添加补白,Flutter中给Widget添加间距也单独抽出Widget
限制类容器(ConstrainedBox、SizedBox)
ConstrainedBox用于添加对子Widget的限制
ConstrainedBox( constraints: BoxConstraints(//用于设置限制条件 minWidth: double.infinity, //宽度尽可能大 minHeight: 50.0 //最小高度为50像素 ), child: Widget,)
SizedBox用于给子Widget指定固定的宽高
SizedBox( width: 80.0, height: 80.0, child: redBox)
装饰容器(DecoratedBox)
const DecoratedBox( Decoration decoration, DecorationPosition position = DecorationPosition.background, Widget child)
使用Decoration的实现类去装饰子Widget(BoxDecoration)
BoxDecoration( Color color, //颜色 DecorationImage image,//图片 BoxBorder border, //边框 BorderRadiusGeometry borderRadius, //圆角 List<BoxShadow> boxShadow, //阴影,可以指定多个 Gradient gradient, //渐变 BlendMode backgroundBlendMode, //背景混合模式 BoxShape shape = BoxShape.rectangle, //形状)
变换(Transform、RotateBox)
Transform可以实现4D矩阵变换(Matrix4)、位移(offset)、旋转(rotate)、缩放(scale);
注意:Transform只应用于绘制阶段,不应用于layout阶段,所以无论对子Widget做何种变换,其在屏幕上的位置和占用空间的大小是不会变的
RotateBox和Transform的功能类似,但是它作用于layout阶段,会影响子Widget的位置和占用空间大小。
Container
Container是各种DecoratedBox、ConstrainedBox、Transform、Padding、Align等widget的一个组合widget,可以同时实现装饰、变换、限制的功能,
此外margin的补白是在容器外部,而padding的补白是在容器内部
其他 Scaffold
Scaffold,由Flutter Material库提供,是一个路由页的骨架,可以非常容易的拼装出一个完整的页面
AppBar是一个Material风格的导航栏,它可以设置标题、导航栏菜单、底部Tab等
TabBar生成一个静态的菜单,TabBarView配合TabBar实现左右切换的View,抽屉菜单Drawer,FloatingActionButton悬浮在页面的某一个位置作为某种常用动作的快捷入口
4.可滚动Widget
SingleChildScrollView,ListView,GridView,CustomScrollView,滚动监听和控制ScrollController。
当内容超过显示窗口(ViewPort)的时候,Flutter就会提示Overflow错误,因此需要滚动Widget,可滚动的Widget都直接或者间接包含Scrollable widget。
SingleChildScrollView
类似Android中的ScrollView,只接收一个子Widget
ListView
ListView最常用的可滚动widget
ListView( ... //可滚动widget公共参数 Axis scrollDirection = Axis.vertical,//滚动方向 bool reverse = false,//是否反向(从右到左) ScrollController controller,//控制滚动位置和监听滚动事件 bool primary,//是否使用Widget树中默认的PrimaryScrollController ScrollPhysics physics,//接收一个ScrollPhysics参数 EdgeInsetsGeometry padding, //ListView各个构造函数的共同参数 double itemExtent,//强制item的高度,相对不设置会高效 bool shrinkWrap = false, bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, double cacheExtent, //子widget列表 List<Widget> children = const <Widget>[],)
physics:决定可滚动widget怎样响应用户的操作,比如滑动完抬起手指,或滑动到边界时如何显示
- ClampingScrollPhysics:Android下微光效果。
- BouncingScrollPhysics:iOS下弹性效果。
addAutomaticKeepAlives:是否将列表项(子Widget)包裹在AutomaticKeepAlive widget中,典型的,在一个懒加载列表中,如果列表项包裹在AutomaticKeepAlive中,列表项移出视口时该列表项不会GC,会使用KeepAliveNotification来保存其状态。如果列表项自己维护KeepAlive状态,则此项为false。
addRepaintBoundaries:是否将列表项(子Widget)包裹在RepaintBoundary中。将列表项包裹在RepaintBoundary中可以避免在滚动的时候重绘,但重绘开销非常小的时候,不添加RepaintBoundary反而会高效。
ListView 的构造函数
默认构造函数
ListView( shrinkWrap: true, padding: const EdgeInsets.all(20.0), children: <Widget>[ const Text("Im dedicating every day to you"), const Text("Domestic life was never quite my style"), const Text("When you smile, you knock me out, I fall apart"), const Text("And I thought I was so smart"), ],);
默认构造函数会把所有的子widget提前创建好。
ListView.builder构造函数
ListView.builder( // ListView公共参数已省略 ... @required IndexedWidgetBuilder itemBuilder, //列表的构造器,返回一个Widget int itemCount,//列表项的数量,null表示无限 ...)
ListView.separated构造函数
比ListView.build多一个separatorBuilder,用于生成分割线。
GridView
基本和ListView相同,有个一SliverGridDelegate gridDelegate参数,用于控制子widget如何排列。
两个实现类:
SliverGridDelegateWithFixedCrossAxisCount 横轴为固定数量子元素,
SliverGridDelegateWithMaxCrossAxisExtent 横轴子元素为固定最大长度的layout算法。
默认构造函数
GridView()
GridView.count构造函数
内部使用SliverGridDelegateWithFixedCrossAxisCount去创建横轴为固定数量的GridView。
GridView.extent构造函数
内部使用了SliverGridDelegateWithMaxCrossAxisExtent去创建横轴子元素为固定最大长度的算法。
GridView.builder构造函数
GridView.builder( ... @required SliverGridDelegate gridDelegate, @required IndexedWidgetBuilder itemBuilder, //子widget构造方法)
Pub上有一个包“flutter_staggered_grid_view” ,它实现了一个交错GridView的布局,子widget大小不一样。
CustomScrollView
CustomScrollView是可以使用Sliver自定义滚动模型(效果)的widget。CustomScrollView可以把彼此独立的可滚动的widget(Sliver)“粘”起来。
可滚动的widget如ListView,GridView都有对应的Sliver实现SliverList,SliverGrid。对于大多数Sliver来说,他们和可滚动的widget的区别是Sliver不包含Scrollable widget,本身Sliver不包含滚动模型,这些widget公用CustomScrollView的Scrollable,最终实现统一滚动效果。
https://book.flutterchina.club/chapter6/custom_scrollview.html
滚动监听及控制ScrollController
可以通过ScrollController来控制Scrollable widget的滚动位置,滚动事件传递等。
ScrollController构造函数
ScrollController( double initialScrollOffset = 0.0, //初始滚动位置 this.keepScrollOffset = true, //是否保存滚动位置)
常用方法和属性offset:可滚动组件当前滚动的位置;jumpTo(double offset)、animateTo(double offset)
跳转到指定位置。
滚动监听
ScrollController间接继承自Listenable,可以监听滚动事件
controller.addListener(()=>print(controller.offset));
滚动位置恢复
PageStorage是用于保存页面(路由)相关数据的Widget,是一个功能型widget,不影响子树的UI外观,它拥有一个存储桶(bucket),子树中的widget可以通过指定不同的PageStorageKey来存储各自的数据或状态。
需要配合keepScrollOffset使用,为true的时候,会记录滚动位置。
当一个路由中包括多个Scrollable widget的时候,在进行一些跳转操作后,滚动位置不能正确恢复,这时可以显式给Scrollable widget指定PageStoreKey来分别跟踪。
并非一个路由包含多个Scrollable widget时,就需要使用PageStoreKey分别跟踪,因为它们都是StatefullWidget,只要widget没有被从树上detach掉,其state就不会销毁(dispose),滚动位置就不会丢失。
ScrollPosition
ScrollController可以被多个Scrollable widget使用,ScrollController会为每个Scrollable widget创建一个ScrollPosition,这些ScrollPosition保存在ScrollController的position中。ScrollPosition是真正保存滑动位置信息的对象,offset只是一个便捷属性。
ScrollPosition有animateTo(),jumpTo(),来控制真正跳转滚动位置的方法,ScrollController的两个同名方法,最终会调用这两个。
滚动监听
Flutter widgets树中的子widget可以通过发送通知与父(包括祖)widget通信,父widget也可以通过NotificationListener widget来监听自己关注的通知。
NotificationListener是一个widget,模板参数是想要关注的通知类型,如果省略,则所有类型的通知都会监听。需要实现一个onNotification回调函数,实现监听处理逻辑,返回布尔值,如果返回true,则事件停止向上传递,返回false则继续向上传递。
5.功能型widget
功能性widget是指不会影响UI布局及外观的widget,通常有一定功能,如事件监听,数据存储等。
导航事件拦截(WillPopScope)
通过WillPopScope实现返回按钮拦截,包括Android的物理返回键和导航返回按钮。在onWillPop回调函数中处理相关逻辑,返回true时当前路由出栈,返回false时,当前路由不出栈。
数据共享(InheritedWidget)
可以高效的将数据在widget树中下传递、共享。例如正是通过InheritedWidget来共享Theme(主题)和Locale(当前语言环境)信息。
主题(Theme)
Theme widget可以为Material App定义主题数据(ThemeData),Material组件库里很多Widget都使用了主题数据,如导航栏颜色、标题字体、Icon样式等。Theme会通过InheritedWidget来为其子树widget共享样式数据。
可定义的主题数据都在ThemeData中,可以通过Theme.of(context)获取当前的ThemeData。
相关参考
1、安全控件实质是一种小程序。由各网站依据需要自行编写,当该网站的注册会员登录该网站时,安全控件发挥作用,然后通过对关键数据进行SSL加密,防止账号密码被木马程序或病毒窃取,可以有效防止木马截取键盘记录。2...
...界面如下31个日期按钮,不需要手工创建,通过代码产生控件数组,生成31个选项按钮。在窗体show事件里,写代码如下声明变量varsbtns:array[1..31]ofTSpeedButton;//用于创建按钮控件数组n,ncount,x,y,a,b,v,leftv,topv:word;show事件代码procedureT...
水平回转平台(wxPython - 基本控件之数据调节框SpinCtrl)
实战wxPython系列-036wx.SpinCtrl是wx.TextCtrl和wx.SpinButton控件的组合。当用户点击wx.SpinButton的向上或者向下按钮的时候,wx.TextCtrl中的值将会随之变化。用户也可以直接在wx.TextCtrl中输入想要的值。一、wx.SpinButton一个wx.SpinButton有两个小...
一、前言数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口、网络、数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示。串...
按钮插件(Qt界面导航插件最新版:添加按钮灯光效果,动态更炫酷)
...航设计和FluentDesignUI概念QtitanNavigationDesignUI组件是一组GUI控件,这些GUI控件实现了诸如汉堡菜单,导航框架,命令栏之类的导航界面,并添加了控件,其主要任务是改善Qt.C++应用程序的用户体验。QtitanNavigationDesignUI的控件结合了...
手表秒针不走怎么回事(没有电池,机械表如何准确走时?(中))
...始,它构成了机芯的主体:(编辑注:原文附上的是交互控件,你可以在控件上拖拽来改变观察视角。受限于微信平台,这里用图片或动图替换,感兴趣的读者可以点击结尾原文链接体验交互
怎么判断水平结构和垂直结构(wxPython - 布局管理之水平布局和垂直布局)
...010在现代GUI桌面程序开发中,一般都有对GUI交互窗口中的控件进行布局的功能,在布局管理中,最常见的两种布局就是水平布局和垂直布局,顾名思义,在水平布局中,所有控件从左到右水平排列,在垂直布局中,控件从上到下...
...机械旋转的电子设备。它们可以以两种方式使用——作为控件或作为测量轴旋转的装置。当它被用作控件的情况下,旋转编码器可以比电位器更通用。当您需要非常精确的控制时可以使用它,并且它们不会因温度而漂移。作为测...
沥青搅拌机配件(沥青混合料搅拌站38个典型故障处理方法(下))
...的暂停按钮或用鼠标点击了计算机监控界面上的禁止出料控件,则搅拌时间到后,搅拌机不会卸料。另卸料门电磁阀损坏,卸料门不能打开,搅拌机也不会卸料。处理过程:1、检查操作台上暂停按钮是否按下,如按下则复位。2...
沥青搅拌机配件(沥青混合料搅拌站38个典型故障处理方法(下))
...的暂停按钮或用鼠标点击了计算机监控界面上的禁止出料控件,则搅拌时间到后,搅拌机不会卸料。另卸料门电磁阀损坏,卸料门不能打开,搅拌机也不会卸料。处理过程:1、检查操作台上暂停按钮是否按下,如按下则复位。2...