日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flutter实现动画卡片式Tab导航 | 掘金技术征文

發(fā)布時間:2025/4/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter实现动画卡片式Tab导航 | 掘金技术征文 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

本人接觸Flutter不到一個月,深深感受到了這個平臺的威力,于是不斷學(xué)習(xí),Flutter官方Example中的flutter_gallery,很好的展示了Flutter各個widget的功能

其中的animation內(nèi)容,展示的是一個非常漂亮的 帶有動畫和拖拽功能的 可展開的卡片式Tab導(dǎo)航,非常漂亮,但是其實現(xiàn)沒有抽象出一個可供第三方使用的Widget出來,而且其頁面內(nèi)容的定制性不夠友好,滑動的時候也有bug,我在他的基礎(chǔ)上進(jìn)行了優(yōu)化

官方展示了一個非常好的開源示例,我改造了一下,也不敢獨自享用,現(xiàn)在分享給大家,歡迎大家多多交流

外觀

實現(xiàn)

這里是我的代碼: GitHub/Realank

想使用這個控件非常簡單,首先定義頁面數(shù)據(jù):

const Color _mariner = const Color(0xFF3B5F8F); const Color _mediumPurple = const Color(0xFF8266D4); const Color _tomato = const Color(0xFFF95B57); const Color _mySin = const Color(0xFFF3A646);List<CardSection> allSections = <CardSection>[new CardSection(title: 'First Page',leftColor: _mediumPurple,rightColor: _mariner,contentWidget: Center(child: new Text('第一頁'))),new CardSection(title: 'Second Page',leftColor: _mariner,rightColor: _mySin,contentWidget: Center(child: new Text('第二頁'))),new CardSection(title: 'Third Page',leftColor: _mySin,rightColor: _tomato,contentWidget: Center(child: new Text('第三頁'))),new CardSection(title: 'Forth Page',leftColor: _tomato,rightColor: Colors.blue,contentWidget: Center(child: new Text('第四頁'))),new CardSection(title: 'Fifth Page',leftColor: Colors.blue,rightColor: _mediumPurple,contentWidget: Center(child: new Text('第五頁'))), ]; 復(fù)制代碼

然后創(chuàng)建這個控件:

void main() => runApp(new MyApp());class MyApp extends StatelessWidget {// This widget is the root of your application.@overrideWidget build(BuildContext context) {return new MaterialApp(title: 'Flutter Demo',home: new Scaffold(body: Center(child: new AnimateTabNavigation(sectionList: allSections,),),),);} } 復(fù)制代碼

大功告成

原理

知其然還要知其所以然,下面來說說這個控件的實現(xiàn)原理

首先,在sections.dart里定義了數(shù)據(jù)結(jié)構(gòu):

class CardSection {CardSection({this.title, this.leftColor, this.rightColor, this.contentWidget});final String title;final Color leftColor;final Color rightColor;final Widget contentWidget;@overridebool operator ==(Object other) {if (other is! CardSection) return false;final CardSection otherSection = other;return title == otherSection.title;}@overrideint get hashCode => title.hashCode; }復(fù)制代碼

它定義了其中一個卡片的標(biāo)題,左邊顏色和右邊顏色(為了顯示過渡顏色效果),以及子控件(這個是我改進(jìn)的,這樣可以別人使用的時候隨意添加控件)

然后在widgets.dart中定義了幾個widget:

  • SectionCard : 標(biāo)題卡片
  • SectionTitle : 標(biāo)題
  • SectionIndicator : 標(biāo)題下的裝飾線

最后在cardNavigation.dart中就是布局這些內(nèi)容啦,這里面代碼很復(fù)雜,其思路倒是不難:

  • 定義全屏展示tab的高度maxHeight,以及打開tab后,tab顯示在頂部的高度minHeight
  • 在用戶拖動tab卡片的時候,根據(jù)卡片的位置于minHeight和maxHeight的比例,計算出動畫進(jìn)度(0.0-1.0)
  • 在_AllSectionsLayout中,定義了全屏顯示tab時,卡片的columnCardRect,以及打開tab后,tab顯示在頂部時候的rowCardRectt
  • 計算出這兩個rect在動畫進(jìn)度0-1過程中的中間態(tài)的rect尺寸,賦值給每一個卡片,這樣卡片就有中間狀態(tài)的外觀了。
  • 當(dāng)用戶點擊了tab區(qū)域,就會觸發(fā)_maybeScroll方法,這個方法判斷當(dāng)前的tab是全屏的還是打開后的
  • 當(dāng)tab是全屏的,就展開對應(yīng)的tab頁
  • 當(dāng)tab已經(jīng)是打開的,就判斷點擊的位置,在tab欄的左側(cè),就往左翻頁,反之亦然。
  • 從 0 到 1:我的 Flutter 技術(shù)實踐 | 掘金技術(shù)征文,征文活動正在進(jìn)行中

    總結(jié)

    以上是生活随笔為你收集整理的Flutter实现动画卡片式Tab导航 | 掘金技术征文的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。