flutter-开发总结
### 上拉加载下拉刷新 ``` import 'dart:async'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_easyrefresh/bezier_hour_glass_header.dart'; import 'package:flutter_easyrefresh/bezier_bounce_footer.dart'; import 'package:flutter_smart_park/widget/refresh/emptyWidget.dart'; List list = []; GlobalKey<EasyRefreshState> _easyRefreshKey = new GlobalKey<EasyRefreshState>(); GlobalKey<RefreshHeaderState> _headerKey = new GlobalKey<RefreshHeaderState>(); GlobalKey<RefreshFooterState> _footerKey = new GlobalKey<RefreshFooterState>(); new EasyRefresh( key: _easyRefreshKey, autoLoad: true, //自动加载 autoControl: false, //自动控制 firstRefresh: true, //首次加载 firstRefreshWidget: null, refreshHeader: BezierHourGlassHeader( key: _headerKey, color: Theme.of(context).scaffoldBackgroundColor, ), refreshFooter: BezierBounceFooter( key: _footerKey, color: Theme.of(context).scaffoldBackgroundColor, ), child: new text('data'), emptyWidget: new EmptyWidget(), onRefresh: () async { List a = []; for (var i = 0; i < 10; i++) { a.add(i); } new Timer(new Duration(seconds: 2), () { setState(() { list.clear(); list.addAll(a); }); _easyRefreshKey.currentState.callRefreshFinish(); }); }, loadMore: () async { List a = []; for (var i = 0; i < 10; i++) { a.add(i); } new Timer(new Duration(seconds: 2), () { setState(() { if (list.length < 20) { list.addAll(a); print(list.length); } }); _easyRefreshKey.currentState.callLoadMoreFinish(); }); }, ), ``` ### 底部导航 ``` bottomNavigationBar: BottomNavigationBar( items: <BottomNavigationBarItem>[ BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')), BottomNavigationBarItem(icon: Icon(Icons.business), title: Text('Business')), BottomNavigationBarItem(icon: Icon(Icons.school), title: Text('School')), ], currentIndex: _selectedIndex, fixedColor: Colors.deepPurple, onTap: _onItemTapped, ), ``` ### listView 列表 ``` new ListView.builder( scrollDirection: Axis.horizontal, //横向 shrinkWrap:true, // 自动高度 physics: NeverScrollableScrollPhysics(), // 禁止滚动 itemCount: 10, itemBuilder: (BuildContext context, int index) { }, ), ``` ### text 文本 ``` Text( "Hello world "*6, //字符串重复六次 textAlign: TextAlign.center, //对齐方式 overflow: TextOverflow.ellipsis, // 文本溢出 maxLines: 3, // 最多显示的行数 textScaleFactor: 1.5, style: TextStyle( color: Colors.blue, fontSize: 18.0, height: 1.2, fontFamily: "Courier", background: new Paint()..color=Colors.yellow, decoration:TextDecoration.underline, decorationStyle: TextDecorationStyle.dashed ), ); // 一行文字多种样式 Text.rich( TextSpan( children: [ TextSpan( text: "Home: " ), TextSpan( text: "https://flutterchina.club", style: TextStyle( color: Colors.blue ), ), ] ), ) ``` ### Container容器 ``` new Container( alignment: Alignment.center, //对齐方式 decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.lightBlue, Colors.greenAccent, Colors.purple], begin: FractionalOffset(0, 0), end: FractionalOffset(1, 1), ), border: Border.all( width: 2.0, color: Colors.red, ), image: DecorationImage( // 背景图片 image: AssetImage('assets/images/parkingbg.png'), //本地 centerSlice: Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0), ), ), ), ``` ### Image图片 BoxFit.fill:全图显示,图片会被拉伸,并充满父容器。 BoxFit.contain:全图显示,显示原比例,可能会有空隙。 BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。 BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。 BoxFit.fitHeight :高度充满(竖向充满),显示可能拉伸,可能裁切。 BoxFit.scaleDown:效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大。 ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。 ImageRepeat.repeatX: 横向重复,纵向不重复。 ImageRepeat.repeatY:纵向重复,横向不重复。 ``` new Image.network( 'http://jspang.com/static/myimg/blogtouxiang.jpg', scale:1.0, fit:BoxFit.cover, olorBlendMode: BlendMode.darken, //图片混合模式 repeat: ImageRepeat.repeat, //图片重复 ), CachedNetworkImage( imageUrl: 'https://pro.modao.cc/uploads4/images/3089/30894737/v2_pnb2pb.png', placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), fit: BoxFit.cover, width: ScreenUtil().setWidth(130), height: ScreenUtil().setWidth(90), ), ``` ### GridView网格列表组件 ``` new GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 2.0, crossAxisSpacing: 2.0, childAspectRatio: 0.7 ), children: <Widget>[ new Image.network('http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg',fit: BoxFit.cover), new Image.network('http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg',fit: BoxFit.cover), ], ) new GridView.builder( shrinkWrap: true, physics: new NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, //一行多少列 mainAxisSpacing: ScreenUtil().setWidth(LqruiStyle.borderWidth), //y轴距离 crossAxisSpacing: ScreenUtil().setWidth(LqruiStyle.borderWidth), //x轴距离 childAspectRatio: 1.4, //框的比列 ), itemCount: homeIcon.length, itemBuilder: (BuildContext context, int index) { <!-- 内容 --> }, ), ``` ### Column垂直布局 ``` new Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text('I am JSPang'), Text('my website is jspang.com'), Text('I love coding') ], ) ``` ### Row横向布局 ``` new Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Expanded( child: Text('I am JSPang'), ) Text('my website is jspang.com'), Text('I love coding') ], ) ``` ### Stack层叠布局 ``` var stack = new Stack( alignment: const FractionalOffset(0.5, 0.8), children: <Widget>[ new CircleAvatar( backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'), radius: 100.0, ), new Container( decoration: new BoxDecoration( color: Colors.lightBlue, ), padding: EdgeInsets.all(5.0), child: new Text('JSPang 技术胖'), ), new Positioned( bottom:10.0, right:10.0, child: new Text('技术胖'), ), ], ); ``` ### Card卡片组件布局 ``` new Card( child: Column( children: <Widget>[ ListTile( title:new Text('吉林省吉林市昌邑区',style: TextStyle(fontWeight: FontWeight.w500),), subtitle: new Text('技术胖:1513938888'), leading: new Icon(Icons.account_box,color: Colors.lightBlue,), ), new Divider(), ListTile( title:new Text('北京市海淀区中国科技大学',style: TextStyle(fontWeight: FontWeight.w500),), subtitle: new Text('胜宏宇:1513938888'), leading: new Icon(Icons.account_box,color: Colors.lightBlue,), ), new Divider(), ListTile( title:new Text('河南省濮阳市百姓办公楼',style: TextStyle(fontWeight: FontWeight.w500),), subtitle: new Text('JSPang:1513938888'), leading: new Icon(Icons.account_box,color: Colors.lightBlue,), ), new Divider(), ], ), ); ``` ### 路由 ``` import 'package:fluro/fluro.dart'; import 'package:flutter_smart_park/routes/routes.dart'; Routes.router .navigateTo(context, '${Routes.xxx}?id=1', transition: TransitionType.inFromRight) .then((result) { print(result); }); Routes.router.navigateTo( context, '${Routes.userSignUp}', transition: TransitionType.inFromRight, ); Navigator.of(context).pop(); ``` ### 文本左右布局 ``` Widget page(title, text) { return new Container( margin: EdgeInsets.only(top: ScreenUtil().setWidth(10)), child: Row( children: <Widget>[ Expanded( child: Text( '$title', style: TextStyle( color: Color(LqruiStyle.colorText2), fontSize: ScreenUtil().setSp(14), ), ), ), Expanded( flex: 0, child: Text( '$text', style: TextStyle( fontSize: ScreenUtil().setSp(14), ), ), ), ], ), ); } ``` ### 文本默认样式 ``` new DefaultTextStyle( //1.设置文本默认样式 style: TextStyle( color:Colors.red, fontSize: 20.0, ), textAlign: TextAlign.start, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text("hello world"), Text("I am Jack"), Text("I am Jack", style: TextStyle( inherit: false, //2.不继承默认样式 color: Colors.grey ), ), ], ), ); ``` ### 页面加载事件 ``` @override void initState() { super.initState(); print('111111111111111111111111111'); } ``` ### 输入法弹起导致容器越界 ``` 1. 包一层SingleChildScrollView 2. 设置Scaffold resizeToAvoidBottomPadding: false, ``` ### 切换后页面状态的保持 ``` // 子页面 class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive =>true; } // 使用 IndexedStack new IndexedStack( index: currentIndex, children: tabBodies ) ``` ### 点击事件 ``` new GestureDetector( child: new Text("忘记密码"), onTap: () => {}, //点击 onDoubleTap: () => {}, //双击 onLongPress: () => {}, //长按 ), ``` ### 输入框 ``` Container( child: TextField( keyboardType: TextInputType.emailAddress, decoration: InputDecoration( labelText: "Email", hintText: "电子邮件地址", prefixIcon: Icon(Icons.email), border: InputBorder.none //隐藏下划线 ) ), decoration: BoxDecoration( // 下滑线浅灰色,宽度1像素 border: Border(bottom: BorderSide(color: Colors.grey[200], width: 1.0)) ), ) Theme( data: Theme.of(context).copyWith( hintColor: Color(LqruiStyle.dividerColor), //定义下划线颜色 inputDecorationTheme: InputDecorationTheme( labelStyle: TextStyle(color: Colors.grey), //定义label字体样式 hintStyle: TextStyle( color: Colors.grey, fontSize: 14.0) //定义提示文本样式 ), ), child: Form(), ), ``` ### 圆角容器 ``` new ClipOval( //默认全圆角 child: Container( width: 100, height: 100, color: Colors.red, ), ), new ClipRRect( //自定义 borderRadius: BorderRadius.circular(50) child: Container( width: 100, height: 100, color: Colors.red, ), ), // shape属性 new Container( width: 72.0, height: 72.0, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: AssetImage( Utils.getImgPath('ali_connors'), ), ), ), ) ``` ### 下拉框 ``` DropdownButtonHideUnderline( //隐藏下划线盒子 child: DropdownButton( items: items, //下拉菜单item点击之后的回调 hint: new Text('下拉选择你想要的数据'), //当没有默认值的时候可以设置的提示 value: widget.select, //下拉菜单选择完之后显示给用户的值 onChanged: widget.onChanged, //下拉菜单item点击之后的回调 elevation: 24, //设置阴影的高度 // isDense: true, //减少按钮的高度。默认情况下,此按钮的高度与其菜单项的高度相同。如果isDense为true, 则按钮的高度减少约一半。 这个当按钮嵌入添加的容器中时,非常有用 isExpanded: true, iconSize: ScreenUtil().setSp(30), //设置三角标icon的大小 ), ); ``` ### 单边框 ``` decoration: BoxDecoration( border: Border( left: BorderSide( width: ScreenUtil().setWidth(5), color: Color(LqruiStyle.primaryColor), style: BorderStyle.solid, ), ), ), ``` ### 模拟器分辨率 ``` 414 736 154 360 640 160 ``` ### 状态栏去阴影 ``` import 'dart:io'; import 'package:flutter/services.dart'; if (Platform.isAndroid) { SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle( statusBarColor: Colors.red, ); SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); } appBar中 elevation: 0, ``` ### 接收参数 ``` final id; final title; ApplyReim({Key key, @required this.id, this.title}) : super(key: key); ``` ### 子组件传参 => 父组件 ``` // 父组件 var data; void onDataChange(val) { setState(() { data = val; }); } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ChildTwo(data4Two: data4Two, callback: (val) => onDataChange(val)), // 子组件 Container( child: Column( children: <Widget>[ Text('子组件2, 传过来的值: ' + '$data'), ] ), ) ], ), ); } // 子组件接收callback,并在某事件中触发 widget.callback(...要返回的数据...); PhotoDetail({Key key, @required this.list, this.index}) : super(key: key); ``` ### 监听Widget宽/高 ``` import 'package:flustars/flustars.dart'; double cardHeight; Builder( builder: (BuildContext context) { WidgetUtil widgetUtil = new WidgetUtil(); widgetUtil.asyncPrepare(context, true, (Rect rect) { Rect rect = WidgetUtil.getWidgetBounds(context); setState(() { cardHeight = rect.height.toInt(); }); }); return ...; } ) ``` ### 进度条 ``` LinearProgressIndicator( backgroundColor: Color(0x42000000), value: 10 / 30, // value值为null时为一个动画 valueColor: AlwaysStoppedAnimation<Color>(Colors.white), ), ```
### Text属性详解