91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter第八期 - 控件總結篇

發布時間:2020-03-19 07:36:54 來源:網絡 閱讀:3341 作者:吳雨聲 欄目:移動開發

????最近寫前端,沒有總結flutter的學習進程,現在來總結一下,關于動畫,布局,登錄,首頁,路由,json格式化,下拉刷新,圖片加載預覽,歡迎頁,焦點問題,保活,上傳圖片,頁面信息傳遞,這些知識點。由于官方文檔給的知識點很少,大部分是一些零零散散的API,所以只能通過一些大神的總結去剝離功能性的寫法,如果理解不了的話就google,記不住的話就看demo,寫多了就記住了,前期國內資源有限大家可以慢慢的學,但是要學,如果你還想做APP的話,flutter以后肯定會有一片天地的,畢竟一套代碼三個平臺,企業老板會因為成本多多少少青睞的,所以加油~

????附:效果圖因為demo有點多,會慢慢補齊,寫了三個小時,感謝大家支持

????1.animated_container(放大 縮小github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_container):AnimationContainer使用要點,必須傳入Duration告訴動畫的播放時間,當animationContainer接收到一個新的值的時候,會根據老值進行補間動畫,例如開始寬高為100,然后給了新值0并setState后,AnimationContainer會讓寬高從100逐漸變化到0,其中變化曲線由Curve決定,默認為Curves.linear。其實動畫大部分都是封裝好的,多寫寫就會了,實在記不住就看demo,好記性不如個爛筆頭。

Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

import?'package:flutter/material.dart';
import?'animated_container_demo.dart';

void?main()?=>?runApp(new?MyApp());

class?MyApp?extends?StatelessWidget?{
??//?This?widget?is?the?root?of?your?application.
??@override
??Widget?build(BuildContext?context)?{
????return?new?MaterialApp(
??????title:?'Flutter?Demo',
??????theme:?new?ThemeData(
????????primarySwatch:?Colors.blue,
??????),
??????home:?AnimatedContainerDemo(),
????);
??}
}


/**
?*?AnimationContainer使用要點
?*?必須傳入Duration告訴動畫的播放時間
?*?當animationContainer接收到一個新的值的時候
?*?會根據老值進行補間動畫
?*?例如開始寬高為100,然后給了新值0并setState后
?*?AnimationContainer會讓寬高從100逐漸變化到0
?*?其中變化曲線由Curve決定,默認為Curves.linear
?*/
import?'package:flutter/material.dart';

class?AnimatedContainerDemo?extends?StatefulWidget?{
??@override
??_AnimatedContainerDemoState?createState()?=>?_AnimatedContainerDemoState();
}

class?_AnimatedContainerDemoState?extends?State<AnimatedContainerDemo>?{
??double?_value?=?255.0;

??_changeValue()?=>?setState(()?{
????????_value?=?_value?==?255.0???80.0?:?255.0;
????????print(_value);
??????});

??@override
??Widget?build(BuildContext?context)?{
????return?Center(
??????child:?GestureDetector(
????????onTap:?_changeValue,?//放大?縮小
????????child:?AnimatedContainer(
??????????curve:?Curves.decelerate,
??????????duration:?Duration(seconds:?1),
??????????width:?_value,
??????????height:?_value,
??????????child:?FlutterLogo(),
????????),
??????),
????);
??}
}

????2.animated_cross_fade(橫豎轉向動畫github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_cross_fade):

Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

import?'package:flutter/material.dart';

class?AnimatedCrossFadeDemo?extends?StatefulWidget?{
??@override
??_AnimatedCrossFadeDemoState?createState()?=>?_AnimatedCrossFadeDemoState();
}

class?_AnimatedCrossFadeDemoState?extends?State<AnimatedCrossFadeDemo>?{
??bool?_first?=?false;

??change()?{
????setState(()?{
??????_first?=?_first???false?:?true;
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Center(
??????child:?GestureDetector(
????????onTap:?change,?//?橫豎轉向動畫
????????child:?AnimatedCrossFade(
??????????duration:?const?Duration(seconds:?2),
??????????firstChild:?const?FlutterLogo(
????????????style:?FlutterLogoStyle.horizontal,
????????????size:?200.0,
??????????),
??????????secondChild:?const?FlutterLogo(
????????????style:?FlutterLogoStyle.stacked,
????????????size:?200.0,
??????????),
??????????crossFadeState:
??????????????_first???CrossFadeState.showFirst?:?CrossFadeState.showSecond,
????????),
??????),
????);
??}
}

????3.animated_floating_action_bar(懸浮按鈕github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_floating_action_bar):這個是官方的demo

?Flutter第八期 - 控件總結篇

import?'package:flutter/material.dart';

void?main()?=>?runApp(MyApp());

class?MyApp?extends?StatelessWidget?{
??//?This?widget?is?the?root?of?your?application.
??@override
??Widget?build(BuildContext?context)?{
????return?MaterialApp(
??????title:?'Flutter?Demo',
??????theme:?ThemeData(
????????//?This?is?the?theme?of?your?application.
????????//
????????//?Try?running?your?application?with?"flutter?run".?You'll?see?the
????????//?application?has?a?blue?toolbar.?Then,?without?quitting?the?app,?try
????????//?changing?the?primarySwatch?below?to?Colors.green?and?then?invoke
????????//?"hot?reload"?(press?"r"?in?the?console?where?you?ran?"flutter?run",
????????//?or?simply?save?your?changes?to?"hot?reload"?in?a?Flutter?IDE).
????????//?Notice?that?the?counter?didn't?reset?back?to?zero;?the?application
????????//?is?not?restarted.
????????primarySwatch:?Colors.blue,
??????),
??????home:?MyHomePage(title:?'Flutter?Demo?Home?Page'),
????);
??}
}

class?MyHomePage?extends?StatefulWidget?{
??MyHomePage({Key?key,?this.title})?:?super(key:?key);

??//?This?widget?is?the?home?page?of?your?application.?It?is?stateful,?meaning
??//?that?it?has?a?State?object?(defined?below)?that?contains?fields?that?affect
??//?how?it?looks.

??//?This?class?is?the?configuration?for?the?state.?It?holds?the?values?(in?this
??//?case?the?title)?provided?by?the?parent?(in?this?case?the?App?widget)?and
??//?used?by?the?build?method?of?the?State.?Fields?in?a?Widget?subclass?are
??//?always?marked?"final".

??final?String?title;

??@override
??_MyHomePageState?createState()?=>?_MyHomePageState();
}

class?_MyHomePageState?extends?State<MyHomePage>?{
??int?_counter?=?0;

??void?_incrementCounter()?{
????setState(()?{
??????//?This?call?to?setState?tells?the?Flutter?framework?that?something?has
??????//?changed?in?this?State,?which?causes?it?to?rerun?the?build?method?below
??????//?so?that?the?display?can?reflect?the?updated?values.?If?we?changed
??????//?_counter?without?calling?setState(),?then?the?build?method?would?not?be
??????//?called?again,?and?so?nothing?would?appear?to?happen.
??????_counter++;
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????//?This?method?is?rerun?every?time?setState?is?called,?for?instance?as?done
????//?by?the?_incrementCounter?method?above.
????//
????//?The?Flutter?framework?has?been?optimized?to?make?rerunning?build?methods
????//?fast,?so?that?you?can?just?rebuild?anything?that?needs?updating?rather
????//?than?having?to?individually?change?instances?of?widgets.
????return?Scaffold(
??????appBar:?AppBar(
????????//?Here?we?take?the?value?from?the?MyHomePage?object?that?was?created?by
????????//?the?App.build?method,?and?use?it?to?set?our?appbar?title.
????????title:?Text(widget.title),
??????),
??????body:?Center(
????????//?Center?is?a?layout?widget.?It?takes?a?single?child?and?positions?it
????????//?in?the?middle?of?the?parent.
????????child:?Column(
??????????//?Column?is?also?layout?widget.?It?takes?a?list?of?children?and
??????????//?arranges?them?vertically.?By?default,?it?sizes?itself?to?fit?its
??????????//?children?horizontally,?and?tries?to?be?as?tall?as?its?parent.
??????????//
??????????//?Invoke?"debug?painting"?(press?"p"?in?the?console,?choose?the
??????????//?"Toggle?Debug?Paint"?action?from?the?Flutter?Inspector?in?Android
??????????//?Studio,?or?the?"Toggle?Debug?Paint"?command?in?Visual?Studio?Code)
??????????//?to?see?the?wireframe?for?each?widget.
??????????//
??????????//?Column?has?various?properties?to?control?how?it?sizes?itself?and
??????????//?how?it?positions?its?children.?Here?we?use?mainAxisAlignment?to
??????????//?center?the?children?vertically;?the?main?axis?here?is?the?vertical
??????????//?axis?because?Columns?are?vertical?(the?cross?axis?would?be
??????????//?horizontal).
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????Text(
??????????????'You?have?pushed?the?button?this?many?times:',
????????????),
????????????Text(
??????????????'$_counter',
??????????????style:?Theme.of(context).textTheme.display1,
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?FloatingActionButton(
????????onPressed:?_incrementCounter,
????????tooltip:?'Increment',
????????child:?Icon(Icons.add),
??????),?//?This?trailing?comma?makes?auto-formatting?nicer?for?build?methods.
????);
??}
}

????4.animation_challenge(github:https://github.com/geeklx/flutter_app2/tree/master/app2/animation_challenge):

Flutter第八期 - 控件總結篇

????home: HeroDemo(),// 添加list item

import?'package:flutter/material.dart';
import?'package:flutter/scheduler.dart'?show?timeDilation;

class?HeroDemo?extends?StatefulWidget?{
??@override
??_HeroDemoState?createState()?=>?_HeroDemoState();
}

class?_HeroDemoState?extends?State<HeroDemo>?{
??List<String>?list;

??@override
??void?initState()?{
????super.initState();
????list?=?List.generate(20,?(index)?=>?"This?is?no.$index");
??}

??@override
??Widget?build(BuildContext?context)?{
????timeDilation?=?2.0;
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('Demo1'),
??????),
??????body:?ListView.builder(
??????????itemCount:?list.length,
??????????itemBuilder:?(context,?index)?{
????????????return?ListTile(
??????????????title:?Text(list[index]),
????????????);
??????????}),
??????floatingActionButtonLocation:?FloatingActionButtonLocation.centerFloat,
??????floatingActionButton:?Hero(
????????tag:?"FloatingActionButton",
????????child:?FloatingActionButton(
??????????backgroundColor:?Colors.blue,
??????????onPressed:?()?=>?Navigator.of(context)
??????????????.push(MaterialPageRoute(builder:?(context)?=>?SecondPage())),
??????????child:?Icon(Icons.add),
????????),
??????),
????);
??}
}

class?SecondPage?extends?StatefulWidget?{
??@override
??_SecondPageState?createState()?=>?_SecondPageState();
}

class?_SecondPageState?extends?State<SecondPage>?{
??final?FocusNode?focusNode?=?FocusNode();

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????backgroundColor:?Colors.transparent,
????????elevation:?0.0,
????????iconTheme:?IconThemeData(
??????????color:?Colors.black,
????????),
??????),
??????body:?Column(
????????crossAxisAlignment:?CrossAxisAlignment.stretch,
????????mainAxisSize:?MainAxisSize.max,
????????children:?<Widget>[
??????????ListView(
????????????shrinkWrap:?true,
????????????padding:?const?EdgeInsets.symmetric(horizontal:?20.0),
????????????children:?<Widget>[
??????????????TextField(
????????????????autofocus:?true,
????????????????focusNode:?focusNode,
????????????????maxLines:?5,
????????????????decoration:?InputDecoration.collapsed(
????????????????????hintText:?'What?do?you?want?to?add?now??'),
??????????????),
????????????],
??????????),
????????],
??????),
??????floatingActionButtonLocation:?FloatingActionButtonLocation.centerFloat,
??????floatingActionButton:?Hero(
??????????tag:?"FloatingActionButton",
??????????child:?Padding(
????????????padding:
????????????????const?EdgeInsets.only(left:?12.0,?right:?12.0,?bottom:?6.0),
????????????child:?ButtonTheme(
??????????????height:?48.0,
??????????????minWidth:?double.infinity,
??????????????child:?RaisedButton(
????????????????color:?Colors.lightBlue,
????????????????onPressed:?()?{},
????????????????elevation:?10.0,
????????????????child:?Icon(
??????????????????Icons.add,
??????????????????color:?Colors.white,
????????????????),
??????????????),
????????????),
??????????)),
????);
??}
}

????home: HideBottomBarDemo(),// 滾動隱藏底部導航 動畫

import?'package:flutter/material.dart';
import?'package:flutter/rendering.dart';

class?HideBottomBarDemo?extends?StatefulWidget?{
??@override
??_HideBottomBarDemoState?createState()?=>?_HideBottomBarDemoState();
}

class?_HideBottomBarDemoState?extends?State<HideBottomBarDemo>
????with?SingleTickerProviderStateMixin?{
??AnimationController?_animationController;
??Animation?_animation;
??ScrollController?_scrollController;

??void?_judgeScroll()?{
????if?(_scrollController.position.userScrollDirection?==
????????ScrollDirection.reverse)?{
??????_animationController.forward();
????}
????if?(_scrollController.position.userScrollDirection?==
????????ScrollDirection.forward)?{
??????_animationController.reverse();
????}
??}

??@override
??void?initState()?{
????super.initState();
????_animationController?=
????????AnimationController(vsync:?this,?duration:?Duration(milliseconds:?300));
????_animation?=?Tween(begin:?0.0,?end:?-100.0).animate(CurvedAnimation(
????????parent:?_animationController,?curve:?Curves.fastOutSlowIn));
????_scrollController?=?ScrollController(keepScrollOffset:?true)
??????..addListener(_judgeScroll);
??}

??@override
??void?dispose()?{
????//?TODO:?implement?dispose
????_animationController?.dispose();
????_scrollController..removeListener(_judgeScroll);
????//?如果銷毀ScrollController,keepScrollOffset將置空
????//?_scrollController?.dispose();
????super.dispose();
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('Immersive?BottomNavigationBar'),
??????),
??????body:?_buildListView(),
??????bottomNavigationBar:?_buildBottomNavigationBar(context),
????);
??}

??Widget?_buildBottomNavigationBar(BuildContext?context)?{
????return?AnimatedBuilder(
??????animation:?_animation,
??????builder:?(context,?child)?{
????????return?Container(
??????????height:?0.0,
??????????child:?Stack(
????????????overflow:?Overflow.visible,
????????????children:?<Widget>[
??????????????Positioned(
??????????????????bottom:?_animation.value,?left:?0.0,?right:?0.0,?child:?child)
????????????],
??????????),
????????);
??????},
??????child:?BottomNavigationBar(
????????items:?[
??????????BottomNavigationBarItem(icon:?Icon(Icons.title),?title:?Text("home")),
??????????BottomNavigationBarItem(icon:?Icon(Icons.title),?title:?Text("home")),
??????????BottomNavigationBarItem(icon:?Icon(Icons.title),?title:?Text("home")),
??????????BottomNavigationBarItem(icon:?Icon(Icons.title),?title:?Text("home")),
????????],
????????type:?BottomNavigationBarType.fixed,
??????),
????);
??}

??Widget?_buildListView()?=>?ListView.builder(
??????controller:?_scrollController,
??????itemBuilder:?(context,?index)?=>?ListTile(
????????????leading:?Icon(Icons.access_alarm),
????????????title:?Text("this?is?index:?$index"),
??????????));

}

????home: AudioScreen(),// 倒計時 暫時不好寫 沒理解(官方demo需要后續去看看寫法很巧妙)

import?'dart:async';

import?'package:flutter/material.dart';
import?'package:flutter_spinkit/flutter_spinkit.dart';

class?AudioScreen?extends?StatefulWidget?{
??@override
??_AudioScreenState?createState()?=>?_AudioScreenState();
}

class?_AudioScreenState?extends?State<AudioScreen>?{
??Stopwatch?stopwatch?=?Stopwatch();

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????body:?Container(
????????color:?Colors.orangeAccent.withOpacity(0.2),
????????child:?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????_buildRecordingStatus(),
????????????_buildTimerText(),
????????????_buildButtonRow(context),
??????????],
????????),
??????),
????);
??}

??void?_stopButtonPressed()?{
????setState(()?{
??????stopwatch
????????..stop()
????????..reset();
????});
??}

??void?_rightButtonPressed()?{
????setState(()?{
??????if?(stopwatch.isRunning)?{
????????stopwatch.stop();
??????}?else?{
????????stopwatch.start();
??????}
????});
??}

??Widget?_buildTimerText()?{
????return?Container(
????????height:?200.0,
????????child:?Center(
??????????child:?TimerText(stopwatch:?stopwatch),
????????));
??}

??Widget?_buildRecordingStatus()?{
????return?Container(
????????height:?100.0,
????????width:?100.0,
????????child:?stopwatch.isRunning
??????????????Center(
????????????????child:?SpinKitWave(
????????????????????color:?Colors.black87.withOpacity(0.7),
????????????????????type:?SpinKitWaveType.start),
??????????????)
????????????:?Image.asset("assets/recorder.png"));
??}

??Widget?_buildButtonRow(BuildContext?context)?{
????return?Row(children:?<Widget>[
??????_buildButton(_stopButtonPressed,?Colors.redAccent,?context,?Icons.stop),
??????_buildButton(_rightButtonPressed,?Colors.blueAccent,?context,
??????????stopwatch.isRunning???Icons.pause?:?Icons.play_arrow),
????]);
??}

??Widget?_buildButton(
??????VoidCallback?callback,?Color?color,?BuildContext?context,?IconData?icon)?{
????Size?size?=?MediaQuery.of(context).size;
????return?Container(
????????width:?size.width?*?0.5,
????????alignment:?Alignment.center,
????????child:?RaisedButton(
??????????elevation:?0.0,
??????????shape:
??????????????RoundedRectangleBorder(borderRadius:?BorderRadius.circular(36.0)),
??????????color:?color,
??????????onPressed:?callback,
??????????child:?Container(
????????????width:?size.width?*?0.5?-?80.0,
????????????height:?MediaQuery.of(context).size.width?*?0.15,
????????????child:?Icon(
??????????????icon,
??????????????color:?Colors.white,
??????????????size:?32.0,
????????????),
??????????),
????????));
??}
}

class?TimerText?extends?StatefulWidget?{
??TimerText({this.stopwatch});
??final?Stopwatch?stopwatch;

??TimerTextState?createState()?=>?TimerTextState(stopwatch:?stopwatch);
}

class?TimerTextState?extends?State<TimerText>?{
??Timer?timer;
??final?Stopwatch?stopwatch;

??TimerTextState({this.stopwatch})?{
????timer?=?Timer.periodic(Duration(milliseconds:?30),?callback);
??}

??void?callback(Timer?timer)?{
????if?(stopwatch.isRunning)?{
??????setState(()?{});
????}
??}

??@override
??Widget?build(BuildContext?context)?{
????final?double?width?=?MediaQuery.of(context).size.width;
????final?TextStyle?timerTextStyle?=?const?TextStyle(
??????fontSize:?60.0,
??????fontFamily:?"Open?Sans",
??????fontWeight:?FontWeight.w300,
??????color:?Colors.black87,
????);
????List<String>?formattedTime?=
????????TimerTextFormatter.format(stopwatch.elapsedMilliseconds);
????return?Row(
??????mainAxisAlignment:?MainAxisAlignment.center,
??????children:?<Widget>[
????????Container(
??????????child:?Text(
????????????"${formattedTime[0]}:",
????????????style:?timerTextStyle,
??????????),
??????????width:?width?/?4.0,
????????),
????????Container(
??????????child:?Text(
????????????"${formattedTime[1]}:",
????????????style:?timerTextStyle,
??????????),
??????????width:?width?/?4.1,
????????),
????????Container(
??????????child:?Text(
????????????"${formattedTime[2]}",
????????????style:?timerTextStyle,
??????????),
??????????width:?width?/?4.6,
????????),
??????],
????);
??}
}

class?TimerTextFormatter?{
??static?List<String>?format(int?milliseconds)?{
????int?hundreds?=?(milliseconds?/?10).truncate();
????int?seconds?=?(hundreds?/?100).truncate();
????int?minutes?=?(seconds?/?60).truncate();

????String?minutesStr?=?(minutes?%?60).toString().padLeft(2,?'0');
????String?secondsStr?=?(seconds?%?60).toString().padLeft(2,?'0');
????String?hundredsStr?=?(hundreds?%?100).toString().padLeft(2,?'0');

????return?[minutesStr,?secondsStr,?hundredsStr];
//????return?"$minutesStr:$secondsStr:$hundredsStr";
??}
}

????home: ImScreen(),// IM 聊天 這里需要注意的是listview滾動會因為item的增加卡頓,目前布局這塊沒有好的方案,期待官方。

import?'dart:async';

import?'package:flutter/material.dart';

class?ImScreen?extends?StatefulWidget?{
??@override
??_ImScreenState?createState()?=>?_ImScreenState();
}

class?_ImScreenState?extends?State<ImScreen>?{
??StreamController?_messageController;
??TextEditingController?_textController;
??List?_myMessages;
??final?_myName?=?"Vadaski";

??@override
??void?initState()?{
????//?TODO:?implement?initState
????super.initState();
????_messageController?=?StreamController();
????_textController?=?TextEditingController();
????_myMessages?=?List();
??}

??@override
??void?dispose()?{
????_textController.dispose();
????_messageController.close();
????super.dispose();
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('IM?Challenge'),
????????centerTitle:?true,
??????),
??????body:?SafeArea(
????????child:?Column(
??????????children:?<Widget>[
????????????Flexible(
????????????????child:?ListView.builder(
????????????????????reverse:?true,
????????????????????itemCount:?_myMessages.length,
????????????????????itemBuilder:?(context,?index)?{
??????????????????????return?_buildMessageWidget(_myMessages[index],?context);
????????????????????})),
????????????Divider(
??????????????height:?1.0,
????????????),
????????????_buildInputWidget(context),
??????????],
????????),
??????),
????);
??}

??Widget?_buildInputWidget(BuildContext?context)?{
????return?SizedBox(
??????child:?Padding(
????????padding:?const?EdgeInsets.only(left:?8.0,?right:?8.0),
????????child:?Row(
??????????children:?<Widget>[
????????????Flexible(
????????????????child:?TextField(
??????????????decoration:
??????????????????InputDecoration.collapsed(hintText:?"Send?your?message"),
??????????????controller:?_textController,
??????????????onChanged:?onMessageChanged,
??????????????onSubmitted:?onMessageSubmit,
????????????)),
????????????Container(
??????????????margin:?const?EdgeInsets.symmetric(horizontal:?4.0),
??????????????child:?StreamBuilder(
????????????????initialData:?"",
????????????????stream:?_messageController.stream,
????????????????builder:?(context,?snapshot)?{
??????????????????return?IconButton(
????????????????????icon:?Icon(
??????????????????????Icons.send,
??????????????????????color:?snapshot.data?==?""
????????????????????????????Colors.grey
??????????????????????????:?Theme.of(context).accentColor,
????????????????????),
????????????????????onPressed:?()?=>?onMessageSubmit(_textController.text),
??????????????????);
????????????????},
??????????????),
????????????)
??????????],
????????),
??????),
????);
??}

??Widget?_buildMessageWidget(String?text,?BuildContext?context)?{
????return?Container(
??????margin:?const?EdgeInsets.symmetric(vertical:?10.0),
??????width:?MediaQuery.of(context).size.width?/?2,
??????child:?Row(
????????crossAxisAlignment:?CrossAxisAlignment.start,
????????children:?<Widget>[
??????????SizedBox(
????????????width:?MediaQuery.of(context).size.width?/?4,
??????????),
??????????Expanded(
????????????child:?Column(
??????????????crossAxisAlignment:?CrossAxisAlignment.end,
??????????????children:?<Widget>[
????????????????Text(_myName,?style:?Theme.of(context).textTheme.subhead),
????????????????Container(
??????????????????decoration:?BoxDecoration(
??????????????????????borderRadius:?BorderRadius.circular(12.0),
??????????????????????color:?Colors.blue.withOpacity(0.2)),
??????????????????margin:?const?EdgeInsets.only(top:?5.0),
??????????????????child:?Padding(
????????????????????padding:?const?EdgeInsets.all(8.0),
????????????????????child:?Text(
??????????????????????text,
??????????????????????overflow:?TextOverflow.fade,
??????????????????????softWrap:?true,
????????????????????),
??????????????????),
????????????????)
??????????????],
????????????),
??????????),
??????????Container(
????????????margin:?const?EdgeInsets.only(right:?16.0,?left:?8.0),
????????????child:?CircleAvatar(
??????????????child:?Text(_myName[0]),
????????????),
??????????),
????????],
??????),
????);
??}

??onMessageChanged(String?message)?{
????_messageController.sink.add(message);
??}

??onMessageSubmit(String?message)?{
????_textController.clear();
????if?(message?!=?"")?{
??????setState(()?{
????????_myMessages.insert(0,?message);
??????});
????}
????onMessageChanged("");
??}
}

????home: RotatingScreen(),//

import 'package:flutter/material.dart';

import '../widgets/rotating_bar.dart';

class RotatingScreen extends StatelessWidget {
?@override
?Widget build(BuildContext context) {
? ?final size = MediaQuery.of(context).size;

? ?return Scaffold(
? ? ? ?body: Stack(
? ? ?children: <Widget>[
? ? ? ?Positioned(
? ? ? ? ?left: size.width / 5,
? ? ? ? ?top: size.height / 3,
? ? ? ? ?child: RotatingBar(
? ? ? ? ? ?getBackCenter: true,
? ? ? ? ? ?dx: size.width / 5,
? ? ? ? ? ?dy: size.height / 3,
? ? ? ? ? ?style: Style.Touch,
? ? ? ? ? ?getAngle: (angle) {
? ? ? ? ? ? ?print(angle);
? ? ? ? ? ?},
? ? ? ? ?),
? ? ? ?)
? ? ?],
? ?));
?}
}

????home: ScrollBackToTop(),// 滾動到頂部 這個比較常用

import 'package:flutter/material.dart';

class ScrollBackToTop extends StatefulWidget {
?@override
?_ScrollBackToTopState createState() => _ScrollBackToTopState();
}

class _ScrollBackToTopState extends State<ScrollBackToTop>
? ?with SingleTickerProviderStateMixin {
?ScrollController _controller;

?@override
?void initState() {
? ?super.initState();
? ?_controller = ScrollController();
?}

?@override
?void dispose() {
? ?_controller.dispose();
? ?super.dispose();
?}

?@override
?Widget build(BuildContext context) {
? ?return Scaffold(
? ? ?appBar: AppBar(
? ? ? ?title: Text('Scroll Back To Top Demo'),
? ? ? ?centerTitle: true,
? ? ?),
? ? ?body: ListView.builder(
? ? ? ? ?controller: _controller,
? ? ? ? ?itemCount: 100,
? ? ? ? ?itemBuilder: (context, index) {
? ? ? ? ? ?return ListTile(
? ? ? ? ? ? ?title: Center(
? ? ? ? ? ? ? ? ?child: Text(
? ? ? ? ? ? ? ?'This is no $index',
? ? ? ? ? ? ? ?style: TextStyle(fontSize: 24),
? ? ? ? ? ? ?)),
? ? ? ? ? ?);
? ? ? ? ?}),
? ? ?floatingActionButton: FloatingActionButton(
? ? ? ?onPressed: backToTop,
? ? ? ?child: Icon(Icons.vertical_align_top),
? ? ?),
? ?);
?}

?backToTop() {
? ?if (_controller.offset != 0)
? ? ?_controller.animateTo(
? ? ? ?0,
? ? ? ?duration: Duration(milliseconds: 500),
? ? ? ?curve: Curves.easeIn,
? ? ?);
?}
}

????5.animation_demo(總結一下各種目前能用的場景化動畫github:https://github.com/geeklx/flutter_app2/tree/master/app2/animation_demo):由于篇幅有限代碼就不說了,地址附上?Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

????6.beaytiful_search_bar_demo(搜索欄):https://github.com/geeklx/flutter_app2/tree/master/app2/beaytiful_search_bar_demo

Flutter第八期 - 控件總結篇

import 'package:flutter/material.dart';
import 'asset.dart';

class SearchBarDemo extends StatefulWidget {
?@override
?_SearchBarDemoState createState() => _SearchBarDemoState();
}

class _SearchBarDemoState extends State<SearchBarDemo> {
?@override
?Widget build(BuildContext context) {
? ?return Scaffold(
? ? ?appBar: AppBar(
? ? ? ?title: Text('SearchBarDemo'),
? ? ? ?actions: <Widget>[
? ? ? ? ?IconButton(
? ? ? ? ? ? ?icon: Icon(Icons.search),
? ? ? ? ? ? ?onPressed: () =>
? ? ? ? ? ? ? ? ?showSearch(context: context, delegate: SearchBarDelegate())),
? ? ? ?],
? ? ?),
? ?);
?}
}

const searchList = [
?"ChengDu",
?"ShangHai",
?"BeiJing",
?"TianJing",
?"NanJing",
?"ShenZheng"
];

const recentSuggest = [
?"suggest1",
?"suggest2"
];

class SearchBarDelegate extends SearchDelegate<String> {
?@override
?List<Widget> buildActions(BuildContext context) {
? ?return [IconButton(icon: Icon(Icons.clear), onPressed: () => query = "")];
?}

?@override
?Widget buildLeading(BuildContext context) {
? ?return IconButton(
? ? ? ?icon: AnimatedIcon(
? ? ? ? ? ?icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
? ? ? ?onPressed: () => close(context, null));
?}

?@override
?Widget buildResults(BuildContext context) {
? ?return Center(child: Container(
? ? ?width: 100.0,
? ? ?height: 100.0,
? ? ?child: Card(
? ? ? ?color: Colors.redAccent,
? ? ? ?child: Center(
? ? ? ? ?child: Text(query),
? ? ? ?),
? ? ?),
? ?),);
?}

?@override
?Widget buildSuggestions(BuildContext context) {
? ?final suggestionList = query.isEmpty
? ? ? ?? recentSuggest
? ? ? ?: searchList.where((input) => input.startsWith(query)).toList();
? ?return ListView.builder(
? ? ? ?itemCount: suggestionList.length,
? ? ? ?itemBuilder: (context, index) => ListTile(

? ? ? ? ?onTap: (){
? ? ? ? ? ?query = suggestionList[index];
? ? ? ? ? ?showResults(context);},

? ? ? ? ? ? ?title: RichText(
? ? ? ? ? ? ? ? ?text: TextSpan(
? ? ? ? ? ? ? ? ? ? ?text: suggestionList[index].substring(0, query.length),
? ? ? ? ? ? ? ? ? ? ?style: TextStyle(
? ? ? ? ? ? ? ? ? ? ? ? ?color: Colors.black, fontWeight: FontWeight.bold),
? ? ? ? ? ? ? ? ? ? ?children: [
? ? ? ? ? ? ? ? ? ?TextSpan(
? ? ? ? ? ? ? ? ? ? ? ?text: suggestionList[index].substring(query.length),
? ? ? ? ? ? ? ? ? ? ? ?style: TextStyle(color: Colors.grey))
? ? ? ? ? ? ? ? ?])),
? ? ? ? ? ?));
?}
}

????7.bloc_provider_pattern(監聽私有方法調用寫法):https://github.com/geeklx/flutter_app2/tree/master/app2/bloc_provider_pattern

Flutter第八期 - 控件總結篇

import 'dart:async';

import './bloc_base.dart';

class IncrementBloc implements BlocBase {
?int _counter;

?StreamController<int> _counterPipe = StreamController<int>();
?Stream<int> get outCounter => _counterPipe.stream;

?IncrementBloc() {
? ?_counter = 0;
? ?//_counterPipe 用于StreamBuilder,已經自動加了listen
?}

?incrementCounter() {
? ?_counter = _counter + 1;
? ?_counterPipe.sink.add(_counter);
?}

?void dispose() {
? ?print('bloc disposed!');
? ?_counterPipe.close();
?}
}


import 'package:flutter/material.dart';

// Generic Interface for all BLoCs
abstract class BlocBase {
?void dispose();
}

// Generic BLoC provider
class BlocProvider<T extends BlocBase> extends StatefulWidget {
?BlocProvider({
? ?Key key,
? ?@required this.child,
? ?@required this.bloc,
?}) : super(key: key);

?final T bloc;
?final Widget child;

?@override
?_BlocProviderState<T> createState() => _BlocProviderState<T>();

?static T of<T extends BlocBase>(BuildContext context) {
? ?final type = _typeOf<BlocProvider<T>>();
? ?BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
? ?return provider.bloc;
?}

?static Type _typeOf<T>() => T;
}

class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
?@override
?void dispose() {
? ?widget.bloc.dispose();
? ?super.dispose();
?}

?@override
?Widget build(BuildContext context) {
? ?return widget.child;
?}
}
//EOP

????8.bottom_appbar_demo(底部導航 比較常用的base寫法):https://github.com/geeklx/flutter_app2/tree/master/app2/bottom_appbar_demo

Flutter第八期 - 控件總結篇

import 'package:flutter/material.dart';

class EachView extends StatefulWidget {
?String _title;
?EachView(this._title);
?@override
?_EachViewState createState() => _EachViewState();
}

class _EachViewState extends State<EachView> {
?@override
?Widget build(BuildContext context) {
? ?return Scaffold(
? ? ?appBar: AppBar(title: Text(widget._title),),
? ?);
?}
}

import 'package:flutter/material.dart';
import 'each_view.dart';

class BottomAppBarDemo extends StatefulWidget {
?@override
?_BottomAppBarDemoState createState() => _BottomAppBarDemoState();
}

class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
?List<Widget> _eachView;
?int _index = 0;

?@override
?void initState() {
? ?// TODO: implement initState
? ?super.initState();
? ?_eachView = List();
? ?_eachView..add(EachView('home'))..add(EachView('me'));
?}

?@override
?Widget build(BuildContext context) {
? ?return new Scaffold(
? ? ?body: _eachView[_index],
? ? ?floatingActionButton: new FloatingActionButton(
? ? ? ?onPressed: () {
? ? ? ? ?Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context){
? ? ? ? ? ?return EachView('New Page');
? ? ? ? ?}));
? ? ? ?},
? ? ? ?tooltip: 'Increment',
? ? ? ?child: new Icon(Icons.add),
? ? ?), // T
? ? ?floatingActionButtonLocation:
? ? ? ? ?FloatingActionButtonLocation.centerDocked, // his
? ? ?bottomNavigationBar: BottomAppBar(
? ? ? ?color: Colors.lightBlue,
? ? ? ?shape: CircularNotchedRectangle(),
? ? ? ?child: Row(
? ? ? ? ?mainAxisSize: MainAxisSize.max,
? ? ? ? ?mainAxisAlignment: MainAxisAlignment.spaceAround,
? ? ? ? ?children: <Widget>[
? ? ? ? ? ?IconButton(
? ? ? ? ? ? ?icon: Icon(Icons.near_me),
? ? ? ? ? ? ?color: Colors.white,
? ? ? ? ? ? ?onPressed: () {
? ? ? ? ? ? ? ?setState(() {
? ? ? ? ? ? ? ? ?_index = 0;
? ? ? ? ? ? ? ?});
? ? ? ? ? ? ?},
? ? ? ? ? ?),
? ? ? ? ? ?IconButton(
? ? ? ? ? ? ?icon: Icon(Icons.edit_location),
? ? ? ? ? ? ?color: Colors.white,
? ? ? ? ? ? ?onPressed: () {
? ? ? ? ? ? ? ?setState(() {
? ? ? ? ? ? ? ? ?_index = 1;
? ? ? ? ? ? ? ?});
? ? ? ? ? ? ?},
? ? ? ? ? ?),
? ? ? ? ?],
? ? ? ?),
? ? ?),
? ?);
?}
}

????9.chip_demo(勾選擇view的各種效果):https://github.com/geeklx/flutter_app2/tree/master/app2/chip_demo

Flutter第八期 - 控件總結篇

import 'package:chip_demo/input_chip.dart';
/**
* 請通過切換home的注釋分別查看
*/
import 'package:flutter/material.dart';

import 'choice_chip.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
?@override
?Widget build(BuildContext context) {
? ?return new MaterialApp(
? ? ?title: 'Flutter Demo',
? ? ?theme: new ThemeData.light(),
// ? ? ?home: ChipDemo(),
// ? ? ?home: ActionChipDemo(),
// ? ? ?home: FilterChipDemo(),// 勾選狀態
// ? ? ?home: ChoiceChipDemo(), // 選中狀態 常用的
? ? ?home: InputChipDemo(),
? ?);
?}
}

????10.custom_router_transition(標準的路由寫法):https://github.com/geeklx/flutter_app2/tree/master/app2/custom_router_transition

/**
* Navigator.of(context).push自定義的route
*/
import 'package:flutter/material.dart';
import 'custome_router.dart';

class FirstPage extends StatelessWidget {
?@override
?Widget build(BuildContext context) {
? ?return Scaffold(
? ? ?backgroundColor: Colors.blue,
? ? ?appBar: AppBar(
? ? ? ?title: Text(
? ? ? ? ?'FirstPage',
? ? ? ? ?style: TextStyle(fontSize: 36.0),
? ? ? ?),
? ? ? ?elevation: 0.0,
? ? ?),
? ? ?body: Center(
? ? ? ?child: MaterialButton(
? ? ? ? ? ?child: Icon(
? ? ? ? ? ? ?Icons.navigate_next,
? ? ? ? ? ? ?color: Colors.white,
? ? ? ? ? ? ?size: 64.0,
? ? ? ? ? ?),
? ? ? ? ? ?onPressed: () =>
? ? ? ? ? ? ? ?Navigator.of(context).push(
? ? ? ? ? ? ? ? ? ?CustomRoute(SecondPage()))),
? ? ?),
? ?);
?}
}

class SecondPage extends StatelessWidget {
?@override
?Widget build(BuildContext context) {
? ?return Scaffold(
? ? ?backgroundColor: Colors.pinkAccent,
? ? ?appBar: AppBar(
? ? ? ?title: Text('SecondPage',style: TextStyle(fontSize: 36.0),),
? ? ? ?backgroundColor: Colors.pinkAccent,
? ? ? ?leading: Container(),
? ? ? ?elevation: 0.0,
? ? ?),
? ? ?body: Center(
? ? ? ?child: MaterialButton(
? ? ? ? ? ?child: Icon(
? ? ? ? ? ? ?Icons.navigate_before,
? ? ? ? ? ? ?color: Colors.white,
? ? ? ? ? ? ?size: 64.0,
? ? ? ? ? ?),
? ? ? ? ? ?onPressed: () => Navigator.of(context).pop()),
? ? ?),
? ?);
?}
}


提供幾個過度動畫
/**
* 通過自定義transitionsBuilder實現路由過渡動畫
*
* 請切換不同注釋分別查看
*/
import 'package:flutter/material.dart';

class CustomRoute extends PageRouteBuilder {
?final Widget widget;
?CustomRoute(this.widget)
? ? ?: super(
? ? ? ? ?transitionDuration: const Duration(seconds: 2),
? ? ? ? ?pageBuilder: (BuildContext context, Animation<double> animation,
? ? ? ? ? ? ?Animation<double> secondaryAnimation) {
? ? ? ? ? ?return widget;
? ? ? ? ?},
? ? ? ? ?transitionsBuilder: (BuildContext context,
? ? ? ? ? ? ?Animation<double> animation,
? ? ? ? ? ? ?Animation<double> secondaryAnimation,
? ? ? ? ? ? ?Widget child) {
? ? ? ? ? ?//淡出過渡路由
? ? ? ? ?return FadeTransition(
? ? ? ? ? ? ?opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
? ? ? ? ? ? ? ? ?parent: animation, curve: Curves.fastOutSlowIn)),
? ? ? ? ? ? ?child: child,
? ? ? ? ? ? ?);

? ? ? ? ? ?//比例轉換路由
// ? ? ? ? ?return ScaleTransition(
// ? ? ? ? ? ?scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
// ? ? ? ? ? ? ? ?parent: animation, curve: Curves.fastOutSlowIn)),
// ? ? ? ? ? ?child: child,
// ? ? ? ? ? ?);

? ? ? ? ? ?//旋轉+比例轉換路由
// ? ? ? ? ? ?return RotationTransition(
// ? ? ? ? ? ? ?turns: Tween(begin: -1.0, end: 1.0).animate(CurvedAnimation(
// ? ? ? ? ? ? ? ? ?parent: animation, curve: Curves.fastOutSlowIn)),
// ? ? ? ? ? ? ?child: ScaleTransition(
// ? ? ? ? ? ? ? ?scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
// ? ? ? ? ? ? ? ? ? ?parent: animation, curve: Curves.fastOutSlowIn)),
// ? ? ? ? ? ? ? ?child: child,
// ? ? ? ? ? ? ?),
// ? ? ? ? ? ?);

? ? ? ? ? ?//幻燈片路由
// ? ? ? ? ? ?return SlideTransition(
// ? ? ? ? ? ? ?position:
// ? ? ? ? ? ? ? ? ?Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset(0.0, 0.0))
// ? ? ? ? ? ? ? ? ? ? ?.animate(CurvedAnimation(
// ? ? ? ? ? ? ? ? ? ? ? ? ?parent: animation, curve: Curves.fastOutSlowIn)),
// ? ? ? ? ? ? ?child: child,
// ? ? ? ? ? ?);
? ? ? ? ?},
? ? ? ?);
}

????11.event_bus_demo(利用eventbus同步頁面數據局部刷新 比較常用):https://github.com/geeklx/flutter_app2/tree/master/app2/event_bus_demo

import 'package:flutter/material.dart';
import 'tools/bus.dart';
import 'events/count_events.dart';
import 'sceeens/first_screen.dart';

void main(){
?runApp(App());
?behaviorBus.fire(CountEvent(0));
}

class App extends StatelessWidget {
?@override
?Widget build(BuildContext context) {
? ?return MaterialApp(
? ? ?title: 'Flutter Demo',
? ? ?theme: ThemeData.dark(),
? ? ?home: FirstScreen(),

? ?);
?}
}

????12.expansion_demo(級聯listview 目前這塊官方沒有demo 只找到郭神的一個寫法 視圖刷新很卡 目前也只能這樣 后續跟進):https://github.com/geeklx/flutter_app2/tree/master/app2/expansion_demo

Flutter第八期 - 控件總結篇

1.
/**
?*最基礎的展開小部件expansion?tile
?*?用法很簡單,將需要被展開的部件放在children中即可
?*?其他用法和list?tile很相似
?*?當expansion?tile?被展開時,我們可以看到background?color
?*?會進行一個transition動畫進行過渡
?*?expansion?tile還有一個trailing屬性,代表右邊的小箭頭
?*?可以自行替換
?*?initiallyExpanded代表最初的狀態是否被展開
?*?默認為false,也就是不展開
?*
?*?當一個list?view中由多個expansion?tile的時候
?*?需要給每一個expansion?tile指定唯一的[PageStorageKey]
?*?以保證在滑動的過程中,能夠記住expansion?tile的開關狀態
?*/

import?'package:flutter/material.dart';

class?ExpansionTileDemo?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(title:?Text('expansion?tile?demo'),),
??????body:?Center(
????????child:?ExpansionTile(
????????????title:?Text('Expansion?Tile'),
????????????leading:?Icon(Icons.ac_unit),
????????????backgroundColor:?Colors.white12,
????????????children:?<Widget>[
??????????????ListTile(
????????????????title:?Text('list?tile'),
????????????????subtitle:?Text('subtitle'),
??????????????),
????????????],
//??????????initiallyExpanded:?true,
????????),
??????),
????);
??}
}

2.
/**
?*??說實話,我覺得expansion?panel?list一點都不好用
?*??所以不想寫注釋。
?*??這里樣例代碼來自于flutter開發者
?*??他會經常更新一些flutter教程,寫的挺不錯的,有興趣自己去看看吧
?*??https://mp.weixin.qq.com/s/Qv08V42LgEr8IATUSfVVHg
?*
?*??需要注意幾點:
?*??ExpansionPanelList必須放在可滑動組件中使用
?*??ExpansionPanel只能在ExpansionPanelList中使用
?*??除了ExpansionPanel還有一種特殊的ExpansionPanelRadio
?*??也是只能在ExpansionPanelList中使用的
?*/

import?'package:flutter/material.dart';

class?ExpansionPanelListDemo?extends?StatefulWidget?{
??@override
??_ExpansionPanelListDemoState?createState()?=>?_ExpansionPanelListDemoState();
}

class?_ExpansionPanelListDemoState?extends?State<ExpansionPanelListDemo>?{
??var?currentPanelIndex?=?-1;

??List<int>?mList;
??//用來保存expansionPanel的狀態
??List<ExpandStateBean>?expandStateList;

??_ExpansionPanelListDemoState()?{
????mList?=?new?List();
????expandStateList?=?new?List();
????for?(int?i?=?0;?i?<?10;?i++)?{
??????mList.add(i);
??????expandStateList.add(ExpandStateBean(i,?false));
????}
??}

??_setCurrentIndex(int?index,?isExpand)?{
????setState(()?{
??????expandStateList.forEach((item)?{
????????if?(item.index?==?index)?{
??????????item.isOpen?=?!isExpand;
????????}
??????});
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
????????appBar:?AppBar(
??????????title:?Text("expansion?panel?list"),
????????),
????????body:?SingleChildScrollView(
??????????child:?ExpansionPanelList(
????????????expansionCallback:?(index,?bol)?{
??????????????_setCurrentIndex(index,?bol);
????????????},
????????????children:?mList.map((index)?{
??????????????return?new?ExpansionPanel(
????????????????headerBuilder:?(context,?isExpanded)?{
??????????????????return?new?ListTile(
????????????????????title:?new?Text('This?is?NO.?$index'),
??????????????????);
????????????????},
????????????????body:?ListTile(
??????????????????title:?Text('expansion?no.$index'),
????????????????),
????????????????isExpanded:?expandStateList[index].isOpen,
??????????????);
????????????}).toList(),
??????????),
????????));
??}
}

class?ExpandStateBean?{
??var?isOpen;
??var?index;
??ExpandStateBean(this.index,?this.isOpen);
}

????13.flutter_bottomnavigationbar(底部導航標準寫法支持保活):https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_bottomnavigationbar

Flutter第八期 - 控件總結篇

1.
import?'package:flutter/material.dart';

class?AirPlayScreen?extends?StatefulWidget?{
??@override
??_AirPlayScreenState?createState()?=>?_AirPlayScreenState();
}

class?_AirPlayScreenState?extends?State<AirPlayScreen>
????with?AutomaticKeepAliveClientMixin?{
??@override
??//?TODO:?implement?wantKeepAlive
??bool?get?wantKeepAlive?=>?true;

??int?_counter?=?0;

??void?_incrementCounter()?{
????setState(()?{
??????_counter++;
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('AirPlayScreen'),
??????),
??????body:?new?Center(
????????child:?new?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????new?Text(
??????????????'You?have?pushed?the?button?this?many?times:',
????????????),
????????????new?Text(
??????????????'$_counter',
??????????????style:?Theme.of(context).textTheme.display1,
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?new?FloatingActionButton(
????????onPressed:?_incrementCounter,
????????tooltip:?'Increment',
????????child:?new?Icon(Icons.add),
??????),
????);
??}
}

2.
import?'package:flutter/material.dart';
import?'package:flutter_bottomnavigationbar/pages_keep_alive/airplay_screen.dart';
import?'package:flutter_bottomnavigationbar/pages_keep_alive/email_screen.dart';
import?'package:flutter_bottomnavigationbar/pages_keep_alive/home_screen.dart';
import?'package:flutter_bottomnavigationbar/pages_keep_alive/pages_screen.dart';

class?NavigationKeepAlive?extends?StatefulWidget?{
??@override
??_NavigationKeepAliveState?createState()?=>?_NavigationKeepAliveState();
}

class?_NavigationKeepAliveState?extends?State<NavigationKeepAlive>
????with?SingleTickerProviderStateMixin?{

??final?_bottomNavigationColor?=?Colors.blue;
??int?_currentIndex?=?0;
??var?_controller?=?PageController(
????initialPage:?0,
??);

??@override
??void?dispose()?{
????super.dispose();
????_controller.dispose();
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????body:?PageView(
????????controller:?_controller,
????????children:?<Widget>[
??????????AirPlayScreen(),
??????????EmailScreen(),
??????????HomeScreen(),
??????????PagesScreen()
????????],
????????physics:?NeverScrollableScrollPhysics(),
??????),
??????bottomNavigationBar:?BottomNavigationBar(
????????currentIndex:?_currentIndex,
//??????????onTap:?(index)=>?_controller.animateToPage(index,?duration:?Duration(milliseconds:?500),?curve:?Curves.fastOutSlowIn),
????????onTap:?(index)?{
??????????_controller.jumpToPage(index);
??????????setState(()?{
????????????_currentIndex?=?index;
??????????});
????????},
????????type:?BottomNavigationBarType.fixed,
????????items:?[
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.home,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'HOME',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.email,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'Email',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.pages,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'PAGES',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.airplay,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'AIRPLAY',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
????????],
??????),
????);
??}
}

3.
/**
?*?新增使用pageview實現方式:navigation——keep——alive
?*?這種方式能夠通過子頁面state實現AutomaticKeepAliveClientMixin
?*?達到切換各頁面保持狀態的效果。
?*?請切換home注釋分別查看
?*/
import?'package:flutter/material.dart';
import?'bottom_navigation_widget.dart';

import?'navigation_keep_alive.dart';

void?main()?=>?runApp(new?MyApp());

class?MyApp?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?new?MaterialApp(
??????title:?'Flutter?bottomNavigationBar',
??????theme:?new?ThemeData.dark(),
//??????home:?BottomNavigationWidget(),
????home:?NavigationKeepAlive(),
????);
??}
}

????14.flutter_provide(官方寫法不用eventbus實現數據同步刷新共享):https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_provide

1.
import?'package:flutter/material.dart';

class?Counter?with?ChangeNotifier{
??int?value?=?0;

??increment(){
????value++;
????notifyListeners();
??}
}
2.
import?'package:flutter/material.dart';

class?Switcher?with?ChangeNotifier{
??bool?status?=?false;

??changeStatus(){
????status?=?!status;
????notifyListeners();
??}
}
3.
import?'package:flutter/material.dart';
import?'package:provide/provide.dart';

import?'models/counter.dart';
import?'models/switcher.dart';
import?'second_screen.dart';

class?FirstScreen?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????body:?Center(
????????child:?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????Text('You?have?pushed?the?button?this?many?times:'),
????????????Provide<Counter>(
??????????????builder:?(context,?child,?counter)?{
????????????????return?Text(
??????????????????'${counter.value}',
??????????????????style:?Theme.of(context).textTheme.display1,
????????????????);
??????????????},
????????????),
????????????Provide<Switcher>(
??????????????builder:?(context,?child,?switcher)?{
????????????????return?Switch(
????????????????????value:?switcher.status,
????????????????????onChanged:?(newValue)?{
??????????????????????switcher.changeStatus();
????????????????????});
??????????????},
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?FloatingActionButton(
????????onPressed:?()?{
??????????Navigator.of(context)
??????????????.push(MaterialPageRoute(builder:?(context)?=>?SecondScreen()));
????????},
????????child:?Icon(Icons.navigate_next),
??????),
????);
??}
}
4.
import?'package:flutter/material.dart';
import?'package:provide/provide.dart';
import?'models/counter.dart';
import?'models/switcher.dart';

class?SecondScreen?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????body:?Center(
????????child:?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????Text('You?have?pushed?the?button?this?many?times:'),
????????????Provide<Counter>(
??????????????builder:?(context,?child,?counter)?{
????????????????return?Text(
??????????????????'${counter.value}',
??????????????????style:?Theme.of(context).textTheme.display1,
????????????????);
??????????????},
????????????),
????????????Provide<Switcher>(
??????????????builder:?(context,?child,?switcher)?{
????????????????return?Switch(
????????????????????value:?switcher.status,
????????????????????onChanged:?(newValue)?{
??????????????????????switcher.changeStatus();
????????????????????});
??????????????},
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?FloatingActionButton(
????????onPressed:?()?{
??????????Provide.value<Counter>(context).increment();
????????},
????????child:?Icon(Icons.add),
??????),
????);
??}
}

????15.flutter_widget_of_the_week(自定義控件部分):https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_widget_of_the_week

????16.frosted_glass_style_demo(毛玻璃效果):https://github.com/geeklx/flutter_app2/tree/master/app2/frosted_glass_style_demo ?

Flutter第八期 - 控件總結篇/**
?*?使用BackdropFilter實現毛玻璃效果,且子部件需要設置Opacity
?*?使用這個部件的代價很高,盡量少用
?*?ImageFilter.blur的sigmaX/Y決定了毛玻璃的模糊程度,值越高越模糊
?*?一般來說,為了防止模糊效果繪制出邊界,需要使用ClipRect?Widget包裹
?*/
import?'package:flutter/material.dart';
import?'dart:ui';

class?FrostedGlassDemo?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?new?Scaffold(
??????body:?new?Stack(
????????children:?<Widget>[
??????????new?ConstrainedBox(
??????????????constraints:?const?BoxConstraints.expand(),
??????????????child:?new?FlutterLogo()),
??????????new?Center(
????????????child:?new?ClipRect(
??????????????child:?new?BackdropFilter(
????????????????filter:?ImageFilter.blur(sigmaX:?10.0,?sigmaY:?10.0),
????????????????child:?Opacity(
??????????????????opacity:?0.5,
??????????????????child:?new?Container(
????????????????????width:?200.0,
????????????????????height:?200.0,
??????????????????decoration:?new?BoxDecoration(
//??????????????????color:?Colors.grey.shade200.withOpacity(0.5),
??????????????????color:?Colors.grey.shade200,
??????????????????),
????????????????????child:?new?Center(
??????????????????????child:?new?Text('Frosted',
??????????????????????????style:?Theme.of(context).textTheme.display3),
????????????????????),
??????????????????),
????????????????),
??????????????),
????????????),
??????????),
????????],
??????),
????);
??}
}

????17.hero_demo(官方提供的標準跟隨動畫 目前感覺場景用處不多 可再看看):https://github.com/geeklx/flutter_app2/tree/master/app2/hero_demo

Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

1.
/**
?*?當HeroAnimation作為app的home屬性提供時,
?*?MaterialApp會隱式推送起始路徑。
?*?InkWell包裝圖像,使得向源和目標英雄添加輕擊手勢變得非常簡單。
?*?使用透明顏色定義“材質”窗口小部件可使圖像在飛往目標時“彈出”背景。
?*?SizedBox指定動畫開始和結束時英雄的大小。
?*?將圖像的fit屬性設置為BoxFit.contain,可確保圖像在過渡期間盡可能大,
?*?而不會更改其縱橫比。
?*/
import?'package:flutter/material.dart';
import?'package:flutter/scheduler.dart'?show?timeDilation;

class?SourceHeroPage?extends?StatelessWidget?{
??Widget?build(BuildContext?context)?{
????timeDilation?=?5.0;?//?1.0?means?normal?animation?speed.

????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('Basic?Hero?Animation'),
??????),
??????body:?Center(
????????child:?PhotoHero(
??????????photo:?'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
??????????width:?300.0,
??????????onTap:?()?{
????????????Navigator.of(context).push(MaterialPageRoute<Null>(
????????????????builder:?(BuildContext?context)?=>?DestinationHeroPage()));
??????????},
????????),
??????),
????);
??}
}

class?DestinationHeroPage?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('Flippers?Page'),
??????),
??????body:?Container(
????????//?The?blue?background?emphasizes?that?it's?a?new?route.
????????color:?Colors.lightBlueAccent,
????????padding:?const?EdgeInsets.all(16.0),
????????alignment:?Alignment.topLeft,
????????child:?PhotoHero(
??????????photo:?'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
??????????width:?100.0,
??????????onTap:?()?{
????????????Navigator.of(context).pop();
??????????},
????????),
??????),
????);
??}
}

class?PhotoHero?extends?StatelessWidget?{
??const?PhotoHero({Key?key,?this.photo,?this.onTap,?this.width})
??????:?super(key:?key);

??final?String?photo;
??final?VoidCallback?onTap;
??final?double?width;

??Widget?build(BuildContext?context)?{
????return?SizedBox(
??????width:?width,
??????child:?Hero(
????????tag:?photo,
????????child:?Material(
??????????color:?Colors.transparent,
??????????child:?InkWell(
????????????onTap:?onTap,
????????????child:?Image.network(
??????????????photo,
??????????????fit:?BoxFit.contain,
????????????),
??????????),
????????),
??????),
????);
??}
}

2.
/**
?*?當HeroAnimation作為app的home屬性提供時,
?*?MaterialApp會隱式推送起始路徑。
?*?InkWell包裝圖像,使得向源和目標英雄添加輕擊手勢變得非常簡單。
?*?使用透明顏色定義“材質”窗口小部件可使圖像在飛往目標時“彈出”背景。
?*?SizedBox指定動畫開始和結束時英雄的大小。
?*?將圖像的fit屬性設置為BoxFit.contain,可確保圖像在過渡期間盡可能大,
?*?而不會更改其縱橫比。
?*/
import?'package:flutter/material.dart';
import?'package:flutter/scheduler.dart'?show?timeDilation;

class?SourceHeroPage?extends?StatelessWidget?{
??Widget?build(BuildContext?context)?{
????timeDilation?=?5.0;?//?1.0?means?normal?animation?speed.

????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('Basic?Hero?Animation'),
??????),
??????body:?Center(
????????child:?PhotoHero(
??????????photo:?'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
??????????width:?300.0,
??????????onTap:?()?{
????????????Navigator.of(context).push(MaterialPageRoute<Null>(
????????????????builder:?(BuildContext?context)?=>?DestinationHeroPage()));
??????????},
????????),
??????),
????);
??}
}

class?DestinationHeroPage?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('Flippers?Page'),
??????),
??????body:?Container(
????????//?The?blue?background?emphasizes?that?it's?a?new?route.
????????color:?Colors.lightBlueAccent,
????????padding:?const?EdgeInsets.all(16.0),
????????alignment:?Alignment.topLeft,
????????child:?PhotoHero(
??????????photo:?'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
??????????width:?100.0,
??????????onTap:?()?{
????????????Navigator.of(context).pop();
??????????},
????????),
??????),
????);
??}
}

class?PhotoHero?extends?StatelessWidget?{
??const?PhotoHero({Key?key,?this.photo,?this.onTap,?this.width})
??????:?super(key:?key);

??final?String?photo;
??final?VoidCallback?onTap;
??final?double?width;

??Widget?build(BuildContext?context)?{
????return?SizedBox(
??????width:?width,
??????child:?Hero(
????????tag:?photo,
????????child:?Material(
??????????color:?Colors.transparent,
??????????child:?InkWell(
????????????onTap:?onTap,
????????????child:?Image.network(
??????????????photo,
??????????????fit:?BoxFit.contain,
????????????),
??????????),
????????),
??????),
????);
??}
}

????18.intro_views(這是目前找到的一個不錯的標準歡迎頁模板,提供大家參考):https://github.com/geeklx/flutter_app2/tree/master/app2/intro_views

Flutter第八期 - 控件總結篇??Flutter第八期 - 控件總結篇

1.
import?'package:flutter/material.dart';
import?'package:intro_views_flutter/Models/page_view_model.dart';
import?'package:intro_views_flutter/intro_views_flutter.dart';

import?'home_page.dart';

class?IntroViewDemo?extends?StatelessWidget?{
??//making?list?of?pages?needed?to?pass?in?IntroViewsFlutter?constructor.
??final?pages?=?[
????new?PageViewModel(
????????pageColor:?const?Color(0xFF03A9F4),
????????iconImageAssetPath:?'assets/air-hostess.png',
????????iconColor:?null,
????????bubbleBackgroundColor:?null,
????????body:?Text(
??????????'Haselfree??booking??of??flight??tickets??with??full??refund??on??cancelation',
????????),
????????title:?Text(
??????????'Flights',
????????),
????????textStyle:?TextStyle(fontFamily:?'MyFont',?color:?Colors.white),
????????mainImage:?Image.asset(
??????????'assets/airplane.png',
??????????height:?285.0,
??????????width:?285.0,
??????????alignment:?Alignment.center,
????????)),
????new?PageViewModel(
??????pageColor:?const?Color(0xFF8BC34A),
??????iconImageAssetPath:?'assets/waiter.png',
??????iconColor:?null,
??????bubbleBackgroundColor:?null,
??????body:?Text(
????????'We??work??for??the??comfort?,??enjoy??your??stay??at??our??beautiful??hotels',
??????),
??????title:?Text('Hotels'),
??????mainImage:?Image.asset(
????????'assets/hotel.png',
????????height:?285.0,
????????width:?285.0,
????????alignment:?Alignment.center,
??????),
??????textStyle:?TextStyle(fontFamily:?'MyFont',?color:?Colors.white),
????),
????new?PageViewModel(
??????pageColor:?const?Color(0xFF607D8B),
??????iconImageAssetPath:?'assets/taxi-driver.png',
??????iconColor:?null,
??????bubbleBackgroundColor:?null,
??????body:?Text(
????????'Easy??cab??booking??at??your??doorstep??with??cashless??payment??system',
??????),
??????title:?Text('Cabs'),
??????mainImage:?Image.asset(
????????'assets/taxi.png',
????????height:?285.0,
????????width:?285.0,
????????alignment:?Alignment.center,
??????),
??????textStyle:?TextStyle(fontFamily:?'MyFont',?color:?Colors.white),
????),
??];

??@override
??Widget?build(BuildContext?context)?{
????return?new?MaterialApp(
??????debugShowCheckedModeBanner:?false,
??????title:?'IntroViews?Flutter',?//title?of?app
??????theme:?new?ThemeData(
????????primarySwatch:?Colors.blue,
??????),?//ThemeData
??????home:?new?Builder(
????????builder:?(context)?=>?new?IntroViewsFlutter(
??????????????pages,
??????????????onTapDoneButton:?()?{
????????????????Navigator.push(
??????????????????context,
??????????????????new?MaterialPageRoute(
????????????????????builder:?(context)?=>
????????????????????????new?MyHomePage(title:?'Flutter?Demo?Home?Page'),
??????????????????),?//MaterialPageRoute
????????????????);
??????????????},
??????????????showSkipButton:
??????????????????true,?//Whether?you?want?to?show?the?skip?button?or?not.
??????????????pageButtonTextStyles:?TextStyle(
????????????????color:?Colors.white,
????????????????fontSize:?18.0,
??????????????),
????????????),?//IntroViewsFlutter
??????),?//Builder
????);?//Material?App
??}
}

2.
import?'package:flutter/material.dart';

class?MyHomePage?extends?StatefulWidget?{
??MyHomePage({Key?key,?this.title})?:?super(key:?key);

??final?String?title;

??@override
??_MyHomePageState?createState()?=>?new?_MyHomePageState();
}

class?_MyHomePageState?extends?State<MyHomePage>?{
??int?_counter?=?0;

??void?_incrementCounter()?{
????setState(()?{
??????_counter++;
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?new?Scaffold(
??????appBar:?new?AppBar(
????????title:?new?Text(widget.title),
??????),
??????body:?new?Center(
????????child:?new?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????new?Text(
??????????????'You?have?pushed?the?button?this?many?times:',
????????????),
????????????new?Text(
??????????????'$_counter',
??????????????style:?Theme.of(context).textTheme.display1,
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?new?FloatingActionButton(
????????onPressed:?_incrementCounter,
????????tooltip:?'Increment',
????????child:?new?Icon(Icons.add),
??????),
????);
??}
}

????19.keep_alive_demo(類似于fragment信息保存于同一activity的意思):https://github.com/geeklx/flutter_app2/tree/master/app2/keep_alive_demo

Flutter第八期 - 控件總結篇

1.
import?'package:flutter/material.dart';
import?'package:keep_alive_demo/keep_alive_demo.dart';

void?main()?=>?runApp(new?MyApp());

class?MyApp?extends?StatelessWidget?{
??//?This?widget?is?the?root?of?your?application.
??@override
??Widget?build(BuildContext?context)?{
????return?new?MaterialApp(
??????title:?'Flutter?Demo',
??????theme:?new?ThemeData(
????????primarySwatch:?Colors.blue,
??????),
??????home:?KeepAliveDemo(),
????);
??}
}

class?KeepAliveDemo?extends?StatefulWidget?{
??@override
??_KeepAliveDemoState?createState()?=>?_KeepAliveDemoState();
}

class?_KeepAliveDemoState?extends?State<KeepAliveDemo>
????with?SingleTickerProviderStateMixin?{
??TabController?_controller;
??final?_bottomNavigationColor?=?Colors.blue;
??int?_currentIndex?=?0;

??@override
??void?initState()?{
????//?TODO:?implement?initState
????super.initState();
????_controller?=?TabController(length:?3,?vsync:?this);
??}

??@override
??void?dispose()?{
????_controller.dispose();
????super.dispose();
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????bottom:?TabBar(
??????????controller:?_controller,
??????????tabs:?[
????????????Tab(icon:?Icon(Icons.directions_car)),
????????????Tab(icon:?Icon(Icons.directions_transit)),
????????????Tab(icon:?Icon(Icons.directions_bike)),
??????????],
????????),
????????title:?Text('Keep?Alive?Demo'),
??????),
??????body:?TabBarView(
????????controller:?_controller,
????????children:?[
??????????MyHomePage(
????????????title:?'Keep?Alive?demo',
??????????),
??????????MyHomePage(
????????????title:?'Keep?Alive?demo',
??????????),
??????????MyHomePage(
????????????title:?'Keep?Alive?demo',
??????????),
????????],
??????),
??????bottomNavigationBar:?BottomNavigationBar(
????????items:?[
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.home,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'HOME',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.email,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'Email',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.pages,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'PAGES',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
??????????BottomNavigationBarItem(
??????????????icon:?Icon(
????????????????Icons.airplay,
????????????????color:?_bottomNavigationColor,
??????????????),
??????????????title:?Text(
????????????????'AIRPLAY',
????????????????style:?TextStyle(color:?_bottomNavigationColor),
??????????????)),
????????],
????????currentIndex:?_currentIndex,
????????onTap:?(int?index)?{
??????????setState(()?{
????????????_currentIndex?=?index;
??????????});
????????},
??????),
????);
??}
}

2.
import?'package:flutter/material.dart';
/**
?*?實現原理,使用AutomaticKeepAliveClientMixin,并重寫wantKeepAlive方法,讓狀態不被回收掉。
?*/

class?MyHomePage?extends?StatefulWidget?{
??MyHomePage({Key?key,?this.title})?:?super(key:?key);
??final?String?title;

??@override
??_MyHomePageState?createState()?=>?new?_MyHomePageState();
}

class?_MyHomePageState?extends?State<MyHomePage>?with?AutomaticKeepAliveClientMixin{
??int?_counter?=?0;

??//?TODO:?implement?wantKeepAlive
??@override
??bool?get?wantKeepAlive?=>?true;

??void?_incrementCounter()?{
????setState(()?{
??????_counter++;
????});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?new?Scaffold(
??????body:?new?Center(
????????child:?new?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????new?Text(
??????????????'You?have?pushed?the?button?this?many?times:',
????????????),
????????????new?Text(
??????????????'$_counter',
??????????????style:?Theme.of(context).textTheme.display1,
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?new?FloatingActionButton(
????????onPressed:?_incrementCounter,
????????tooltip:?'Increment',
????????child:?new?Icon(Icons.add),
??????),
????);
??}


}

????20.load_multi_image(圖片多選上傳,目前的問題是列表展示是小圖 看不清 正在想解決方案):https://github.com/geeklx/flutter_app2/tree/master/app2/load_multi_image

Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

import?'dart:async';

import?'package:flutter/material.dart';
import?'package:flutter/services.dart';
import?'package:multi_image_picker/asset.dart';
import?'package:multi_image_picker/multi_image_picker.dart';

class?LoadImageDemo?extends?StatefulWidget?{
??@override
??_LoadImageDemoState?createState()?=>?_LoadImageDemoState();
}

class?_LoadImageDemoState?extends?State<LoadImageDemo>?{
??List<Asset>?images?=?List<Asset>();
??String?_error;

??Future<void>?loadAssets()?async?{
????setState(()?{
??????images?=?List<Asset>();
????});
????List?resultList;
????try?{
??????resultList?=?await?MultiImagePicker.pickImages(
????????maxImages:?300,
??????);
????}?on?PlatformException?catch?(e)?{
??????_error?=?e.message;
????}
????//?If?the?widget?was?removed?from?the?tree?while?the?asynchronous?platform
????//?message?was?in?flight,?we?want?to?discard?the?reply?rather?than?calling
????//?setState?to?update?our?non-existent?appearance.
????if?(!mounted)?return;

????setState(()?{
??????images?=?resultList;
??????if?(_error?==?null)?_error?=?'No?Error?Dectected';
????});
??}

??Widget?builtImage(Asset?asset)?{
????if?(asset.thumbData?!=?null)?{
??????return?Image.memory(
????????asset.thumbData.buffer.asUint8List(),
????????fit:?BoxFit.cover,
????????gaplessPlayback:?true,
??????);
????}
????return?Container();
??}

??void?_loadImage(Asset?asset)?async?{
????await?asset.requestThumbnail(300,?300);
//????await?asset.releaseThumb();
????setState(()?{});
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('LoadImageDemo'),
??????),
??????body:?ListView.builder(
??????????itemCount:?images.length,
??????????itemBuilder:?(context,?index)?{
????????????_loadImage(images[index]);
????????????return?builtImage(images[index]);
??????????}),
??????floatingActionButton:?FloatingActionButton(
????????onPressed:?loadAssets,
????????child:?Icon(Icons.image),
??????),
????);
??}
}

????21.overlay(overlay組件能夠讓我們在當前頁面上層覆蓋一層新的組件):https://github.com/geeklx/flutter_app2/tree/master/app2/overlay

/**
?*?請切換import中的注釋分別查看
?*/
import?'package:flutter/material.dart';
//import?'overlay_demo.dart';
//import?'overlay_demo2.dart';
import?'overlay_demo3.dart';

void?main()?=>?runApp(new?MyApp());

class?MyApp?extends?StatelessWidget?{
??//?This?widget?is?the?root?of?your?application.
??@override
??Widget?build(BuildContext?context)?{
????return?new?MaterialApp(
??????title:?'Flutter?Demo',
??????theme:?new?ThemeData(
????????primarySwatch:?Colors.blue,
??????),
??????home:?OverlayDemo(),
????);
??}
}

????22.pinch_zoom_image_demo(很不錯的第三方圖片加載有緩存機制):https://github.com/geeklx/flutter_app2/tree/master/app2/pinch_zoom_image_demo

Flutter第八期 - 控件總結篇

import?'package:flutter/material.dart';
import?'package:pinch_zoom_image/pinch_zoom_image.dart';
import?'package:cached_network_image/cached_network_image.dart';

class?PinchZoomImageDemo?extends?StatelessWidget?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('Pinch?Zoom?Image?Demo'),
??????),
??????body:?ListView(
????????children:?<Widget>[
??????????PinchZoomImage(
????????????image:?Image.network('https://s2.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg'),
????????????zoomedBackgroundColor:?Color.fromRGBO(240,?240,?240,?1.0),
??????????),
??????????PinchZoomImage(
????????????image:?Image(
??????????????image:
??????????????????CachedNetworkImageProvider(
??????????????????????'https://s2.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg',
??????????????????),
????????????),
????????????zoomedBackgroundColor:?Color.fromRGBO(240,?240,?240,?1.0),
??????????),
????????],
??????),
????);
??}
}

????23.pull_on_loading(下拉刷新 很標準的寫法):https://github.com/geeklx/flutter_app2/tree/master/app2/pull_on_loading

Flutter第八期 - 控件總結篇

????24.redux_demo(頁面傳值標準框架用法舉例demo 很不錯):https://github.com/geeklx/flutter_app2/tree/master/app2/redux_demo

Flutter第八期 - 控件總結篇?Flutter第八期 - 控件總結篇

1.
import?'package:meta/meta.dart';

/**
?*?State中所有屬性都應該是只讀的
?*/
@immutable
class?CountState?{
??final?int?_count;
??get?count?=>?_count;

??CountState(this._count);

??CountState.initState()?:?_count?=?0;
}

/**
?*?定義操作該State的全部Action
?*?這里只有增加count一個動作
?*/
enum?Action?{?increment?}

/**
?*?reducer會根據傳進來的action生成新的CountState
?*/
CountState?reducer(CountState?state,?action)?{
??//匹配Action
??if?(action?==?Action.increment)?{
????return?CountState(state.count?+?1);
??}
??return?state;
}

2.
import?'package:flutter/material.dart';
import?'package:redux_demo/under_screen.dart';
import?'package:flutter_redux/flutter_redux.dart';
import?'package:redux_demo/states/count_state.dart';

class?TopScreen?extends?StatefulWidget?{
??@override
??_TopScreenState?createState()?=>?_TopScreenState();
}

class?_TopScreenState?extends?State<TopScreen>?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('Top?Screen'),
??????),
??????body:?Center(
????????child:?StoreConnector<CountState,int>(
??????????converter:?(store)?=>?store.state.count,
??????????builder:?(context,?count)?{
????????????return?Text(
??????????????count.toString(),
??????????????style:?Theme.of(context).textTheme.display1,
????????????);
??????????},
????????),
??????),
??????floatingActionButton:?FloatingActionButton(
????????onPressed:?()?{
??????????Navigator.of(context).push(MaterialPageRoute(builder:?(BuildContext?context){
????????????return?UnderScreen();
??????????}));
????????},
????????child:?Icon(Icons.forward),
??????),
????);
??}
}

3.
import?'package:flutter/material.dart';
import?'package:flutter_redux/flutter_redux.dart';
import?'package:redux_demo/states/count_state.dart';

class?UnderScreen?extends?StatefulWidget?{
??@override
??_UnderScreenState?createState()?=>?_UnderScreenState();
}

class?_UnderScreenState?extends?State<UnderScreen>?{
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?Text('Under?Screen'),
??????),
??????body:?Center(
????????child:?new?Column(
??????????mainAxisAlignment:?MainAxisAlignment.center,
??????????children:?<Widget>[
????????????new?Text(
??????????????'You?have?pushed?the?button?this?many?times:',
????????????),
????????????StoreConnector<CountState,int>(
??????????????converter:?(store)?=>?store.state.count,
??????????????builder:?(context,?count)?{
????????????????return?Text(
??????????????????count.toString(),
??????????????????style:?Theme.of(context).textTheme.display1,
????????????????);
??????????????},
????????????),
??????????],
????????),
??????),
??????floatingActionButton:?StoreConnector<CountState,VoidCallback>(

????????converter:?(store)?{
??????????return?()?=>?store.dispatch(Action.increment);
????????},
????????builder:?(context,?callback)?{
??????????return?FloatingActionButton(
????????????onPressed:?callback,
????????????child:?Icon(Icons.add),
??????????);
????????},
??????),
????);
??}
}

? ? 未完待續...




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

敦煌市| 北京市| 将乐县| 建德市| 黔南| 武城县| 黄骅市| 岳阳市| 玛沁县| 南投县| 格尔木市| 台东市| 娱乐| 天等县| 兴义市| 井研县| 德惠市| 佛山市| 射洪县| 行唐县| 达拉特旗| 革吉县| 柏乡县| 莆田市| 兴安县| 苍溪县| 青川县| 遵义县| 长武县| 迭部县| 岗巴县| 海原县| 务川| 简阳市| 武汉市| 驻马店市| 临江市| 庆城县| 江西省| 临夏市| 辉县市|