赞
踩
在Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget 或 StatefulWidget
StatelessWidget: 无状态组件,状态不可变的widget
StatefulWidget: 有状态组件,持有的状态可能在widget 生命周期改变
import 'package:flutter/material.dart'; void main(){ runApp(MyApp()); } class MyApp extends StatelessWidget{ @override Widget build(BuildContext context) { // TODO: implement build return Center( child: Text( "我是一个文本内容", textDirection: TextDirection.ltr, // 文字方向 // 文字样式 style: TextStyle( fontSize: 40.0, fontWeight: FontWeight.bold, // color: Colors.yellow color: Color.fromRGBO(255, 222, 222, 0.5) ), ), ); } }
MaterialApp 是一个方便的Widget,它封装了应用程序实现 Material Design 所需要的一些Widget。一般作为顶层widget 使用。
常用的属性:
home(主页)
title(标题)
color(颜色)
theme(主题)
routes(路由)
…
Scaffold 是Material Design 布局结构的基本实现。此类提供了用于显示drawer、snackbar 和底部 sheet 的API。
Scaffold 有下面几个主要属性:
appBar - 显示在界面顶部的一个AppBar。
body - 当前界面所显示的主要内容Widget。
drawer - 抽屉菜单控件。
…
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( title: "我是一个标题", home: Scaffold( appBar: AppBar( title: Text('IT 营'), elevation: 30.0, //设置标题阴影不需要的话值设置成0.0 ), body: MyHome(), ), theme: ThemeData( // 设置主题颜色 primarySwatch: Colors.yellow), ); } } class MyHome extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( child: Text( "我是Dart 一个文本内容", textDirection: TextDirection.ltr, style: TextStyle( fontSize: 40.0, fontWeight: FontWeight.bold, color: Colors.black38 // color: Color.fromRGBO(255, 222, 222, 0.5) ), ), ); ; } }
属性 | 功能 |
---|---|
textAlign | 文本对齐方式(center 居中,left 左对齐,right 右对齐,justfy 两端对齐) |
textDirection | 文本方向(ltr 从左至右,rtl 从右至左) |
overflow | 文字超出屏幕之后的处理方式(clip 裁剪,fade 渐隐,ellipsis 省略号) |
textScaleFactor | 字体显示倍率 |
maxLines | 文字显示最大行数 |
style | 字体的样式设置 |
TextStyle 常用参数:
属性 | 功能 |
---|---|
decoration | 文字装饰线(none 没有线,lineThrough 删除线,overline 上划线,underline 下划线) |
decorationColor | 文字装饰线颜色 |
decorationStyle | 文字装饰线风格([dashed,dotted] 虚线,double 两根线,solid 一根实线,wavy 波浪线) |
wordSpacing | 单词间隙(如果是负值,会让单词变得更紧凑) |
letterSpacing | 字母间隙(如果是负值,会让字母变得更紧凑) |
fontStyle | 文字样式(italic 斜体,normal 正常体) |
fontSize | 文字大小 |
color | 文字颜色 |
fontWeight | 字体粗细(bold 粗体,normal 正常体) |
属性 | 功能 |
---|---|
alignment | topCenter:顶部居中对齐 topLeft:顶部左对齐 topRight:顶部右对齐 center:水平垂直居中对齐 centerLeft:垂直居中水平居左对齐 centerRight:垂直居中水平居右对齐 bottomCenter 底部居中对齐 bottomLeft:底部居左对齐 bottomRight:底部居右对齐 |
margin | margin 属性是表示Container 与外部其他组件的距离。margin: EdgeInsets.all(20.0) |
padding | padding 就是Container 的内边距, 指Container 边缘与Child 之间的距离padding: EdgeInsets.all(10.0) |
transform | 让Container 进行一些旋转之类的transform: Matrix4.rotationZ(0.2) |
height | 容器高度 |
width | 容器宽度 |
child | 容器子元素 |
decoration | 组件样式 |
decoration: BoxDecoration(
color: Colors.blue,
// 边框样式
border: Border.all(
color: Colors.red,
width: 2.0,
),
// 边框圆角
borderRadius:
BorderRadius.all(
Radius.circular(8.0)
)
)
图片组件是显示图像的组件,Image 组件有很多构造函数,这里例举两个:
Image.asset, 本地图片
Image.network 远程图片
Image 组件的常用属性:
属性名 | 类型 | 说明 |
---|---|---|
alignment | Alignment | 图片的对齐方式 |
color 和 colorBlendMode | 设置图片的背景颜色,通常和colorBlendMode 配合一起使用,这样可以使图片颜色和背景色混合。 | |
fit | BoxFit | fit 属性用来控制图片的拉伸和挤压,这都是根据父容器来的。 BoxFit.fill: 全图显示,图片会被拉伸,并充满父容器。 BoxFit.contain: 全图显示,显示原比例,可能会有空隙。 BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。 BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。 BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。 BoxFit.scaleDown:效果和contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大。 |
repeat | ImageRepeat | ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。 ImageRepeat.repeatX: 横向重复,纵向不重复。 ImageRepeat.repeatY:纵向重复,横向不重复。 |
width | 宽度 一般结合ClipOval 才能看到效果 | |
height | 高度 一般结合ClipOval 才能看到效果 |
return Center( child: Container( child: Image.network( "http://pic.baike.soso.com/p/20130828/20130828161137-1346445960.jpg", alignment: Alignment.topLeft, color: Colors.red, colorBlendMode: BlendMode.colorDodge, // repeat: ImageRepeat.repeatX, fit: BoxFit.cover, ), width: 300.0, height: 400.0, decoration: BoxDecoration( color: Colors.yellow ), ), );
然后,打开 pubspec.yaml 声明一下添加的图片文件
代码中使用
child: Container(
child: Image.asset("images/a.jpeg",
fit:BoxFit.cover
),
width: 300.0,
height: 300.0,
decoration: BoxDecoration(
color: Colors.yellow
),
)
child: Container(
width: 300.0,
height: 300.0,
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: NetworkImage("http://pic.baike.soso.com/p/20130828/20130828161137-1346445960.jpg"),
fit: BoxFit.cover
)
),
),
Center(
child: ClipOval(
child: Image.network(
"https://www.itying.com/images/201905/thumb_img/1101_thumb_G_1557845381862.jpg",
width: 150.0,
height: 150.0,
),
)),
列表布局是我们项目开发中最常用的一种布局方式。Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。
列表有以下分类:
1、垂直列表
2、垂直图文列表
3、水平列表
4、动态列表
5、矩阵式列表
属性 | 类型 | 说明 |
---|---|---|
scrollDirection | Axis | Axis.horizontal 水平列表 Axis.vertical 垂直列表 |
padding | EdgeInsetsGeometry | 内边距 |
resolve | bool | 组件反向排序 |
children | List | 列表元素 |
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Center( child: ListView( children: <Widget>[ ListTile( leading: Icon(Icons.phone), title: Text( "this is list", style: TextStyle(fontSize: 28.0), ), subtitle: Text('this is list this is list'), ), ListTile( title: Text("this is list"), subtitle: Text('this is list this is list'), trailing: Icon(Icons.phone), ), ListTile( title: Text("this is list"), subtitle: Text('this is list this is list'), ) ], ), ); } }
水平列表
class HomeContent extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Container( height: 200.0, margin: EdgeInsets.all(5), child: ListView( scrollDirection: Axis.horizontal, // 定义水平列表 children: <Widget>[ Container( width: 180.0, color: Colors.lightBlue, ), Container( width: 180.0, color: Colors.amber, child: ListView( children: <Widget>[ Image.network( 'https://resources.ninghao.org/images/childhood-in-a-picture.jpg'), SizedBox(height: 16.0), Text( '这是一个文本信息', textAlign: TextAlign.center, style: TextStyle(fontSize: 16.0), ) ], ), ), Container( width: 180.0, color: Colors.deepOrange, ), Container( width: 180.0, color: Colors.deepPurpleAccent, ), ], )); } }
动态列表(动态循环数据)
class HomeContent extends StatelessWidget { List list = new List(); HomeContent({Key key}) : super(key: key) { for (var i = 0; i < 20; i++) { list.add("这是第${i}条数据"); } print(list); } @override Widget build(BuildContext context) { return ListView.builder( // 定义动态列表 itemCount: this.list.length, itemBuilder: (context, index) { // print(context); return ListTile( leading: Icon(Icons.phone), title: Text("${list[index]}"), ); }, ); } }
GridView 创建网格列表有多种方式,主要介绍两种:
1、可以通过GridView.count 实现网格布局
2、通过GridView.builder 实现网格布局
常用属性:
名称 | 类型 | 说明 |
---|---|---|
scrollDirection | Axis | 滚动方向 |
padding | EdgeInsetsGeometry | 内边距 |
resolve | bool | 组件反向排序 |
crossAxisSpacing | double | 水平子Widget 之间间距 |
mainAxisSpacing | double | 垂直子Widget 之间间距 |
crossAxisCount | int | 一行的Widget 数量 |
childAspectRatio | double | 子Widget 宽高比例 |
children | [ ] | 子元素 |
gridDelegate | SliverGridDelegateWithFixedCrossAxisCount(常用) SliverGridDelegateWithMaxCrossAxisExtent | 控制布局,主要用在GridView.builder 里面 |
GridView.count 实现网格布局:
class LayoutContent extends StatelessWidget { List<Widget> _getListData() { var tempList = listData.map((value) { return Container( child: Column( children: <Widget>[ Image.network(value["imageUrl"]), SizedBox(height: 12), Text(value["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 20)), ], ), decoration: BoxDecoration( border: Border.all( color: Color.fromRGBO(230, 230, 230, 0.9), width: 1.0)), ); }); // ('124124','124214') return tempList.toList(); } @override Widget build(BuildContext context) { // TODO: implement build return GridView.count( padding: EdgeInsets.all(20), crossAxisCount: 2, crossAxisSpacing: 20, mainAxisSpacing: 20, // childAspectRatio:0.7, children: this._getListData(), ); } }
GridView.builder 实现网格布局:
class LayoutContent extends StatelessWidget { Widget _getListData(context, index) { return Container( child: Column( children: <Widget>[ Image.network(listData[index]["imageUrl"]), SizedBox(height: 12), Text(listData[index]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 20)), ], ), decoration: BoxDecoration( border: Border.all( color: Color.fromRGBO(230, 230, 230, 0.9), width: 1.0)), ); } @override Widget build(BuildContext context) { // TODO: implement build return GridView.builder( itemCount: listData.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( //横轴元素个数 crossAxisCount: 2, //纵轴间距 mainAxisSpacing: 20.0, //横轴间距 crossAxisSpacing: 10.0, //子组件宽高长度比例 childAspectRatio: 1.0), itemBuilder: this._getListData, ); } }
class HomePage extends StatefulWidget { //Flutter2.2.0之后需要注意把Key改为可空类型 {Key? key} 表示Key为可空类型 HomePage({Key? key}) : super(key: key); _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { List list=[]; @override Widget build(BuildContext context) { return ListView( children: <Widget>[ Column( children: this.list.map((value){ return ListTile( title: Text(value), ); }).toList() ), SizedBox(height: 20), //Flutter2.x以后可以使用ElevatedButton替代RaisedButton也可以继续使用RaisedButton ElevatedButton( child: Text("按钮"), onPressed: (){ // 通过 setState 方法改变状态 setState(() { this.list.add('新增数据1'); this.list.add('新增数据2'); }); }, ) ], ); } }
BottomNavigationBar 是底部导航条,可以让我们定义底部 Tab 切换,BottomNavigationBar 是 Scaffold 组件的参数。
BottomNavigationBar 常见的属性:
属性 | 说明 |
---|---|
items | List 底部导航条按钮集合 |
iconSize | icon 大小 |
currentIndex | 默认选中第几个 |
onTap | 选中变化回调函数 |
fixedColor | 选中的颜色 |
type | BottomNavigationBarType.fixed BottomNavigationBarType.shifting |
Scaffold( appBar: AppBar( title: Text('Flutter Demo') ), body: this._pagesList[this._curentIndex], // 通过改变值实现页面切换 bottomNavigationBar: BottomNavigationBar( currentIndex: _curentIndex, onTap: _changePage, fixedColor: Colors.black, type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( title:Text("首页"), icon:Icon(Icons.home) ), BottomNavigationBarItem( title:Text("分类"), icon:Icon(Icons.category) ), BottomNavigationBarItem( title:Text("设置"), icon:Icon(Icons.settings) ), ], ), )
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。