您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關flutter如何實現帶刪除動畫的listview功能,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
個人開發app中,需要開發一個帶有刪除功能的ListView
效果如下
列表可以滾動用listView,
有兩個動畫,第一個動畫是透明度變化,第二個是size變化
是順序執行
新建一個動畫頁面進行單獨控制
記得用statefulwidget類,這第二個動畫之間涉及到頁面刷新切換widget
記得with tickerproviderstatemixin 這個是動畫類狀態管理的必備
class AnimationListItem extends StatefulWidget { AnimationListItem(); @override _AnimationListItemState createState() => _AnimationListItemState(); } class _AnimationListItemState extends State<AnimationListItem> with TickerProviderStateMixin { @override Widget build(BuildContext context) { // TODO: implement build return Container(); } }
聲明
//控制器 AnimationController lucencyController; AnimationController sizeController; // 動畫 Animation<double> lucencyAnimation; Animation<double> sizeAnimation;
初始化
///必須在initstate這個生命周期進行初始化 @override void initState() { // TODO: implement initState super.initState(); lucencyController = AnimationController(vsync: this, duration: Duration(milliseconds: 150)); lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate( CurvedAnimation(parent: lucencyController, curve: Curves.easeOut)); sizeController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); sizeAnimation = Tween(begin: 1.0, end: 0.0).animate( CurvedAnimation(parent: sizeController, curve: Curves.easeOut)); }
注銷
@override void dispose() { lucencyController.dispose(); sizeController.dispose(); super.dispose(); }
最后內容呈現
class AnimationListItem extends StatefulWidget { AnimationListItem(); @override _AnimationListItemState createState() => _AnimationListItemState(); } class _AnimationListItemState extends State<AnimationListItem> with TickerProviderStateMixin { AnimationController lucencyController; AnimationController sizeController; Animation<double> lucencyAnimation; Animation<double> sizeAnimation; bool isChange = false; @override void initState() { // TODO: implement initState super.initState(); lucencyController = AnimationController(vsync: this, duration: Duration(milliseconds: 150)); lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate( CurvedAnimation(parent: lucencyController, curve: Curves.easeOut)); sizeController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); sizeAnimation = Tween(begin: 1.0, end: 0.0).animate( CurvedAnimation(parent: sizeController, curve: Curves.easeOut)); } @override Widget build(BuildContext context) { return buildItemBox(); } @override void dispose() { lucencyController.dispose(); sizeController.dispose(); super.dispose(); } Widget buildItemBox() { return isChange ? SizeTransition( axis: Axis.vertical, sizeFactor: sizeAnimation, child: Container( height: duSetWidth(100), width: double.infinity, ), ) : FadeTransition( opacity: lucencyAnimation, child: Container( alignment: Alignment.center, padding: EdgeInsets.only( left: duSetWidth(15), right: duSetWidth(15), ), height: duSetWidth(100), child: buildRow(), ), ); } Widget buildRow() { ///設置顯示的樣式 bool _isSub = false; Color _isSubColor = Color.fromRGBO(245, 77, 130, 1); Color _isSubBackColor = Colors.transparent; Widget isSubWidget = InkWell( child: Container( alignment: Alignment.center, width: duSetWidth(55), height: duSetWidth(28), decoration: BoxDecoration( color: _isSubBackColor, border: Border.all(color: _isSubColor), borderRadius: BorderRadius.circular(duSetWidth(15)), ), child: Text( '+ 書架', style: TextStyle( color: _isSubColor, ), ), ), onTap: () { if (_isSub) print('dasd'); else print('dsada'); }, ); return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: duSetWidth(60), height: duSetWidth(80), child: ClipRRect( borderRadius: BorderRadius.circular(duSetWidth(5)), child: Image.network( 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2F00.minipic.eastday.com%2F20170307%2F20170307164725_114ea3c04f605e59bd10699f37870267_13.jpeg&refer=http%3A%2F%2F00.minipic.eastday.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623596389&t=946dba98698d8d67d773ea8f7af55f45', fit: BoxFit.cover, ), ), ), Container( width: duSetWidth(155), height: duSetWidth(80), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: duSetWidth(25), alignment: Alignment.centerLeft, width: double.infinity, child: Text( '這是標題', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: Colors.white, fontSize: duSetFontSize(16), ), ), ), Container( height: duSetWidth(20), alignment: Alignment.centerLeft, width: double.infinity, child: Text( '這是副標題', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: Color.fromRGBO(162, 168, 186, 1), fontSize: duSetFontSize(14), ), ), ), ], ), ), Container( width: duSetWidth(100), height: duSetWidth(80), padding: EdgeInsets.only( top: duSetWidth(4), ), alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ isSubWidget, InkWell( onTap: () async { await lucencyController.forward(); setState(() { isChange = true; sizeController.forward(); }); }, child: Container( alignment: Alignment.center, width: duSetWidth(35), height: duSetWidth(28), decoration: BoxDecoration( border: Border.all( color: Color.fromRGBO(113, 118, 140, 1), ), borderRadius: BorderRadius.circular(duSetWidth(15)), ), child: Icon( Icons.delete, color: Color.fromRGBO(113, 118, 140, 1), size: duSetFontSize(16), ), ), ), ], ), ) ], ); } }
dusetwidth是我自定義的函數可以不用管,自己替換
下列是在頁面使用
class HistoryPage extends StatefulWidget { @override _HistoryPageState createState() => _HistoryPageState(); } class _HistoryPageState extends State<HistoryPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: ListView( children: [ AnimationListItem(), AnimationListItem(), AnimationListItem(), AnimationListItem(), ], ), ); } /// 構造appbar Widget buildAppabr() { return AppBar( backgroundColor: Color.fromRGBO(33, 39, 46, 1), brightness: Brightness.dark, centerTitle: true, title: Text( '瀏覽記錄', style: TextStyle( fontSize: duSetFontSize(16), color: Colors.white, ), ), leading: IconButton( icon: Icon( Icons.arrow_back_ios, color: Colors.white, size: duSetFontSize(18), ), onPressed: () { Get.back(); }, ), ); } }
這個我原來是準備使用animatedList來進行實現的,最后發現,animatedList里面只能設置移除動畫,不能實現補位動畫
第一個透明度的動畫就是移除動畫,第二個size變化就是補位動畫,
animatedList沒有補位,所以下方list直接移動上去會顯得非常突兀,我看了看源碼,修改較為麻煩。所以就直接用動畫變換來寫
這個List內的內容,并不是直接移除,而是替換成高低為0 的一個盒子
關于“flutter如何實現帶刪除動畫的listview功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。