一区二区三区欧美日韩-一区二区三区欧美-一区二区三区免费在线视频-一区二区三区免费在线观看-久久精品店-久久精品第一页

歡迎您光臨深圳塔燈網絡科技有限公司!
電話圖標 余先生:13699882642

網站百科

為您解碼網站建設的點點滴滴

Flutter擼一個加載動畫

發表日期:2018-12 文章編輯:小燈 瀏覽次數:2779

Flutter正式版出了,做為一個Android開發,是時候跟隨大部隊進坑了。在寫一個登錄頁面的時候登錄是寫完了,突然發現不知道怎么搞一個加載中的動畫效果,畢竟Android中有ProgressDialog可用,然而Flutter中不知道用啥,那就自己寫一個出來。

項目地址

目標

先上效果圖:


目標.gif

是不是感覺跟ProgressDialog創建出來的一毛一樣!!!

實現思路

使用對話框

首先想到的是用Flutter自帶的SimpleDialog對話框,但是想到這玩意貌似要主動點擊按鈕關閉,這種方案不符合自己的要求。

根據情況返回不同布局

在加載的時候返回加載的布局,不加載的時候返回登陸頁面布局,代碼如下:

import 'package:flutter/material.dart'; import 'package:flutter_loading/Toast.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( primarySwatch: Colors.blue, ), home: MyHomePage(title: '加載動畫'), ); } }class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);final String title;@override _MyHomePageState createState() => _MyHomePageState(); }class _MyHomePageState extends State<MyHomePage> { bool _loading = false;@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: _childLayout(), ); }Widget _childLayout() { if (_loading) { return Center( child: Container( child: CircularProgressIndicator(), ), ); } else { return Center( child: RaisedButton( onPressed: () => _onRefresh(), child: Text('顯示加載動畫'), ), ); } }Future<Null> _onRefresh() async { setState(() { _loading = !_loading; }); await Future.delayed(Duration(seconds: 3), () { setState(() { _loading = !_loading; Toast.show(context, "加載完成"); }); }); } }

重點在_childLayout()方法,當加載中的時候返回環形進度條,加載完成,返回實際顯示的布局,代碼效果如下:

GIF0.gif

看效果是好像實現,但是這種效果只適合普通數據列表頁面的加載,要是登陸頁面,你總不能這么搞吧,一點登錄,頁面布局都跑路了,只有一個圈圈有啥意思。這種方法也不行。

使用Stack層疊布局

在原本布局上面疊加一層半透明背景,顯示一個進度條。這個想法好像可以。重點來了開始擼一波
層疊布局至少有兩個控件,按照Flutter思想,一切皆控件。我們自定義一個控件叫ProgressDialog,我們這個控件接收兩個必傳參數:子布局child,是否顯示加載進度:loading,這兩個參數是必須的,所以自定義控件如下

import 'package:flutter/material.dart';class ProgressDialog extends StatelessWidget { final bool loading; final Widget child;ProgressDialog({Key key, @required this.loading, @required this.child}) : assert(child != null), assert(loading != null), super(key: key);@override Widget build(BuildContext context) { return null; } } 

構造函數寫好了,那么開始寫控件,Stack層疊布局必須返回兩個以上的控件,所以先定義一個List<Widget>,用來放層疊的控件組,首先要把child控件加進去,再加一個加載中的動畫。上代碼:

import 'package:flutter/material.dart';class ProgressDialog extends StatelessWidget { final bool loading; final Widget child;ProgressDialog({Key key, @required this.loading, @required this.child}) : assert(child != null), assert(loading != null), super(key: key);@override Widget build(BuildContext context) { List<Widget> widgetList = []; widgetList.add(child); //如果正在加載,則顯示加載添加加載中布局 if (loading) { widgetList.add(Center( child: CircularProgressIndicator(), )); } return Stack( children: widgetList, ); } } 

是不是感覺好像很簡單的樣子,慣例上圖:

加載中1

看圖效果好像很接近了,起碼原先的布局沒有被直接替換,但是感覺不美觀,好吧加個透明背景效果,這里就用到控件Opacity,專門用來繪制透明效果。 上代碼:

import 'package:flutter/material.dart';class ProgressDialog extends StatelessWidget { final bool loading; final Widget child;ProgressDialog({Key key, @required this.loading, @required this.child}) : assert(child != null), assert(loading != null), super(key: key);@override Widget build(BuildContext context) { List<Widget> widgetList = []; widgetList.add(child); //如果正在加載,則顯示加載添加加載中布局 if (loading) { //增加一層黑色背景透明度為0.8 widgetList.add( Opacity( opacity: 0.8, child: ModalBarrier( color: Colors.black87, )), ); //環形進度條 widgetList.add(Center( child: CircularProgressIndicator(), )); } return Stack( children: widgetList, ); } } 

老規矩,上圖:


增加透明度.gif

看著樣子是不是差不多,一般進度都可以用了吧,但是如果我要想在進度條下方顯示文字怎么辦?并且我看那個toast樣子蠻好看的,還想要搞成那樣的。好吧,那樣的話加載進度條和提示內容得是同一層,用個垂直布局顯示一個進度一個Text()應該能搞定:

import 'package:flutter/material.dart';class ProgressDialog extends StatelessWidget { final bool loading; final Widget child;ProgressDialog({Key key, @required this.loading, @required this.child}) : assert(child != null), assert(loading != null), super(key: key);@override Widget build(BuildContext context) { List<Widget> widgetList = []; widgetList.add(child); //如果正在加載,則顯示加載添加加載中布局 if (loading) { //增加一層黑色背景透明度為0.8 widgetList.add( Opacity( opacity: 0.8, child: ModalBarrier( color: Colors.black87, )), ); //環形進度條 widgetList.add(Center( child: Container( padding: const EdgeInsets.all(20.0), decoration: BoxDecoration( //黑色背景 color: Colors.black87, //圓角邊框 borderRadius: BorderRadius.circular(10.0)), child: Column( //控件里面內容主軸負軸劇中顯示 mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, //主軸高度最小 mainAxisSize: MainAxisSize.min, children: <Widget>[ CircularProgressIndicator(), Text( '加載中...', style: TextStyle(color: Colors.white), ) ], ), ), )); } return Stack( children: widgetList, ); } } 

用一個垂直布局Column包裹進度條和提示內容,完美解決,已經接近目標了,圖來-->

增加提醒內容.gif

目標完成,最后潤色:提示字體要讓用戶自定義,加載動畫也得可以自定義,那么最終代碼如下:

import 'package:flutter/material.dart';class ProgressDialog extends StatelessWidget { //子布局 final Widget child;//加載中是否顯示 final bool loading;//進度提醒內容 final String msg;//加載中動畫 final Widget progress;//背景透明度 final double alpha;//字體顏色 final Color textColor;ProgressDialog( {Key key, @required this.loading, this.msg, this.progress = const CircularProgressIndicator(), this.alpha = 0.6, this.textColor = Colors.white, @required this.child}) : assert(child != null), assert(loading != null), super(key: key);@override Widget build(BuildContext context) { List<Widget> widgetList = []; widgetList.add(child); if (loading) { Widget layoutProgress; if (msg == null) { layoutProgress = Center( child: progress, ); } else { layoutProgress = Center( child: Container( padding: const EdgeInsets.all(20.0), decoration: BoxDecoration( color: Colors.black87, borderRadius: BorderRadius.circular(4.0)), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: <Widget>[ progress, Container( padding: const EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0), child: Text( msg, style: TextStyle(color: textColor, fontSize: 16.0), ), ) ], ), ), ); } widgetList.add(Opacity( opacity: alpha, child: new ModalBarrier(color: Colors.black87), )); widgetList.add(layoutProgress); } return Stack( children: widgetList, ); } } 

最后附上在工程中調用的例子代碼:

import 'package:flutter/material.dart'; import 'package:flutter_loading/Toast.dart'; import 'package:flutter_loading/view_loading.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( primarySwatch: Colors.blue, ), home: MyHomePage(title: '加載動畫'), ); } }class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);final String title;@override _MyHomePageState createState() => _MyHomePageState(); }class _MyHomePageState extends State<MyHomePage> { bool _loading = false;@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: ProgressDialog( loading: _loading, msg: '正在加載...', child: Center( child: RaisedButton( onPressed: () => _onRefresh(), child: Text('顯示加載動畫'), ), ), ), ); }Future<Null> _onRefresh() async { setState(() { _loading = !_loading; }); await Future.delayed(Duration(seconds: 3), () { setState(() { _loading = !_loading; Toast.show(context, "加載完成"); }); }); } }

對于加載動畫,只要把progress屬性改為自定義的屬性即可,比如這位大佬寫的加載動畫:
flutter自定義進度動畫,我們用他的加載中動畫:
只需在上述代碼中加一行(當然前提是你得去github上git到他自定義的代碼):

loading: _loading, //自定義動畫 progress: MyProgress(size: new Size(100.0, 20.0),color: Colors.white,), msg: '正在加載...', 

效果如下:

自定義動畫.gif
  • 參考項目:
    https://github.com/While1true/flutter_refresh
    https://pub.dartlang.org/packages/modal_progress_hud

本頁內容由塔燈網絡科技有限公司通過網絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網頁中由涉嫌抄襲的內容,請及時與我們聯系,并提供相關證據,工作人員會在5工作日內聯系您,一經查實,本站立刻刪除侵權內容。本文鏈接:http://www.junxiaosheng.cn/17646.html
相關APP開發
 八年  行業經驗

多一份參考,總有益處

聯系深圳網站公司塔燈網絡,免費獲得網站建設方案及報價

咨詢相關問題或預約面談,可以通過以下方式與我們聯系

業務熱線:余經理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

主站蜘蛛池模板: 一区二区三区四区国产| 在线不卡日本v二区| WWW国产精品人妻一二三区| 亚洲人日本人jlzzy| 久草色视频| 在线va无卡无码高清| 恋夜秀场1234手机视频在线观看| 亚洲午夜精品A片久久软件| 久久全国免费观看视频| 最近高清日本免费| 日本高清天码一区在线播放| 制服国产欧美亚洲日韩| 牛牛在线精品视频(正)| 办公室韩国电影免费完整版| 特大黑人娇小亚洲女mp4| 国产久爱青草视频在线观看| 亚洲视频一区在线| 蜜柚免费视频高清观看在线| 超碰在线视频人人AV| 亚洲 欧美 国产 综合 在线| 久久精品国产免费播高清无卡| 中文字幕人成人乱码亚洲影视| 欧美18videosex| 国产精品亚洲AV毛片一区二区三区| 亚洲精品国产国语| 男女XX00上下抽搐动态图| 国产精品青青在线麻豆| 在线视频中文字幕| 天美麻豆成人AV精品| 乱码国产丰满人妻WWW| 国产AV国片精品无套内谢无码 | 好男人视频免费高清在线观看www| 亚洲蜜芽在线观看精品一区| 男人被绑着强行摸j| 狠狠色欧美亚洲狠狠色www| 草莓视频在线观看免费观看高清| 亚洲欧美免费无码专区| 欧美成人中文字幕在线视频| 国产又粗又黄又爽的大片| 99免费视频观看| 中国女人内谢69XXXXXA片|