前端开发进阶篇——Flutter容器
1. 容器类Widget
容器类Widget和布局类Widget都作用于其子Widget,不同的是:
-
布局类Widget一般都需要接收一个widget数组(children),他们直接或间接继承自(或包含)MultiChildRenderObjectWidget ;而容器类Widget一般只需要接收一个子Widget(child),他们直接或间接继承自(或包含)SingleChildRenderObjectWidget。
-
布局类Widget是按照一定的排列方式来对其子Widget进行排列;而容器类Widget一般只是包装其子Widget,对其添加一些修饰(补白或背景色等)、变换(旋转或剪裁等)、或限制(大小等)。
2. 填充(Padding)
Padding可以给其子节点添加填充(留白),和边距效果类似。其定义为:
Padding({ ... EdgeInsetsGeometry padding, Widget child,})
EdgeInsetsGeometry是一个抽象类,开发中,我们一般都使用EdgeInsets类,它是EdgeInsetsGeometry的一个子类,定义了一些设置填充的便捷方法。
EdgeInsets提供的便捷方法:
-
fromLTRB(double left, double top, double right, double bottom):分别指定四个方向的填充。
-
all(double value) : 所有方向均使用相同数值的填充。
-
only({left, top, right ,bottom }):可以设置具体某个方向的填充(可以同时指定多个方向)。
-
symmetric({ vertical, horizontal }):用于设置对称方向的填充,vertical指top和bottom,horizontal指left和right。
3. 尺寸限制类容器
ConstrainedBox
ConstrainedBox用于对子组件添加额外的约束。例如,如果你想让子组件的最小高度是80像素,你可以使用const BoxConstraints(minHeight: 80.0)作为子组件的约束。BoxConstraints用于设置限制条件,它的定义如下:
const BoxConstraints({ this.minWidth = 0.0, //最小宽度 this.maxWidth = double.infinity, //最大宽度 this.minHeight = 0.0, //最小高度 this.maxHeight = double.infinity //最大高度}
SizedBox
SizedBox用于给子元素指定固定的宽高,如:
SizedBox( width: 80.0, height: 80.0, child: redBox)
实际上SizedBox只是ConstrainedBox的一个定制。ConstrainedBox和SizedBox都是通过RenderConstrainedBox来渲染的。
4. 装饰容器DecoratedBox
DecoratedBox可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变等。DecoratedBox定义如下:
const DecoratedBox({ Decoration decoration, DecorationPosition position = DecorationPosition.background, Widget child})
-
decoration:代表将要绘制的装饰,它的类型为Decoration。Decoration是一个抽象类,它定义了一个接口 createBoxPainter(),子类的主要职责是需要通过实现它来创建一个画笔,该画笔用于绘制装饰。
-
position:绘制Decoration的位置,它接收DecorationPosition的枚举类型,该枚举类有两个值:
1)background:背景装饰。
2)foreground:前景。
BoxDecoration
BoxDecoration类,它是一个Decoration的子类,实现了常用的装饰元素的绘制。其定义如下:
BoxDecoration({ Color color, //颜色 DecorationImage image,//图片 BoxBorder border, //边框 BorderRadiusGeometry borderRadius, //圆角 List<BoxShadow> boxShadow, //阴影,可以指定多个 Gradient gradient, //渐变 BlendMode backgroundBlendMode, //背景混合模式 BoxShape shape = BoxShape.rectangle, //形状})
5. 变换(Transform)
Transform可以在其子组件绘制时对其应用一些矩阵变换来实现一些特效。Matrix4是一个4D矩阵,通过它我们可以实现各种矩阵操作。
-
平移:Transform.translate接收一个offset参数,可以在绘制时沿x、y轴对子组件平移指定的距离。
-
旋转:ransform.rotate可以对子组件进行旋转变换。这里需要引入数学库(import 'dart:math' as math;)。
-
缩放:Transform.scale可以对子组件进行缩小或放大。
Transform的变换是应用在绘制阶段,而并不是应用在布局(layout)阶段,所以无论对子组件应用何种变化,其占用空间的大小和在屏幕上的位置都是固定不变的,因为这些是在布局阶段就确定的。
RotatedBox和Transform.rotate功能相似,它们都可以对子组件进行旋转变换,但是有一点不同:RotatedBox的变换是在layout阶段,会影响在子组件的位置和大小。
6. Container
Container是一个组合类容器,它本身不对应具体的RenderObject,它是DecoratedBox、ConstrainedBox、Transform、Padding、Align等组件组合的一个多功能容器,所以我们只需通过一个Container组件可以实现同时需要装饰、变换、限制的场景。
Container的定义如下:
Container({ this.alignment, this.padding, //容器内补白,属于decoration的装饰范围 Color color, // 背景色 Decoration decoration, // 背景装饰 Decoration foregroundDecoration, //前景装饰 double width,//容器的宽度 double height, //容器的高度 BoxConstraints constraints, //容器大小的限制条件 this.margin,//容器外补白,不属于decoration的装饰范围 this.transform, //变换 this.child,})
容器的大小可以通过width、height属性来指定,也可以通过constraints来指定;如果它们同时存在时,width、height优先。实际上Container内部会根据width、height来生成一个constraints。color和decoration是互斥的,如果同时设置它们则会报错!实际上,当指定color时,Container内会自动创建一个decoration。
Padding和Margin
Container组件margin和padding属性都是通过Padding 组件来实现的,margin的留白是在容器外部,而padding的留白是在容器内。
6. Scaffold、TabBar、底部导航
一个完整的路由页可能会包含导航栏、抽屉菜单(Drawer)以及底部Tab导航菜单等。Flutter Material组件库提供了一些现成的组件来减少我们的开发任务。
-
Scaffold是一个路由页的骨架,我们使用它可以很容易地拼装出一个完整的页面。
-
AppBar是一个Material风格的导航栏,通过它可以设置导航栏标题、导航栏菜单、导航栏底部的Tab标题等。其定义如下:
AppBar({ Key key, this.leading, //导航栏最左侧Widget,常见为抽屉菜单按钮或返回按钮。 this.automaticallyImplyLeading = true, //如果leading为null,是否自动实现默认的leading按钮 this.title,// 页面标题 this.actions, // 导航栏右侧菜单 this.bottom, // 导航栏底部菜单,通常为Tab按钮组 this.elevation = 4.0, // 导航栏阴影 this.centerTitle, //标题是否居中 this.backgroundColor, ... //其它属性见源码注释})
-
Tab组件有三个可选参数,除了可以指定文字外,还可以指定Tab菜单图标,或者直接自定义组件样式。Tab组件定义如下:
Tab({ Key key, this.text, // 菜单文本 this.icon, // 菜单图标 this.child, // 自定义组件样式})
TabBar我们只能生成一个静态的菜单,真正的Tab页还没有实现。由于Tab菜单和Tab页的切换需要同步,我们需要通过TabController去监听Tab菜单的切换去切换Tab页。Material库提供了一个TabBarView
组件,通过它不仅可以轻松的实现Tab页,而且可以非常容易的配合TabBar来实现同步切换和滑动状态同步。abBar和TabBarView都是通过同一个controller来实现菜单切换和滑动状态同步的。
-
抽屉菜单Drawer:Scaffold的drawer和endDrawer属性可以分别接受一个Widget来作为页面的左、右抽屉菜单。如果开发者提供了抽屉菜单,那么当用户手指从屏幕左(或右)侧向里滑动时便可打开抽屉菜单。
- RaisedButton组件有两个最基本的属性:
1)child:可以放入容器,图标,文字。让你构建多彩的按钮。
2)onPressed:点击事件的相应,一般会调用Navigator
组件。
-
Navigator.push是跳转到下一个页面,它要接受两个参数一个是上下文context,另一个是要跳转的函数。
-
Navigator.pop是返回到上一个页面,使用时传递一个context(上下文)参数,使用时要注意的是,你必须是有上级页面的,也就是说上级页面使用了Navigator.push。
7. 剪裁(Clip)
Flutter中提供了一些剪裁函数,用于对组件进行剪裁。
剪裁Widget | 作用 |
---|---|
ClipOval | 子组件为正方形时剪裁为内贴圆形,为矩形时,剪裁为内贴椭圆 |
ClipRRect | 将子组件剪裁为圆角矩形 |
ClipRect | 剪裁子组件到实际占用的矩形大小(溢出部分剪裁) |
- 点赞
- 收藏
- 关注作者
评论(0)