flutter實(shí)現(xiàn)帶刪除動(dòng)畫的listview功能
個(gè)人開(kāi)發(fā)app中,需要開(kāi)發(fā)一個(gè)帶有刪除功能的ListView
效果如下

需求動(dòng)畫分析
列表可以滾動(dòng)用listView,
有兩個(gè)動(dòng)畫,第一個(gè)動(dòng)畫是透明度變化,第二個(gè)是size變化
是順序執(zhí)行
實(shí)現(xiàn)過(guò)程
新建一個(gè)動(dòng)畫頁(yè)面進(jìn)行單獨(dú)控制
記得用statefulwidget類,這第二個(gè)動(dòng)畫之間涉及到頁(yè)面刷新切換widget
記得with tickerproviderstatemixin 這個(gè)是動(dòng)畫類狀態(tài)管理的必備
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();
}
}
動(dòng)畫流程
聲明
//控制器 AnimationController lucencyController; AnimationController sizeController; // 動(dòng)畫 Animation<double> lucencyAnimation; Animation<double> sizeAnimation;
初始化
///必須在initstate這個(gè)生命周期進(jìn)行初始化
@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();
}
最后內(nèi)容呈現(xiàn)
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() {
///設(shè)置顯示的樣式
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(
'這是標(biāo)題',
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(
'這是副標(biāo)題',
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是我自定義的函數(shù)可以不用管,自己替換
下列是在頁(yè)面使用
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(),
],
),
);
}
/// 構(gòu)造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();
},
),
);
}
}
這個(gè)我原來(lái)是準(zhǔn)備使用animatedList來(lái)進(jìn)行實(shí)現(xiàn)的,最后發(fā)現(xiàn),animatedList里面只能設(shè)置移除動(dòng)畫,不能實(shí)現(xiàn)補(bǔ)位動(dòng)畫
第一個(gè)透明度的動(dòng)畫就是移除動(dòng)畫,第二個(gè)size變化就是補(bǔ)位動(dòng)畫,
animatedList沒(méi)有補(bǔ)位,所以下方list直接移動(dòng)上去會(huì)顯得非常突兀,我看了看源碼,修改較為麻煩。所以就直接用動(dòng)畫變換來(lái)寫
這個(gè)List內(nèi)的內(nèi)容,并不是直接移除,而是替換成高低為0 的一個(gè)盒子
如果有animatedList簡(jiǎn)單的改造實(shí)現(xiàn)的補(bǔ)位動(dòng)畫,希望留言給我地址,非常感謝
到此這篇關(guān)于flutter實(shí)現(xiàn)帶刪除動(dòng)畫的listview功能的文章就介紹到這了,更多相關(guān)flutter listview刪除內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
RecyclerView實(shí)現(xiàn)流式標(biāo)簽單選多選功能
RecyclerView是Android一個(gè)更強(qiáng)大的控件,其不僅可以實(shí)現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。這篇文章主要介紹了RecyclerView實(shí)現(xiàn)的流式標(biāo)簽單選多選功能,需要的朋友可以參考下2019-11-11
Android使用ViewDragHelper實(shí)現(xiàn)圖片下拽返回示例
這篇文章主要介紹了Android使用ViewDragHelper實(shí)現(xiàn)圖片下拽返回示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
android輕松管理安卓應(yīng)用中的log日志 發(fā)布應(yīng)用時(shí)log日志全部去掉的方法
android合理的管理log日志,在開(kāi)發(fā)的時(shí)候打印出來(lái),在發(fā)布的時(shí)候,把所有的log日志全部關(guān)掉,下面就把方法給你一一道來(lái)2013-11-11
Android10.0實(shí)現(xiàn)本地音樂(lè)播放(附源碼下載)
這篇文章主要介紹了Android10.0實(shí)現(xiàn)本地音樂(lè)播放(附源碼下載),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
android notification 的總結(jié)分析
notification是一種出現(xiàn)在任務(wù)欄的提示,特別是在4.0以后notification改進(jìn)了不少,本文內(nèi)容都是基于4.0及4.1以后總結(jié)來(lái)的2013-05-05
OpenHarmony如何調(diào)用電話服務(wù)API撥打電話
OpenHarmony3.1版本標(biāo)準(zhǔn)系統(tǒng)增加了通話相關(guān)的聯(lián)系人應(yīng)用,來(lái)電應(yīng)用等,在系統(tǒng)服務(wù)層面電話相關(guān)功能也比較完善,這篇文章主要介紹了OpenHarmony如何調(diào)用電話服務(wù)API撥打電話2022-11-11

