Flutter StatefluWidget与基础组件(1.2)

在这里插入图片描述

记忆是一首歌曲,忘了词却又能哼得出它的旋律。不要说我变了,我只不过学会了,别人怎样对我,我就该怎样去对别人。失去了缘分的人,即使在同一个城市里也不太容易碰到;一次转身就意味着一辈子。

StatefluWidget与基础组件

  • MaterialApp

  • Scaffold与BottomNavigationBar

  • AppBar

  • RefreshIndicator

  • Image

      • 加载网络图片
        • 加载本地图片
  • PageView

MaterialApp

只列举常用的属性

title String 任务管理界面看到的title(下面我会带大家详细查看具体位置) theme ThemeData 设置主题 home Widget 主页面 routes Map<String, WidgetBuilder> 设置路由(后面说跳转页面的时候会具体说) supportedLocales Iterable<Locale> 支持多国语言默认<Locale>[Locale(‘en’, ‘US’)] darkTheme ThemeDate 暗主题(我看不出有什么效果)

1import 'package:flutter/material.dart'; 2 3//StatefluWidget与基础组件 4class Flutter_Demo5 extends StatefulWidget { 5 @override 6 _Flutter_Demo5State createState() => _Flutter_Demo5State(); 7} 8 9class _Flutter_Demo5State extends State<Flutter_Demo5> { 10 @override 11 Widget build(BuildContext context) { 12 return MaterialApp( 13 title: "StatefluWidget与基础组件", 14 //主题 15 theme: 16 ThemeData(primarySwatch: Colors.green, brightness: Brightness.light), 17 18 //暗主题 19 darkTheme: 20 ThemeData(primarySwatch: Colors.yellow, brightness: Brightness.dark), 21 home: Scaffold( 22 appBar: AppBar( 23 title: Text("StatefluWidget与基础组件"), 24 ), 25 body: Container( 26 color: Colors.white, 27 ), 28 ), 29 color: Colors.pink, 30 routes: <String, WidgetBuilder>{ 31 //定义跳转路由 32 }, 33 supportedLocales: <Locale>[ 34 const Locale('en', 'US'), 35 const Locale('fi', 'FI'), 36 ], 37 debugShowCheckedModeBanner: false, //右上角DEBUG图标 默认为true 38// showPerformanceOverlay: true,//打开性能监控,覆盖在屏幕最上面,默认false 39// checkerboardOffscreenLayers:true,//打开渲染到屏幕外位图的图层的checkerboarding。,默认false 40// debugShowMaterialGrid: true,//显示网格,默认false 41// checkerboardRasterCacheImages:true,//打开光栅缓存图像的检查板,默认false 42 ); 43 } 44} 45 46 47 48

title使用切换到任务管理界面(我的是华为手机):

Scaffold与BottomNavigationBar

appBar AppBar 顶部显示文本 body Widgit AppBar以下,显示内容 persistentFooterButtons List<Widget> 位置如下图 bottomsheet Widget 位置如下图 draw Widget 位置如下图 floatingActionButton Widget(FloatingActionButton) 位置如下图 bottomNavigationBar Widget(BottomNavigationBar) 位置如下图 primary bool 是否显示顶部状态栏,默认为true endDraw Widget 后缀Draw

BottomNavigationBar类型介绍:

1BottomNavigationBar({ 2 Key key, 3 @required this.items,//必须要实现的,最少要有两个子widgets 4 this.onTap,//点击事件,知道当前点击的是哪一个widget 5 this.currentIndex = 0,//当前显示的是哪一个widget 6 this.elevation = 8.0,//阴影 7 BottomNavigationBarType type,//设置items的布局 8 Color fixedColor,//相当于selectedItemColor,但是不能跟selectedItemColor同时存在 9 this.backgroundColor,//设置背景颜色 10 this.iconSize = 24.0,//设置图标大小 11 Color selectedItemColor,//设置选中时的颜色 12 this.unselectedItemColor,//设置没选中时的颜色 13 this.selectedIconTheme = const IconThemeData(),//设置选中时的icon的主题 14 this.unselectedIconTheme = const IconThemeData(),//设置没选中时的icon的主题 15 this.selectedFontSize = 14.0,//设置选中时文字大小 16 this.unselectedFontSize = 12.0,//设置没选中时的文字大小 17 this.selectedLabelStyle,//设置选中时的labe样式 18 this.unselectedLabelStyle,//设置没选中时的labe样式 19 this.showSelectedLabels = true,//设置选中时是否显示文字 20 bool showUnselectedLabels,//设置没选中时是否显示文字 21 }) 22 23 24
1 home: Scaffold( 2 drawer: Container( 3 color: Colors.white, 4 width: 300, 5 child: Column( 6 children: <Widget>[ 7 Container( 8 child: Text("drawer1"), 9 ), 10 Container( 11 child: Text("drawer2"), 12 ), 13 Container( 14 child: Text("drawer3"), 15 ) 16 ], 17 ), 18 ), 19 primary: false, 20 floatingActionButton: FloatingActionButton( 21 child: Text("点我"), 22 ), 23 bottomSheet: Text("bottomSheet"), 24 endDrawer: Container( 25 //右侧Drawer 26 color: Colors.white, 27 width: 300, 28 height: 300, 29 child: Text("endDrawer"), 30 ), 31 persistentFooterButtons: <Widget>[ 32 Container( 33 child: Text("按钮一"), 34 ), 35 Container( 36 child: Text("按钮二"), 37 ), 38 ], 39 bottomNavigationBar: BottomNavigationBar( 40 currentIndex: mIndex, 41 onTap: (index) { 42 setState(() {//每次点击按钮都会刷新整个StatefluWidget 43 mIndex = index; 44 }); 45 }, 46 items: [ 47 BottomNavigationBarItem( 48 icon: Icon(Icons.cached), //默认状态 49 activeIcon: Icon( 50 //选中状态 51 Icons.cached, 52 color: Colors.green, 53 ), 54 title: Text("刷新"), //颜色跟随主题颜色变化 55 ), 56 BottomNavigationBarItem( 57 icon: Icon(Icons.ac_unit), 58 activeIcon: Icon( 59 Icons.ac_unit, 60 color: Colors.green, 61 ), 62 title: Text("雪花"), 63 ) 64 ], 65 ), 66 appBar: AppBar( 67 title: Text("StatefluWidget与基础组件"), 68 ), 69 body: mIndex == 0 //使用三目用算法显示当前显示页面 70 ? Container( 71 color: Colors.white, 72 ) 73 : Container( 74 width: 200, 75 alignment: Alignment.center, 76 height: 200, 77 child: Text("雪花"), 78 color: Colors.green, 79 ), 80 ), 81 82

AppBar

leading Widget 最左边显示按钮一般为返回键(不能和draw按钮重复) title Widget 显示文本 actions List<Widget> 右边显示Widget(此按钮会和endDraw重复) shape ShapeBorder(RoundedRectangleBorder) AppBar形状 backgroundColor Color AppBar背景颜色 brightness Brightness 状态栏颜色 Brightness.dark亮色 Brightness.light深色 iconTheme IconThemeData AppBar中leading中的操作 elevation double AppBar阴影 toolbarOpacity double AppBar透明度 最大值1,最小值0 bottomOpacity double AppBar中bottom透明度 最大值1,最小值0 bottom PreferredSizeWidget(TabBar) 位置如下图

具体位置请看下图:

一般Button都是配合TabBar使用:

tabs List<Widget> 子Tab isScrollable bool 是否可以滚动 indicatorColor Color 指示器颜色 indicatorPadding EdgeInsetsGeometry 指示器内边距 indicator BoxDecoration 选中颜色,(指示器和选中颜色只能选一个) indicatorSize TabBarIndicatorSize 默认是:TabBarIndicatorSize.tab TabBarIndicatorSize.label跟文字等宽 labelColor Color Tab颜色 labelStyle TextStyle Tab样式 labelPadding EdgeInsetsGeometry Tab内边距 unselectedLabelStyle TextStyle Tab未选中样式 unselectedLabelColor Color Tab未选中颜色 onTap ValueChanged<int> 点击Tab响应事件

使用TabBar需要用DefaultTabController包裹,并且length需要设置为当前Tab的数量

1 home: DefaultTabController( 2 length: 3, 3 child: Scaffold( 4 drawer: Container( 5 color: Colors.white, 6 width: 300, 7 child: Column( 8 children: <Widget>[ 9 Container( 10 child: Text("drawer1"), 11 ), 12 Container( 13 child: Text("drawer2"), 14 ), 15 Container( 16 child: Text("drawer3"), 17 ) 18 ], 19 ), 20 ), 21 primary: true, 22 //AppBar标题是否显示完整 默认是true 23 floatingActionButton: FloatingActionButton( 24 child: Text("点我"), 25 ), 26 bottomSheet: Text("bottomSheet"), 27 endDrawer: Container( 28 //右侧Drawer 29 color: Colors.white, 30 width: 300, 31 height: 300, 32 child: Text("endDrawer"), 33 ), 34 persistentFooterButtons: <Widget>[ 35 Container( 36 child: Text("按钮一"), 37 ), 38 Container( 39 child: Text("按钮二"), 40 ), 41 ], 42 bottomNavigationBar: BottomNavigationBar( 43 currentIndex: mIndex, 44 onTap: (index) { 45 setState(() { 46 mIndex = index; 47 }); 48 }, 49 items: [ 50 BottomNavigationBarItem( 51 icon: Icon(Icons.cached), //默认状态 52 activeIcon: Icon( 53 //选中状态 54 Icons.cached, 55 color: Colors.green, 56 ), 57 title: Text("刷新"), //颜色跟随主题颜色变化 58 ), 59 BottomNavigationBarItem( 60 icon: Icon(Icons.ac_unit), 61 activeIcon: Icon( 62 Icons.ac_unit, 63 color: Colors.green, 64 ), 65 title: Text("雪花"), 66 ) 67 ], 68 ), 69 appBar: AppBar( 70 leading: Icon(Icons.arrow_back), 71 //此按钮会和draw按钮重复 72 73 title: Text("StatefluWidget与基础组件"), 74 //按钮显示文字 75 actions: <Widget>[ 76 //右边显示//此按钮会和endDraw按钮重复 77 Container( 78 child: Text("actions"), 79 ), 80 ], 81 shape: RoundedRectangleBorder( 82 //AppBar形状 83 borderRadius: BorderRadius.all(Radius.circular(20))), 84 backgroundColor: Colors.red, 85 //背景色 默认跟随主题色 86 brightness: Brightness.light, 87 //状态栏亮度 88 iconTheme: IconThemeData( 89 color: Colors.blue, //AppBar中leading的颜色 90 opacity: 0.8 //AppBar中leading的透明度 1不透明 91 ), 92 93 //阴影 94 elevation: 20, 95 96 //AppBar透明度 97 toolbarOpacity: 0.7, 98 //botton透明度 99 bottomOpacity: 0.7, 100 101 bottom: mIndex != 0 102 ? TabBar( 103 isScrollable: false, 104 //是否可滚动 105 tabs: <Widget>[ 106 //TabBar子Tab 107 Tab( 108 text: "page1", 109 icon: Icon(Icons.call), 110 ), 111 Tab( 112 text: "page2", 113 icon: Icon(Icons.save), 114 ), 115 Tab( 116 text: "page3", 117 icon: Icon(Icons.data_usage), 118 ), 119 ], 120 indicatorColor: Colors.greenAccent, 121 //指示器选中颜色 122 indicatorPadding: EdgeInsets.zero, 123 //指示器内边距 124// indicator: BoxDecoration(//选中颜色(指示器与选中颜色只能选一个) 125// color: Colors.deepOrange, 126// ), 127 indicatorSize: TabBarIndicatorSize.tab, 128 //tab指示器计算方式TabBarIndicatorSize.lable与文字等宽 129 labelColor: Colors.blue, 130 //Tab默认颜色 131 labelStyle: TextStyle(fontSize: 18), 132 //Tab样式 133 labelPadding: EdgeInsets.all(5), 134 //Tab内边距 135 unselectedLabelColor: Colors.yellow, 136 //Tab未选中颜色 137 unselectedLabelStyle: TextStyle(fontSize: 15), 138 //Tab为选中样式 139 onTap: (index) { 140 mIndex = index; 141 print('现在是第:${index}个'); 142 }, 143 ) 144 : null, 145 ), 146 body: mIndex == 0 147 ? Container( 148 color: Colors.white, 149 ) 150 : TabBarView(//使用TabBarView来响应 151 children: <Widget>[ 152 initTabitem("page1", Colors.blue), 153 initTabitem("page2", Colors.red), 154 initTabitem("page3", Colors.yellow), 155 ], 156 ), 157 ), 158 ), 159 160 initTabitem(String s, Color color) { 161 return Container( 162 color: color, 163 child: Text(s), 164 ); 165 } 166 167

来看看效果图吧:

注:我的审美很好,这样写是为了让大家看到的效果更佳明显!!!

RefreshIndicator

刷新组件

onRefresh RefreshCallback 下拉刷新回调 color Color 指示器颜色 backgroudColor Color 背景颜色 displacement double 下拉显示距离

注:使用RefreshIndicator子Widget必须是可以滚动的!

1 body: RefreshIndicator( 2 child: ListView( 3 children: <Widget>[ 4 Container( 5 color: Colors.white, 6 ) 7 ], 8 ), 9 onRefresh:initRefresh ,//必写参数 10 color: Colors.green,//指示器颜色 11 backgroundColor: Colors.yellow,//背景颜色 12 displacement: 20,//下拉距离 13 ) 14 Future<Null> initRefresh() async { 15 await Future.delayed(new Duration(milliseconds: 1000)); //刷新1s 16 return null; 17 } 18 19 20

回调方法中Future,async和await可以点击参考文档

来看看效果图吧:

Image

图片加载控件(只举例常用属性)

src String Image显示图片路径 width double 图片宽度 height double 图片高度 fit BoxFit BoxFit.fill完全填充,宽高比可能会变 BoxFit.contain等比拉伸,直到一边填充满 BoxFit.cover等比拉伸,直到2边都填充满,此时一边可能超出范围 BoxFit.fitWidth等比拉伸,宽填充满 BoxFit.fitHeight等比拉伸,高填充满 BoxFit.none不拉伸,超出范围截取 BoxFit.scaleDown只缩小,等比

加载网络图片

1 Image.network( 2 //添加网络图片 3 "http://pic1.win4000.com/pic/c/cf/cdc983699c.jpg", 4 width: 100, 5 height: 150, 6 fit: BoxFit.fill, 7 ), 8 9

加载本地图片

1.先在本地创建images文件夹,将需要加载的图片放进去
在这里插入图片描述

2,在pubspec.yaml下声明图片(一定要写对,连一个空格都不能写错!!!)
在这里插入图片描述

在代码中使用asset加载本地图片:

1Image.asset( 2 "images/green.jpeg", 3 width: 100, 4 height: 150 5 ), 6 7

来看看加载的图片吧:
图一网络加载图片用到了BoxFit.fill完全填充,所以会占满整个宽度! # TextField > 文本输入组件

obscureText bool 隐藏文字 keyboardType TextInputType 弹出键盘类型TextInputType.text TextInputType.multiline TextInputType.number TextInputType.phone TextInputType.datetime TextInputType.emailAddress TextInputType.url textInputAction TextInputAction 弹出键盘右下角按钮 TextInputAction.none … TextInputAction.newline (按住ctrl可以点进来,注释写的很清楚我就不再重复说啦) textCapitalization TextCapitalization 大小写控制 TextCapitalization.words… cursorColor Color 光标颜色 cursorWidth double 光标宽度 cursorRadius Radius 光标圆角 maxLines int 最大行数(要比最小行数大) minLines int 最小行数(要比最大行数小) maxLength int 最大输入字符个数(右下角会有当前输入角标) controller TextEditingController 直接new TextEditingController()控制器配置(删除文本内容需要使用) focusNode FocusNode 直接new FocusNode()关闭软键盘配置(关闭软键盘需要使用) decoration InputDecoration 装饰器InputDecoration.collapsed(hintText: “无下划线”)无下划线装饰器(具体装饰器使用下面会介绍) onChanged ValueChanged<String> 当前输入响应回调

InputDecoration只举例常用类型

counter Widget 自定义技数 icon Widget 左侧外图标 prefixIcon Widget 左侧内图标 suffixIcon Widget 右侧图标 helperText String 帮助文字 helperStyle TextStyle 帮助文字样式 hintText String 提示文字 labelText String 悬浮提示文字 errorText String 错误提示 border InputBorder(OutlineInputBorder) 边框设置

在这里插入图片描述
代码注释都标注了,来看看效果图吧~

1TextField( 2// obscureText:true,//隐藏文字 3 keyboardType: TextInputType.number, 4 //设置键盘弹出类型 5 textInputAction: TextInputAction.next, 6 //键盘按钮右下角按钮 7 textCapitalization: TextCapitalization.characters, 8 //大小写控制(我看不出效果!) 9 cursorColor: Colors.yellow, 10 //光标颜色 11 cursorWidth: 10, 12 //光标宽度 13 cursorRadius: Radius.circular(20), 14 //光标圆角 15 maxLines: 3, 16 //最大行数 17 minLines: 1, 18 //最小行数 19 maxLength: 8, 20 //最大输入字符 21 controller: mController = new TextEditingController(), 22 //初始化控制器controller 23 focusNode: focusNode = new FocusNode(), 24 //配置关闭软件按钮 25// decoration: InputDecoration.collapsed(hintText: "无下划线"),//无下划线输入框 26 27 decoration: InputDecoration( //右下角最大输入样式 28 counter: Text("最大输入字符"), 29 icon: Icon(Icons.accessibility), 30 //左侧图标 31 prefixIcon: Icon(Icons.title), 32 //左侧内图标 33 suffixIcon: IconButton( //右侧图标 34 icon: Icon(Icons.delete), 35 onPressed: () { 36 print('SZJonPressed'); 37 mController?.clear();//清除文字 38 focusNode?.unfocus();//关闭软键盘 39 }, 40 ), 41 42 helperText: "请输入手机号", 43 //帮助提示 44 helperStyle: TextStyle(color: Colors.green), 45 hintText: "请输入", 46 //hint提示 47 labelText: "账号", 48 //悬浮提示 先显示lableText在显示hintText 49 errorText: "请正确输入手机号", 50 errorMaxLines: 5, 51 //错误提示 52// errorBorder: OutlineInputBorder(), 53 54 55 border: OutlineInputBorder( //设置边框 56 borderRadius: BorderRadius.all( 57 Radius.circular(30)), //设置圆角 58 ) 59 60 ), 61 62 onChanged: (value) { //响应回调 63 print('当前输入的是${value}'); 64 mValue = value; 65 }, 66 67 68 ) 69 70

效果图:

PageView

切换页面控件

scrollDirection Axis 设置滚动方向Axis.vertical垂直滚动 Axis.horizontal controller PageController 控制器 onPageChanged ValueChanged<int> 响应当前页数 children List<Widget> 子Page的Widget

viewportFraction double 设置每一个Page不占满屏幕,漏出上一个和下一个Page! initialPage int 设置默认显示page keepPage bool 是否保存当前page状态

1Container( 2 height: 100, 3 margin: EdgeInsets.only(top: 30), 4 child: PageView( 5 scrollDirection: Axis.vertical,//设置滑动方向 默认是Axis.horizontal 6 controller: PageController( 7 viewportFraction: 0.9,//设置每一个Page不占满屏幕,漏出上一个和下一个Page! 8 initialPage: 0,//设置默认Page 9 keepPage: true//是否保存当前滚动page 10 11 ), 12 onPageChanged: (index){ 13 print("SZJonPageChanged${index}\t\t"); 14 }, 15 16 children: <Widget>[ 17 initPageViewItem("page1", Colors.green), 18 initPageViewItem("page2", Colors.yellow), 19 initPageViewItem("page3", Colors.red), 20 initPageViewItem("page4", Colors.blue), 21 ], 22 ), 23 ) 24 initPageViewItem(String s, Color color) { 25 return Container( 26 color: color, 27 alignment: Alignment.center, 28 child: Text(s), 29 ); 30 } 31 32

来看看效果图吧:
查看完整代码.

上一章:Flutter StatelessWidget与基础组件(1.1)

下一章:Flutter 如何进行Flutter布局开发(1.3)

原创不易,您的点赞是对我最大的鼓励,留下您的点赞吧~

代码交流 2021