Container 用来创建一个可见的矩形元素,相当于 HTML 中的 div 元素。
常用属性:
Container(
alignment: Alignment.Center, //child的对齐方式
height: 44,
width: double.infinity, // 无限制
color: Colors.red, // 背景颜色,会被decoration中配置color效果覆盖
padding: EdgeInsets.fromLTRB(left, top, right, bottom),
margin: EdgeInsets.all(20);
constraints: BoxConstraints( // 容器的尺寸约束,可以使用BoxConstraints类来设置最小和最大宽度、高度等
maxHeight: 48,
),
decoration: BoxDecoration( // 容器的装饰效果,例如边框、阴影等
border: Border.all(
color: Colors.green, // 边框颜色
width: 1, // 边框宽度
),
borderRadius: BorderRadius.circular(16),
),
child: Text('Hello world!'), // container中的内容widget
)
Row 将 children 排成一行,Column 将 children 排成一列,其中个各项属性的使用类似 CSS 中的 Flex 布局。
常用属性:
Row(
mainAxisAlignment: MainAxisAlignment.start, //children在主轴上的对齐方式,默认为start。还可以设置为 center、end、spaceBetween(children之间的空白区域相等,首尾child都靠近首尾,没有间隙)
crossAxisAlignment: CrossAxisAlignment.start, // children在交叉轴的对齐方式,Row默认为start,Column默认为center
verticalDirection: VerticalDirection.down, // children在垂直方向的排列顺序,默认down为从上到下,还可以设置从下到上排列的up
children: [
Text('left'), // 还可以使用Expanded对子节点进行权重处理
Text('center'),
Text('right'),
]
)
Text 创建带样式的文本。
常用属性:
Text(
'Hello, World!',
textAlign: TextAlign.center, // 文本在水平方向的对齐方式:left、center、right、justify(两端对齐)
style: TextStyle(
color: Color(0xFF95A3A9),
fontSize: 14,
fontWeight: FontWeight.w400, // 默认为w400/normal。加粗:w700/bold
height: 1.4, // 行间距,字体的1.4倍
),
maxLines: 3, // 指定文本最大行数,超出部分省略
overflow: TextOverflow.ellipsis, // 使用省略号来表示被截断的文本
)
Image 用于显示图像,可以加载网络图片或本地资源图片。
加载资源图片需要先将图片资源放入项目中。例如:新建images文件夹,将图片放在该文件夹下,然后在 pubspec.yaml 中配置 assets。
// pubspec.yaml
assets:
- images/scan.png
// 静态函数
Image.asset(
"images/scan.png",
width: 16,
height: 16,
fit: BoxFit.cover, // 图片的缩放形式,将图片等比例缩放填满容器,可能会发生剪切
);
Image.network(image_url);
Icon 用于显示矢量图标,支持内置图标和 iconfont 图标。衍生的组件有 ImageIcon、IconButton 等。
Icon(
Icons.favorite,
color: Colors.red,
size: 24,
),
ImageIcon(AssetImage("images/scan.png")),
IconButton(
icon: Image.asset('images/scan.png'),
onPressed: () {
ToastUtil.showToast('保存');
}),
Flutter 中的 Button 组件有很多,常用的有:RaisedButton(Material 风格的 Button)、IconButton、TextButton、ButtonBar(按钮组)、FloatingActionButton(浮动按钮)。
常用属性:
RaisedButton(
padding: EdgeInsets.all(10),
child: Text('保存'), // 按钮中显示的文字
textColor: Colors.blue,
highlightColor: Colors.red, // 点击按钮时的颜色
onPressed: () { // 按钮点击时的回调函数,必填。onPressed: null, 表示按钮禁用,会显示禁用的样式
ToastUtil.showToast('click button');
},
disabledColor: Colors.grey, // 禁用时按钮颜色
disabledTextColor: Colors.white, // 禁用时文字颜色
shape: RoundedRectangleBorder( // 按钮形状
borderRadius: BorderRadius.circular(20),
),
)
MaterialApp 是 Flutter 中用于创建一个遵循 Material Design 规范的应用程序的顶层组件。它通常被用作应用程序的根组件,并被放置在 runApp() 函数中,提供了路由、导航、主题和样式等常用功能。
常用属性:
MaterialApp(
title: 'My App', // app切换时显示的标题
theme: ThemeData( // app的主题
primarySwatch: Colors.blue, // 预定义的颜色样本集合,可生成与主要颜色相关的不同深度和透明度的颜色
// primaryColor: Colors.blue, // 单独的颜色值,用于直接指定应用程序的主要颜色
),
home: Scaffold(...), // app的初始页面
initialRoute: '/',
routes: { // 定义应用程序的路由表
'/': (context) => HomePage(), // 可以通过 Navigator.pushNamed(context, '/settings'); 来方便的跳转页面
'/settings': (context) => SettingsPage(),
},
)
Scaffold 提供了一个具有基本布局结构的屏幕或页面。Scaffold 可以作为应用程序的根部件,并且通常用于创建具有标准 Material Design 布局的应用程序。
Scaffold(
appBar: AppBar( // 屏幕顶部的应用程序栏,可以显示标题、操作按钮等
title: Text('My App'),
),
body: Center( // 主要内容区域
child: Text(
'Hello, World!',
style: TextStyle(fontSize: 24),
),
),
floatingActionButton: FloatingActionButton( // 悬浮按钮,通常位于屏幕右下角
onPressed: () {
// 处理按钮点击事件
print('FloatingActionButton clicked!');
},
child: Icon(Icons.add),
),
bottomNavigationBar: BottomNavigationBar( // 底部导航栏,用于切换不同页面
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('首页'),
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
title: Text('我的'),
),
],
onTap: (flag){
// ...
}
),
);
Center 是 Flutter 中的一个布局组件,用于将其子组件在水平和垂直方向上居中显示。
Center(
child: Text('Hello World!'),
)
Expanded 是 Flutter 中的一个布局组件,用于在父容器中占据剩余可用空间。它通常与 Column 或 Row 组件一起使用,可以使用 flex 来确定子组件的大小和位置。
Column(
children: [
Expanded: (
flex: 1, // flex 用于指定 Expanded 组件在父容器中所占据的空间比例。当多个 Expanded 组件存在时,它们的 flex 值会决定它们在剩余空间中的分配比例。默认情况下,所有的 Expanded 组件具有相同的 flex 值。
child: Container(
color: Colors.blue,
),
),
Expanded: (
flex: 2,
child: Container(
color: Colors.red,
),
)
]
)
Stack 和 Positioned 是 Flutter 中一对常用的布局组件,它们通常一起使用来创建重叠的布局效果。类似于 CSS 中的 position 布局。
top / bottom / left / right 分别表示子元素距离 Stack 容器的 上 / 下 / 左 / 右边缘的距离。
Stack(
children: [
Positioned(
top: 100,
left: 50,
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
),
Positioned(
right: 100,
bottom: 100,
child: Text(
'Hello, World!',
style: TextStyle(fontSize: 24),
),
),
]
)
ListView 提供了提供了垂直或水平方向上的滚动功能。ListView的创建方式有多种,常用的有 ListView() 或 ListView.builder()。
常用属性:
ScrollController _controller = ScrollController();
// 适用于子组件数量已知且比较少的情况
ListView(
scrollDirection: Axis.vertical, // 滚动方向,默认为垂直方向。水平方向值为Axis.horizontal
controller: _controller, // 指定与此ListView关联的ScrollController,可用于控制滚动位置和监听滚动事件
children: [
// ...
]
)
// 适合列表项比较多或者列表项不确定的情况
void initState() {
_controller.addListener(() { // 增加监听,滚动到底部时加载更多数据
int offset = _controller.position.pixels.toInt();
int maxOffset = _controller.position.maxScrollExtent.truncate(); // truncate() 方法用于将浮点数截断为整数
if (offset == maxOffset) {
loadMoreData();
}
});
}
List<widget> items = [];
ListView.builder(
controller: _controller,
itemCount: items.length, // item的数量
itemBuilder: (BuildContext context, int index) { // 返回子节点
return items[index];
}
),
GestureDetector 是 Flutter 中常用的手势识别组件,它可以用来监听和处理用户的各种手势操作。常用的手势操作有点击(onTap)、双击(onDoubleTap)、长按(onLongPress)、缩放(onScaleStart、onScaleUpdate、onScaleEnd)等。
GestureDetector(
onTap: (){
// ...
},
child: Container(
// ...
),
)
Visibility 可以根据给定的条件来控制其子组件是否可见。
Visibility(
visible: true; // true时可见,false时不可见
child: Container(),
)
TextField 是 Flutter 常用的输入框组件。
常用属性:
TextEditingController _inputController = TextEditingController();
FocusNode _inputFocusNode = FocusNode();
TextField(
controller: _inputController, //可以通过设置一个TextEditingController来控制TextField的内容以及监听文本变化事件
focusNode: _inputFocusNode, // 用于管理和控制焦点,可以在用户回车键后,在onSubmitted 回调函数中将焦点切换到下一个输入框
keyboardType: TextInputType.phone, // 显示键盘类型,还有 text、number、emailAddress等
maxLines: 1, // 输入框的最大可见行数,相应的还有minLines
maxLength: 11, // 输入框允许输入的最大字符数,同时在右下角出现counterText。可以配置maxLengthEnforced来配置是否允许超过输入最大长度
enabled: true, // 设置为 false 表示输入框不可编辑,disabledBorder来设置不可编辑时的样式
decoration: InputDecoration( // 设置输入框的外观和提示信息
icon: Icon(Icons.home), // 输入框前增加icon,还可以使用prefix、suffix添加前缀和后缀(icon或文本)
labelText: '手机号', // label,通常显示在输入框上方,labelStyle设置样式
hintText: '请输入手机号', // 输入框中无内容时的占位文本,hintStyle: TextStyle() 来控制样式
helperText: '输入11位手机号', // 输入框下方的提示信息,除此之外还有errorText(验证错误时的错误信息)、counterText(输入框右下角,通常用于显示已输入字符的数量)
contentPadding: EdgeInsets.all(10), // 控制文本区域和输入框边界的间距
border: OutlineInputBorder( // boder属性下borderSide无效,能起效果的只有borderRadius
borderRadius:
BorderRadius.all(Radius.circular(24)),
),
focusedBorder: OutlineInputBorder( // 焦点选中当前输入框时外边框样式,除此之外还有enabledBorder(未选中时边框)
borderRadius: BorderRadius.circular(24),
borderSide: BorderSide(
color: Color.yellow,
),
),
filled: true,
fillColor: Colors.grey.shade200, // 设置是否填充输入框背景以及填充颜色
),
obscureText: true, // 用于隐藏用户输入的文本,常用于密码输入框
obscuringCharacter: '#',
onChanged: (text){}, // 文本内容改变时触发
onSubmitted: (text){}, // 回车触发
)
Form 组件提供了一个容器,可以包含多个表单字段,并处理表单的提交。TextFormField 相比 TextField 而言,提供了更多的表单验证和处理功能。
final _formKey = GlobalKey<FormState>();
TextEditingController _usernameController = TextEditingController();
void _submitForm() {
if (_formKey.currentState!.validate()) {
print('Username: ${_usernameController.text}');
}
}
Form(
key: _formKey, //唯一标识,通过key获取当前的FormState
child: Column(
TextFormField(
controller: _usernameController,
validator: (value) { // 表单验证
if (value == null || value.isEmpty) {
return 'Please enter a username';
}
return null;
},
decoration: InputDecoration(
labelText: 'Username',
),
),
ElevatedButton(
onPressed: _submitForm,
child: Text('Submit'),
),
)
)