欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Flutter制作一個會飛的菜單

 更新時間:2023年06月06日 14:03:36   作者:程序那些事  
flutter中自帶了drawer組件,可以實(shí)現(xiàn)通用的菜單功能,所以本文將嘗試一下通過自定義動畫來實(shí)現(xiàn)一個會飛的菜單,感興趣的可以了解一下

簡介

flutter中自帶了drawer組件,可以實(shí)現(xiàn)通用的菜單功能,那么有沒有一種可能,我們可以通過自定義動畫來實(shí)現(xiàn)一個別樣的菜單呢?

答案是肯定的,一起來看看吧。

定義一個菜單項(xiàng)目

因?yàn)檫@里的主要目的是實(shí)現(xiàn)菜單的動畫,所以這里的菜單比較簡單,我們的menu是一個StatefulWidget,里面就是一個Column組件,column中有四行詩:

  static const _menuTitles = [
    '遲日江山麗',
    '春風(fēng)花草香',
    '泥融飛燕子',
    '沙暖睡鴛鴦',
  ];
    Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child:_buildContent()
    );
  }
  Widget _buildContent() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 16),
        ..._buildListItems()
      ],
    );
  }
  List<Widget> _buildListItems() {
    final listItems = <Widget>[];
    for (var i = 0; i < _menuTitles.length; ++i) {
      listItems.add(
         Padding(
            padding: const EdgeInsets.symmetric(horizontal: 36.0, vertical: 16),
            child: Text(
              _menuTitles[i],
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.w500,
              ),
            ),
      )
      );
    }
    return listItems;
  }

讓menu動起來

怎么讓menu動起來呢?我們需要給最外層的AnimateMenuApp添加一個AnimationController,所以需要在_AnimateMenuAppState添加SingleTickerProviderStateMixin的mixin,如下所示:

class _AnimateMenuAppState extends State<AnimateMenuApp>
    with SingleTickerProviderStateMixin {
  late AnimationController _drawerSlideController;

然后在initState中對_drawerSlideController進(jìn)行初始化:

  void initState() {
    super.initState();
    _drawerSlideController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 150),
    );
  }

在讓menu動起來之前,我們需要設(shè)計(jì)一下動畫的樣式。假如我們的動畫是讓menu從右向左飛出。那么我們可以使用FractionalTranslation來進(jìn)行offset進(jìn)行位置變換。

并且當(dāng)菜單沒有開啟的時候,我們需要顯示一個空的組件,這里用SizedBox來替代。

當(dāng)菜單開啟的時候,就執(zhí)行這個FractionalTranslation的動畫,所以我們的build方法需要這樣寫:

  Widget _buildDrawer() {
    return AnimatedBuilder(
      animation: _drawerSlideController,
      builder: (context, child) {
        return FractionalTranslation(
          translation: Offset(1.0 - _drawerSlideController.value, 0.0),
          child: _isDrawerClosed() ? const SizedBox() : const Menu(),
        );
      },
    );
  }

FractionalTranslation中的Offset是根據(jù)_drawerSlideController的value來進(jìn)行變化的。

那么_drawerSlideController的value怎么變化呢?

我們定義一個_toggleDrawer方法,在點(diǎn)擊菜單按鈕的時候來觸發(fā)這個方法,從而實(shí)現(xiàn)_drawerSlideController的value變化:

  void _toggleDrawer() {
    if (_isDrawerOpen() || _isDrawerOpening()) {
      _drawerSlideController.reverse();
    } else {
      _drawerSlideController.forward();
    }
  }

同時,我們定義下面幾個判斷菜單狀態(tài)的方法:

  bool _isDrawerOpen() {
    return _drawerSlideController.value == 1.0;
  }
  bool _isDrawerOpening() {
    return _drawerSlideController.status == AnimationStatus.forward;
  }
  bool _isDrawerClosed() {
    return _drawerSlideController.value == 0.0;
  }

因?yàn)椴藛螆D標(biāo)需要根據(jù)菜單狀態(tài)來發(fā)生改變,菜單的狀態(tài)又是依賴于_drawerSlideController,所以,我們把IconButton放到一個AnimatedBuilder里面,從而實(shí)現(xiàn)動態(tài)變化的效果:

  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      title: const Text(
        '動畫菜單',
        style: TextStyle(
          color: Colors.black,
        ),
      ),
      backgroundColor: Colors.transparent,
      elevation: 0.0,
      automaticallyImplyLeading: false,
      actions: [
        AnimatedBuilder(
          animation: _drawerSlideController,
          builder: (context, child) {
            return IconButton(
              onPressed: _toggleDrawer,
              icon: _isDrawerOpen() || _isDrawerOpening()
                  ? const Icon(
                Icons.clear,
                color: Colors.black,
              )
                  : const Icon(
                Icons.menu,
                color: Colors.black,
              ),
            );
          },
        ),
      ],
    );
  }

最后實(shí)現(xiàn)的效果如下:

添加菜單內(nèi)部的動畫

上面的例子中整個菜單是作為一個整體來動畫的,有沒有可能菜單里面的每一個item也有自己的動畫呢?

答案當(dāng)然是肯定的。

我們只需要在上面的基礎(chǔ)上將menu組件添加動畫支持即可:

class _MenuState extends State<Menu> with SingleTickerProviderStateMixin

動畫中的位移我們選擇使用Transform.translate,同時還添加了淡入淡出的效果,也就是把上面例子中的Padding用AnimatedBuilder包裹起來,如下所示:

  List<Widget> _buildListItems() {
    final listItems = <Widget>[];
    for (var i = 0; i < _menuTitles.length; ++i) {
      listItems.add(
        AnimatedBuilder(
          animation: _itemController,
          builder: (context, child) {
            final animationPercent = Curves.easeOut.transform(
              _itemSlideIntervals[i].transform(_itemController.value),
            );
            final opacity = animationPercent;
            final slideDistance = (1.0 - animationPercent) * 150;
            return Opacity(
              opacity: opacity,
              child: Transform.translate(
                offset: Offset(slideDistance, 0),
                child: child,
              ),
            );
          },
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 36.0, vertical: 16),
            child: Text(
              _menuTitles[i],
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
        ),
      );
    }
    return listItems;
  }

AnimatedBuilder中的builder返回的是一個Opacity對象,里面包含了opacity和child兩個屬性。其中最終要的一個變化值是animationPercent,這個值是根據(jù)_itemController的value和初始設(shè)置的各個item的變化時間來決定的。

每個item的值是不一樣的:

  void _createAnimationIntervals() {
    for (var i = 0; i < _menuTitles.length; ++i) {
      final startTime = _initialDelayTime + (_staggerTime * i);
      final endTime = startTime + _itemSlideTime;
      _itemSlideIntervals.add(
        Interval(
          startTime.inMilliseconds / _animationDuration.inMilliseconds,
          endTime.inMilliseconds / _animationDuration.inMilliseconds,
        ),
      );
    }
  }

最后運(yùn)行結(jié)果如下:

總結(jié)

在flutter中一切皆可動畫,我們只需要掌握動畫創(chuàng)作的訣竅即可。

本文的例子:https://github.com/ddean2009/learn-flutter.git

到此這篇關(guān)于利用Flutter制作一個會飛的菜單的文章就介紹到這了,更多相關(guān)Flutter菜單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android中ListView綁定CheckBox實(shí)現(xiàn)全選增加和刪除功能(DEMO)

    Android中ListView綁定CheckBox實(shí)現(xiàn)全選增加和刪除功能(DEMO)

    本文通過實(shí)例給大家講解了Android中ListView綁定CheckBox實(shí)現(xiàn)全選增加和刪除功能(DEMO)的代碼,對android checkbox全選相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-08-08
  • Android代碼混淆的寫法總結(jié)

    Android代碼混淆的寫法總結(jié)

    本篇文章主要介紹了Android代碼混淆的寫法總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Android多渠道打包時獲取當(dāng)前渠道的方法

    Android多渠道打包時獲取當(dāng)前渠道的方法

    這篇文章主要介紹了Android多渠道打包時獲取當(dāng)前渠道的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Android本地視頻壓縮方案的示例代碼

    Android本地視頻壓縮方案的示例代碼

    本篇文章主要介紹了Android本地視頻壓縮方案的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Android實(shí)現(xiàn)鬧鐘功能小Dome

    Android實(shí)現(xiàn)鬧鐘功能小Dome

    本篇文章主要介紹了Android實(shí)現(xiàn)鬧鐘功能小Dome,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • Flutter 仿微信支付界面

    Flutter 仿微信支付界面

    網(wǎng)傳微信支付頁面的第三方鏈接一個格子需要廣告費(fèi)1一個億,微信支付頁非常適合做功能導(dǎo)航,本篇使用 ListView和 GridView 模仿了微信支付的頁面,同時介紹了如何裝飾一個組件的背景和邊緣樣式。
    2021-05-05
  • Android編程之代碼創(chuàng)建布局實(shí)例分析

    Android編程之代碼創(chuàng)建布局實(shí)例分析

    這篇文章主要介紹了Android編程之代碼創(chuàng)建布局的方法,結(jié)合實(shí)例形式分析了Android通過代碼創(chuàng)建布局的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Android自定義View之RadioGroup實(shí)現(xiàn)跨多行顯示

    Android自定義View之RadioGroup實(shí)現(xiàn)跨多行顯示

    這篇文章主要介紹了Android自定義View之RadioGroup實(shí)現(xiàn)跨多行顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Android超詳細(xì)講解組件LinearLayout的使用

    Android超詳細(xì)講解組件LinearLayout的使用

    LinearLayout又稱作線性布局,是一種非常常用的布局。正如它的名字所描述的一樣,這個布局會將它所包含的控件在線性方向上依次排列。既然是線性排列,肯定就不僅只有一個方向,這里一般只有兩個方向:水平方向和垂直方向
    2022-03-03
  • Flutter進(jìn)階之實(shí)現(xiàn)動畫效果(二)

    Flutter進(jìn)階之實(shí)現(xiàn)動畫效果(二)

    這篇文章主要為大家詳細(xì)介紹了Flutter進(jìn)階之實(shí)現(xiàn)動畫效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08

最新評論