Flutter学习-基础组件Widgets
前言
Flutter是一个跨平台开发框架,使用dart语言开发,其提供了很多基础组件。开发者可以直接使用达到快速开发效果。参考文献:
1.官网基础组件:https://flutterchina.club/widgets/basics/
2.Flutter Widget 索引:https://flutterchina.club/widgets/widgetindex/(可以搜索组件)
一、Container
一个拥有绘制、定位、调整大小的 widget。(可以看做Android的一个layout布局,里面可以有多个视图view)
参考文档:https://docs.flutter.io/flutter/widgets/Container-class.html
注:所有控件都是Widget的子类
属性:
参考源码如下:
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
})
参数说明:
1. child: 是最重要的元素,即内部布局视图,其定义是一个widget:
final Widget child;
既然类型是Widget,那么可以是哪些呢?通过源码不难发现,widget有很多,但是都是继承于有状态或者无状态的Widget。
class StatelessWidget extends Widget、class StatefulWidget extends Widget.
包括我们常用的Text控件:class Text extends StatelessWidget ,所以这里的child可以是任意的widget。
2. alignment:对齐方式,是相对于父容器位置(含义同Android的align一样,参数值不一样),如:
构造函数:
const Alignment(this.x, this.y)
: assert(x != null),
assert(y != null);
参数范围为:[-1.0,1.0] 表示从顶部到底部或者从左到右。
居中:Alignment(0.0, 0.0)
右下角: Alignment(1.0,1.0),
还有其他设置,这里就不多讲了。
padding
3. padding:表示Widget边框和内容区之间距离。
构造函数很多,先看一个:
const EdgeInsets.all(double value)
: left = value, top = value, right = value, bottom = value;
以上就是内容距离上下左右的边距值,单位是像素:pixels
4. color:颜色值 类型是Color
构造函数:
const Color(int value) : value = value & 0xFFFFFFFF;
可以设置颜色值(同Android设置方法)指定颜色,也可以使用定义好的颜色(颜色常量在类Colors中)
设置红色:new Color(0xffff0000)或者Colors.red
5. decoration:英文含义是装饰,在这里就是指背景图案
这个比较复杂,可以自定义很多背景样式,边框、圆角、阴影、形状、渐变、背景图像等。后面用到再学习。
注意:
container背景色和decoration不能同时设置。
assert(color == null || decoration == null,
‘Cannot provide both a color and a decoration\n’
‘The color argument is just a shorthand for “decoration: new BoxDecoration(color: color)”.’
),
6. width、height:容器宽高
width:container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。
height:container的高度,设置为double.infinity可以强制在高度上撑满。
7. constraints: 约束,意思是给child加上额外的约束条件。
设置child的宽高范围值,构造函数如下:
/// The minimum width that satisfies the constraints.
final double minWidth;
/// The maximum width that satisfies the constraints.
///
/// Might be [double.infinity].
final double maxWidth;
/// The minimum height that satisfies the constraints.
final double minHeight;
/// The maximum height that satisfies the constraints.
///
/// Might be [double.infinity].
final double maxHeight;
class BoxConstraints extends Constraints {
/// Creates box constraints with the given constraints.
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity
});
0.0表示最小,double.infinity为无限大,但是不能大过父容器
8. margin:外边距:本Widget与父边框的距离。
值与padding一致。
9. 外边距:本Widget与父边框的距离。
10. transform:矩阵变换,动画相关处理(后面再学习)
/// The transformation matrix to apply before painting the container.
final Matrix4 transform;
使用方法:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new Container(
alignment: new Alignment(1.0,1.0),
color: Colors.red,
width: 500,
height: 600,
padding: new EdgeInsets.all(10),
constraints: new BoxConstraints(),
child: new Text("this is a container"),
);
}
}
此时运行出现错:
I/flutter ( 1782): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 1782): The following assertion was thrown building Text(“this is a container”):
I/flutter ( 1782): No Directionality widget found.
I/flutter ( 1782): RichText widgets require a Directionality widget ancestor.
I/flutter ( 1782): The specific widget that could not find a Directionality ancestor was:
I/flutter ( 1782): RichText(softWrap: wrapping at box width, maxLines: unlimited, text: “this is a container”)
I/flutter ( 1782): The ownership chain for the affected widget is:
I/flutter ( 1782): RichText ← Text ← Align ← Padding ← DecoratedBox ← ConstrainedBox ← Container ← MyApp ← [root]
I/flutter ( 1782): Typically, the Directionality widget is introduced by the MaterialApp or WidgetsApp widget at the
I/flutter ( 1782): top of your application widget tree. It determines the ambient reading direction and is used, for
I/flutter ( 1782): example, to determine how to lay out text, how to interpret “start” and “end” values, and to resolve
I/flutter ( 1782): EdgeInsetsDirectional, AlignmentDirectional, and other *Directional objects.
I/flutter ( 1782): When the exception was thrown, this was the stack
查了一下原因是:
flutter doesn’t know whether the text is LTR or RTL, so you need to tell him the textDirection explicitly。
由于没有使用MaterialApp ,所以:
There was an API change for text RTL support, which requires the textDirection property to be set on the Text widget if the widget is not a descendant of MaterialApp. If you add the property, the app will run again. Of course this needs to be fixed in the tutorial.
参考:https://github.com/flutter/flutter/issues/14146
所以修改代码:增加了extDirection: TextDirection.ltr一行
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new Container( alignment: new Alignment(1.0,1.0),
color: Colors.red,
width: 500,
height: 600,
padding: new EdgeInsets.all(110),
constraints: new BoxConstraints(),
child: new Text("this is a container",
textDirection: TextDirection.ltr),
);
}
}
运行后效果如下:
总结
其实Container就是一个Widget,里面可以有多个child,child也是Widget。Container可以设置子child的布局,大小,位置等。
注意一点:其属性中的transform、decoration、foregroundDecoration关系如下:
- 优先绘制transform
- 然后是decoration
- 最后是foregroundDecoration