常用的容器类控件有哪些(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的区别

  1. 布局类Widget一般接收一个Widget数组(children),直接或间接继承自(包含)MultiChildRenderObjectWidget,容器类Widget一般只需要接收一个Widget(child),直接或间接继承自(包含)SingleChildRenderObjectWidget;
  2. 布局类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编写控件属性设计器7-串口采集)

一、前言数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口、网络、数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示。串...

按钮插件(Qt界面导航插件最新版:添加按钮灯光效果,动态更炫酷)

...航设计和FluentDesignUI概念QtitanNavigationDesignUI组件是一组GUI控件,这些GUI控件实现了诸如汉堡菜单,导航框架,命令栏之类的导航界面,并添加了控件,其主要任务是改善Qt.C++应用程序的用户体验。QtitanNavigationDesignUI的控件结合了...

手表秒针不走怎么回事(没有电池,机械表如何准确走时?(中))

...始,它构成了机芯的主体:(编辑注:原文附上的是交互控件,你可以在控件上拖拽来改变观察视角。受限于微信平台,这里用图片或动图替换,感兴趣的读者可以点击结尾原文链接体验交互

怎么判断水平结构和垂直结构(wxPython - 布局管理之水平布局和垂直布局)

...010在现代GUI桌面程序开发中,一般都有对GUI交互窗口中的控件进行布局的功能,在布局管理中,最常见的两种布局就是水平布局和垂直布局,顾名思义,在水平布局中,所有控件从左到右水平排列,在垂直布局中,控件从上到下...

旋转编码器的工作原理(旋转编码器概述)

...机械旋转的电子设备。它们可以以两种方式使用——作为控件或作为测量轴旋转的装置。当它被用作控件的情况下,旋转编码器可以比电位器更通用。当您需要非常精确的控制时可以使用它,并且它们不会因温度而漂移。作为测...

沥青搅拌机配件(沥青混合料搅拌站38个典型故障处理方法(下))

...的暂停按钮或用鼠标点击了计算机监控界面上的禁止出料控件,则搅拌时间到后,搅拌机不会卸料。另卸料门电磁阀损坏,卸料门不能打开,搅拌机也不会卸料。处理过程:1、检查操作台上暂停按钮是否按下,如按下则复位。2...

沥青搅拌机配件(沥青混合料搅拌站38个典型故障处理方法(下))

...的暂停按钮或用鼠标点击了计算机监控界面上的禁止出料控件,则搅拌时间到后,搅拌机不会卸料。另卸料门电磁阀损坏,卸料门不能打开,搅拌机也不会卸料。处理过程:1、检查操作台上暂停按钮是否按下,如按下则复位。2...