<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    Flutter 中自定義動(dòng)畫底部導(dǎo)航欄

    共 25709字,需瀏覽 52分鐘

     ·

    2021-07-10 23:54


    在這個(gè)博客中,我們將探索Flutter中的自定義動(dòng)畫底部導(dǎo)航欄。我們將看到如何實(shí)現(xiàn)自定義動(dòng)畫底部導(dǎo)航欄的演示程序以及如何在您的 Flutter 應(yīng)用程序中使用它。

    介紹:

    顯示在應(yīng)用程序底部的Material小部件,用于在幾個(gè)視角中進(jìn)行選擇,通常在 3 到 5 范圍內(nèi)的某個(gè)位置。底部導(dǎo)航欄包含各種選項(xiàng),如文本標(biāo)簽、圖標(biāo)或兩者。它提供了應(yīng)用程序的高級(jí)視角之間的快速導(dǎo)航。對(duì)于更大的屏幕,側(cè)面導(dǎo)航可能更合適。

    這個(gè)演示視頻展示了如何在 flutter 中使用自定義的底部導(dǎo)航欄。它展示了自定義底部導(dǎo)航欄將如何在您的 Flutter 應(yīng)用程序中工作。它顯示當(dāng)用戶點(diǎn)擊底部導(dǎo)航欄圖標(biāo)時(shí),它們將被動(dòng)畫化并顯示標(biāo)簽文本。當(dāng)用戶點(diǎn)擊任何圖標(biāo)時(shí),顏色也會(huì)發(fā)生變化和動(dòng)畫。它將顯示在您的設(shè)備上。

    特性

    自定義動(dòng)畫底部導(dǎo)航欄的一些屬性是:

    • selectedIndex:這個(gè)屬性用于被選中的項(xiàng)是一個(gè)索引。更改此屬性將更改所選項(xiàng)目并為其設(shè)置動(dòng)畫。默認(rèn)為零。
    • backgroundColor:該屬性用于導(dǎo)航欄的背景顏色。如果未提供,則默認(rèn)為 Theme.bottomAppBarColor。
    • showElevation:此屬性用于此導(dǎo)航欄是否應(yīng)顯示高程。默認(rèn)為真。
    • Listitems:該屬性用于定義底部導(dǎo)航欄中顯示的按鈕的外觀。這應(yīng)該至少有兩個(gè)項(xiàng)目,最多五個(gè)。
    • onItemSelected:該屬性用于在按下項(xiàng)目時(shí)調(diào)用的回調(diào)。
    • **curve:**該屬性用于配置動(dòng)畫曲線。
    • itemCornerRadius:該屬性用于物品的角半徑,如果不設(shè)置,默認(rèn)為50。

    如何在 dart 文件中實(shí)現(xiàn)代碼

    創(chuàng)建一個(gè)新的 dart 文件*my_home_page.dart*。

    在構(gòu)建方法中,我們將返回一個(gè) scaffold()。在里面我們將添加一個(gè) appBar。在 appBar 中,我們將添加 title 和 backgroundColor。我們將添加 body 并添加到**getBody()小部件中。下面我們將深入定義代碼?,F(xiàn)在,我們將添加 bottomNavigationBar 并將其添加到_buildBottomBar()**小部件中。我們還將深入定義下面的代碼。

    return Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: Text("Custom Animated Bottom Navigation Bar"),
          backgroundColor: Colors.green[200],
        ),
        body: getBody(),
        bottomNavigationBar: _buildBottomBar()
    );

    我們將深入定義**getBody()**小部件

    首先,我們將創(chuàng)建一個(gè)整數(shù)變量 _currentIndex 等于零。

    int_currentIndex = 0;

    我們將創(chuàng)建 getBody() 小部件。在這個(gè)小部件中,我們將添加 List頁面。我們將添加四個(gè)具有不同文本的容器并返回**IndexedStack()**小部件。在小部件內(nèi)部,我們將添加索引是我的變量 _currentIndex 和 children 是列表小部件頁面。

    Widget getBody() {
      List<Widget> pages = [
        Container(
          alignment: Alignment.center,
          child: Text("Home",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
        ),
        Container(
          alignment: Alignment.center,
          child: Text("Users",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
        ),
        Container(
          alignment: Alignment.center,
          child: Text("Messages",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
        ),
        Container(
          alignment: Alignment.center,
          child: Text("Settings",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
        ),
      ];
      return IndexedStack(
        index: _currentIndex,
        children: pages,
      );
    }

    我們將創(chuàng)建一個(gè) _buildBottomBar() 小部件。在這個(gè)小部件中,我們將返回一個(gè)CustomAnimatedBottomBar()。在里面,我們將添加一個(gè)容器高度、backgroundColor、selectedIndex、變量_currentIndex、showElevation、動(dòng)畫曲線、onItemSelected和items。在 items 中, e 將添加四個(gè)BottomNavyBarItem()。在里面,我們將添加四個(gè)不同的圖標(biāo)、標(biāo)題、activeColors,并且所有的 text-align 都應(yīng)該居中。

    Widget _buildBottomBar(){
      return CustomAnimatedBottomBar(
        containerHeight: 70,
        backgroundColor: Colors.black,
        selectedIndex: _currentIndex,
        showElevation: true,
        itemCornerRadius: 24,
        curve: Curves.easeIn,
        onItemSelected: (index) => setState(() => _currentIndex = index),
        items: <BottomNavyBarItem>[
          BottomNavyBarItem(
            icon: Icon(Icons.apps),
            title: Text('Home'),
            activeColor: Colors.green,
            inactiveColor: _inactiveColor,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.people),
            title: Text('Users'),
            activeColor: Colors.purpleAccent,
            inactiveColor: _inactiveColor,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.message),
            title: Text(
              'Messages ',
            ),
            activeColor: Colors.pink,
            inactiveColor: _inactiveColor,
            textAlign: TextAlign.center,
          ),
          BottomNavyBarItem(
            icon: Icon(Icons.settings),
            title: Text('Settings'),
            activeColor: Colors.blue,
            inactiveColor: _inactiveColor,
            textAlign: TextAlign.center,
          ),
        ],
      );
    }

    創(chuàng)建custom_animated_bottom_bar.dart文件

    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';

    class CustomAnimatedBottomBar extends StatelessWidget {

      CustomAnimatedBottomBar({
        Key? key,
        this.selectedIndex = 0,
        this.showElevation = true,
        this.iconSize = 24,
        this.backgroundColor,
        this.itemCornerRadius = 50,
        this.containerHeight = 56,
        this.animationDuration = const Duration(milliseconds: 270),
        this.mainAxisAlignment = MainAxisAlignment.spaceBetween,
        required this.items,
        required this.onItemSelected,
        this.curve = Curves.linear,
      }) : assert(items.length >= 2 && items.length <= 5),
            super(key: key);
      
      final int selectedIndex;
      final double iconSize;
      final Color? backgroundColor;
      final bool showElevation;
      final Duration animationDuration;
      final List<BottomNavyBarItem> items;
      final ValueChanged<int> onItemSelected;
      final MainAxisAlignment mainAxisAlignment;
      final double itemCornerRadius;
      final double containerHeight;
      final Curve curve;

      @override
      Widget build(BuildContext context) {
        final bgColor = backgroundColor ?? Theme.of(context).bottomAppBarColor;

        return Container(
          decoration: BoxDecoration(
            color: bgColor,
            boxShadow: [
              if (showElevation)
                const BoxShadow(
                  color: Colors.black12,
                  blurRadius: 2,
                ),
            ],
          ),
          child: SafeArea(
            child: Container(
              width: double.infinity,
              height: containerHeight,
              padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
              child: Row(
                mainAxisAlignment: mainAxisAlignment,
                children: items.map((item) {
                  var index = items.indexOf(item);
                  return GestureDetector(
                    onTap: () => onItemSelected(index),
                    child: _ItemWidget(
                      item: item,
                      iconSize: iconSize,
                      isSelected: index == selectedIndex,
                      backgroundColor: bgColor,
                      itemCornerRadius: itemCornerRadius,
                      animationDuration: animationDuration,
                      curve: curve,
                    ),
                  );
                }).toList(),
              ),
            ),
          ),
        );
      }
    }

    class _ItemWidget extends StatelessWidget {
      final double iconSize;
      final bool isSelected;
      final BottomNavyBarItem item;
      final Color backgroundColor;
      final double itemCornerRadius;
      final Duration animationDuration;
      final Curve curve;

      const _ItemWidget({
        Key? key,
        required this.item,
        required this.isSelected,
        required this.backgroundColor,
        required this.animationDuration,
        required this.itemCornerRadius,
        required this.iconSize,
        this.curve = Curves.linear,
      })  : super(key: key);

      @override
      Widget build(BuildContext context) {
        return Semantics(
          container: true,
          selected: isSelected,
          child: AnimatedContainer(
            width: isSelected ? 130 : 50,
            height: double.maxFinite,
            duration: animationDuration,
            curve: curve,
            decoration: BoxDecoration(
              color:
              isSelected ? item.activeColor.withOpacity(0.2) : backgroundColor,
              borderRadius: BorderRadius.circular(itemCornerRadius),
            ),
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              physics: NeverScrollableScrollPhysics(),
              child: Container(
                width: isSelected ? 130 : 50,
                padding: EdgeInsets.symmetric(horizontal: 8),
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    IconTheme(
                      data: IconThemeData(
                        size: iconSize,
                        color: isSelected
                            ? item.activeColor.withOpacity(1)
                            : item.inactiveColor == null
                            ? item.activeColor
                            : item.inactiveColor,
                      ),
                      child: item.icon,
                    ),
                    if (isSelected)
                      Expanded(
                        child: Container(
                          padding: EdgeInsets.symmetric(horizontal: 4),
                          child: DefaultTextStyle.merge(
                            style: TextStyle(
                              color: item.activeColor,
                              fontWeight: FontWeight.bold,
                            ),
                            maxLines: 1,
                            textAlign: item.textAlign,
                            child: item.title,
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    class BottomNavyBarItem {

      BottomNavyBarItem({
        required this.icon,
        required this.title,
        this.activeColor = Colors.blue,
        this.textAlign,
        this.inactiveColor,
      });

      final Widget icon;
      final Widget title;
      final Color activeColor;
      final Color? inactiveColor;
      final TextAlign? textAlign;

    }

    代碼文件

    import 'package:flutter/material.dart';
    import 'package:flutter_animated_bottom/custom_animated_bottom_bar.dart';

    class MyHomePage extends StatefulWidget {

      @override
      _MyHomePageState createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage{
      int _currentIndex = 0;

      final _inactiveColor = Colors.grey;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              automaticallyImplyLeading: false,
              title: Text("Custom Animated Bottom Navigation Bar"),
              backgroundColor: Colors.green[200],
            ),
            body: getBody(),
            bottomNavigationBar: _buildBottomBar()
        );
      }

      Widget _buildBottomBar(){
        return CustomAnimatedBottomBar(
          containerHeight: 70,
          backgroundColor: Colors.black,
          selectedIndex: _currentIndex,
          showElevation: true,
          itemCornerRadius: 24,
          curve: Curves.easeIn,
          onItemSelected: (index) => setState(() => _currentIndex = index),
          items: <BottomNavyBarItem>[
            BottomNavyBarItem(
              icon: Icon(Icons.apps),
              title: Text('Home'),
              activeColor: Colors.green,
              inactiveColor: _inactiveColor,
              textAlign: TextAlign.center,
            ),
            BottomNavyBarItem(
              icon: Icon(Icons.people),
              title: Text('Users'),
              activeColor: Colors.purpleAccent,
              inactiveColor: _inactiveColor,
              textAlign: TextAlign.center,
            ),
            BottomNavyBarItem(
              icon: Icon(Icons.message),
              title: Text(
                'Messages ',
              ),
              activeColor: Colors.pink,
              inactiveColor: _inactiveColor,
              textAlign: TextAlign.center,
            ),
            BottomNavyBarItem(
              icon: Icon(Icons.settings),
              title: Text('Settings'),
              activeColor: Colors.blue,
              inactiveColor: _inactiveColor,
              textAlign: TextAlign.center,
            ),
          ],
        );
      }


      Widget getBody() {
        List<Widget> pages = [
          Container(
            alignment: Alignment.center,
            child: Text("Home",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
          ),
          Container(
            alignment: Alignment.center,
            child: Text("Users",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
          ),
          Container(
            alignment: Alignment.center,
            child: Text("Messages",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
          ),
          Container(
            alignment: Alignment.center,
            child: Text("Settings",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
          ),
        ];
        return IndexedStack(
          index: _currentIndex,
          children: pages,
        );
      }


    }

    結(jié)論:

    在文章中,我已經(jīng) 在flutter中講解了自定義動(dòng)畫BottomNavigation Bar的基本結(jié)構(gòu);您可以根據(jù)自己的選擇修改此代碼。這是我對(duì)用戶交互自定義動(dòng)畫底部導(dǎo)航欄的一個(gè)小介紹。

    原文鏈接:https://medium.com/flutterdevs/custom-animated-bottomnavigation-bar-in-flutter-65293e231e4a


    瀏覽 176
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    三级无码Av | 高清肏屄视频 | 黄片视频一区二区三区 | 三级片欧美网站 | 成人毛片18女人免费看 |