在 Flutter 开发中最实用的 Dart 语法知识 的文章中,介绍了 Dart
语法,本篇文章就来说一说 Flutter
开发中常见的组件的用法。
在 Flutter 开发中,记住一句话,一切皆组件。
Flutter 的组件很多,要完全记住是不可能的,我的方法就是记住常见的,然而对于组件的属性,这个不需要记住,根据实际开发需求,需要什么属性,直接点开源码,去查看一下这个组件是否有需要的属性即可。
Widget 是 Flutter 应用用户界面的基本构建单元,每个 Widget 都最终与用户界面紧密相关。整个页面都是靠 Widget 展示的。一个按钮,一个菜单,一个字体,一个配色方案,一个布局等等都可以看做是 Widget。
Widget 的分类,主要使用的是两类:
StatelessWidget
: 内部没有保存状态,UI 界面构建后不会发生改变。StatefulWidget
: 内部保存状态,调用 setState() 方法,变更 UI。图中有个概念是 Widget 树:
创建的第一个工程就是带有 MaterialApp Widget
组件的。Material 应用以 MaterialApp Widget 开始,主要封装了应用程序实现 Material Design 需要的一些配置。
从构造方法中,可以看出,这是一个根 Widget,接下来是 Scaffold
组件,翻译过来就是脚手架,这个组件里面配置的一般就是导航栏,页面中间部分,给张图大概说明一下:
文本组件,对于文本,最需要关心的一般就是文本内容和文本样式。其余属性,按需选择
Text(
'Text 文本组件',//此参数必传
maxLines: 1,//最大一行
softWrap: true, //自动换行
overflow: TextOverflow.ellipsis, //超出内容如何显示:3小点
//样式属性
style: TextStyle(
fontSize: 30.0, //大小
)
富文本组件,文本的内容可以分段显示不同的样式。源码中 text 属性必须传入,类型是 InlineSpan 类型的,而 TextSpan 继承 InlineSpan 的。
RichText(
text: TextSpan(
text: '富文本',
style: TextStyle(color: Color(0xffff0000), fontSize: 20.0),
children: <TextSpan>[
TextSpan(text: '富文本1', ),
TextSpan(text: '富文本2', style: TextStyle(color:Color(0xff0000ff)),)
],
),
),
文本输入框,一般最关心的是默认 hint 值,文本输入的限制等。
TextField(
//最普通的样式
controller: TextEditingController(text: "input phone"),
//装饰
decoration: InputDecoration(
//hint 文字
hintText: "please input phone",
//外边框
border: OutlineInputBorder(),
),
inputFormatters: [
//过滤 白名单:数字 11位
WhitelistingTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(11)
],
//密码形式
obscureText: true,
)
顾名思义,展示图片的组件,这边就简单介绍几种图片展示方式
Image.network(
'https://www.baidu.com/img/bd_logo1.png?where=super',
height: 100.0,
width: 100.0,
),
从源码中看出 src 必传,width,height 设置图片宽高。
//例如:
// 1. 项目根目录下创建 assets 文件夹,此文件夹下创建 images 文件夹,将设计给的图片放入其中
// 2. 在 pubspec.yaml 文件中写入
flutter:
assets:
- assets/images/tzd.jpg
// 3. 加载图片
Image.asset(
'assets/images/tzd.jpg',
height: 200.0,
width: 200.0,
)
系统内置了很多 Icon 的图片,供开发者使用。
Icon(
Icons.folder,
color: Colors.red,
size: 50,
)
正常都会有展示圆形图片的需求,使用组件 ClipOval
ClipOval(
child: Image(
image: NetworkImage( "https://img.aigaojixtxz.com/d/file/images/20191113/15690311636958128.jpg"),
width: 50,
height: 50,
)
对于圆形图片,再介绍一种方式供选择:
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage( "https://img.aigaojixtxz.com/d/file/images/20191113/15690311636958128.jpg")),
shape: BoxShape.circle,
),
)
这边的 Container 是一个容器组件,类似于 HTML 中的 div。对于常见的功能,从相册中选择图片,推荐使用 image_picker
这个插件。
对于按钮,就简单介绍两个最常见的 IconButton
和 RasiedButton
。
IconButton(icon: Icon(Icons.error), onPressed: () {}),
RaisedButton(
onPressed: () {},
child: Text('RaisedButton'),
)
IconButton
是带图标的按钮,其中的 onPressed()
是点击事件,RasiedButton
是自带水波纹的按钮。
比较简单一点的是 SimpleDialog
组件:
SimpleDialog(
title: Text('对话框标题'),
children: <Widget>[
SimpleDialogOption(
child: Text('选项1'),
onPressed: () {
print('选项1');
},
),
SimpleDialogOption(
child: Text('选项2'),
onPressed: () {
print('选项2');
},
)
],
)
然而开发中一般使用的 AlertDialog
:
AlertDialog(
title: Text('提示'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('是否删除?'),
Text('删除后不可恢复!'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
);
关于布局组件,主要使用的有三种:线性布局
、弹性布局
、层叠布局
。
线性布局:指沿水平或垂直方向排布子组件。 Flutter 中通过 Row
和 Column
来实现线性布局。
对于线性布局来说,有个比较重要的概念:主轴和交叉轴。来张图展示一下:
对上面的图解释一下:
千言万语不如一张图
:
Flex
和 Expanded
来配合实现。class SimpleFlex extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Simple Flex'),
),
body: Flex(
//方向:水平方向布局
direction: Axis.horizontal,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
height: 50,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.green,
height: 50,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.yellow,
height: 50,
),
),
],
),
);
}
}
Stack
允许子组件堆叠,而 Positioned
用于根据 Stack 的四个角来确定子组件的位置。class SimpleStack extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Simple Stack'),
),
body: Stack(
//此参数决定如何去对齐没有定位或部分定位的子组件
alignment: AlignmentDirectional.topStart,
//fit:此参数用于确定没有定位的子组件如何去适应Stack的大小
//overflow :此属性决定如何显示超出Stack显示空间的子组件
children: <Widget>[
Container(
color: Colors.red,
),
//单个组件定位
Positioned(
left: 100,
child: Container(
width: 150,
height: 150,
color: Colors.green,
),
),
Container(
width: 100,
height: 100,
color: Colors.yellow,
)
],
),
);
}
}
这类的组件类似于 Android 中的 CardView
控件。
Widget buildCard() {
return Container(
child: Card(
elevation: 5,//阴影
//图片显示圆角
clipBehavior: Clip.antiAlias,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(14.0))), //设置圆角
child: Column(
children: <Widget>[
Container(
child: Image.asset(
'assets/images/tzd.jpg',
width: double.infinity,
height: 150.0,
fit: BoxFit.cover,
),
),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(15.0),
child: Container(
child: Icon(Icons.home),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'棒棒的',
style: TextStyle(fontSize: 22.0),
),
Text(
'500',
style: TextStyle(fontSize: 14.0),
),
],
),
),
Container(
child: Column(
children: <Widget>[
Icon(
Icons.favorite,
color: Color(0xffff0000),
),
Text('66'),
],
),
),
],
)
],
),
),
);
}
本篇文章介绍了 Flutter
开发中的最常用的基础组件,希望各位有所收获。 本人水平有限,如有错误,请在下方评论中指出。