91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Flutter怎么實現一個底部導航

發布時間:2021-06-09 17:21:18 來源:億速云 閱讀:200 作者:Leah 欄目:移動開發

使用Flutter怎么實現一個底部導航?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

創建navigation_icon_view.dart文件,定義一個NavigationIconView類,用于管理BottomNavigationBarItem(底部導航欄項目)控件的樣式、行為與動畫。

import 'package:flutter/material.dart';
// 創建類,導航圖標視圖
class NavigationIconView {
 // 導航圖標視圖的構造函數
 NavigationIconView({
  // 控件參數,傳遞圖標
  Widget icon,
  // 控件參數,傳遞標題
  Widget title,
  // 控件參數,傳遞顏色
  Color color,
  /*
   * Ticker提供者
   * 由類實現的接口,可以提供Ticker對象
   *  Ticker對象:每個動畫幀調用它的回調一次
   */
  TickerProvider vsync,
 }):_icon = icon, //接收傳遞的圖標
  // 接收傳遞的顏色
  _color = color,
  // 創建底部導航欄項目
  item = new BottomNavigationBarItem(
   // 項目的圖標
   icon: icon,
   // 項目的標題
   title: title
  ),
  // 創建動畫控制器
  controller = new AnimationController(
   // 動畫持續的時間長度:默認情況下主題更改動畫的持續時間
   duration: kThemeAnimationDuration,
   // 垂直同步
   vsync: vsync,
  ) {
   // 創建曲線動畫
   _animation = new CurvedAnimation(
    // 應用曲線動畫的動畫
    parent: controller,
    /*
     * 正向使用的曲線:
     * 從0.5
     * 到1.0結束
     * 應用的曲線:快速啟動并緩和到最終位置的曲線
     */
    curve: new Interval(0.5, 1.0, curve: Curves.fastOutSlowIn),
   );
  }
 // 類成員,存儲圖標
 final Widget _icon;
 // 類成員,存儲顏色
 final Color _color;
 // 類成員,底部導航欄項目
 final BottomNavigationBarItem item;
 // 類成員,動畫控制器
 final AnimationController controller;
 // 類成員,曲線動畫
 CurvedAnimation _animation;
 /*
  * 類函數,過渡轉換
  * BottomNavigationBarType:定義底部導航欄的布局和行為
  * BuildContext:處理控件樹中的控件
  */
 FadeTransition transition(BottomNavigationBarType type, BuildContext context) {
  // 局部變量,存儲圖標顏色
  Color iconColor;
  // 如果底部導航欄的位置和大小在點擊時會變大
  if (type == BottomNavigationBarType.shifting) {
   // 存儲顏色作為圖標顏色
   iconColor = _color;
  } else {
   /*
    * 保存質感設計主題的顏色和排版值:
    * 使用ThemeData來配置主題控件
    * 使用Theme.of獲取當前主題
    */
   final ThemeData themeData = Theme.of(context);
   /*
    * 如果程序整體主題的亮度很高(需要深色文本顏色才能實現可讀的對比度)
    * 就返回程序主要部分的背景顏色作為圖標顏色
    * 否則返回控件的前景顏色作為圖標顏色
    */
   iconColor = themeData.brightness == Brightness.light
    ? themeData.primaryColor
    : themeData.accentColor;
  }
  // 返回值,創建不透明度轉換
  return new FadeTransition(
   // 控制子控件不透明度的動畫
   opacity: _animation,
   // 子控件:創建滑動轉換過渡
   child: new SlideTransition(
    /*
     * 控制子控件位置的動畫
     * 開始值和結束值之間的線性插值<以尺寸的分數表示的偏移量>
     *  (1.0,0.0)表示Size的右上角
     *  (0.0,1.0)表示Size的左下角
     */
    position: new Tween<FractionalOffset>(
     // 此變量在動畫開頭的值
     begin: const FractionalOffset(0.0, 0.02),
     // 此變量在動畫結尾處的值:左上角
     end: FractionalOffset.topLeft,
    ).animate(_animation), // 返回給定動畫,該動畫接受由此對象確定的值
    // 子控件:創建控制子控件的顏色,不透明度和大小的圖標主題
    child: new IconTheme(
     // 用于子控件中圖標的顏色,不透明度和大小
     data: new IconThemeData(
      // 圖標的默認顏色
      color: iconColor,
      // 圖標的默認大小
      size: 120.0,
     ),
     // 子控件
     child: _icon,
    )
   )
  );
 }
}

再創建main.dart文件。類CustomIcon創建一個容器控件,作為一個自定義的圖標使用。同時使用質感設計的彈出菜單控件切換底部導航欄的行為和樣式。

import 'package:flutter/material.dart';
import 'navigation_icon_view.dart';
// 創建類,自定義圖標,繼承StatelessWidget(無狀態的控件)
class CustomIcon extends StatelessWidget {
 // 覆蓋此函數以構建依賴于動畫的當前狀態的控件
 @override
 Widget build(BuildContext context) {
  // 獲取當前圖標主題,創建與此圖標主題相同的圖標主題
  final IconThemeData iconTheme = IconTheme.of(context).fallback();
  // 返回值,創建一個容器控件
  return new Container(
   // 圍繞子控件的填充:每個邊都偏移4.0
   margin: const EdgeInsets.all(4.0),
   // 容器寬度:圖標主題的寬度減8.0
   width: iconTheme.size - 8.0,
   // 容器高度:圖標主題的高度減8.0
   height: iconTheme.size - 8.0,
   // 子控件的裝飾:創建一個裝飾
   decoration: new BoxDecoration(
    // 背景顏色:圖標主題的顏色
    backgroundColor: iconTheme.color
   )
  );
 }
}
// 創建類,菜單演示,繼承StatefulWidget(有狀態的控件)
class MenusDemo extends StatefulWidget {
 /*
  * 覆蓋具有相同名稱的超類成員
  * createState方法在樹中的給定位置為此控件創建可變狀態
  * 子類應重寫此方法以返回其關聯的State子類新創建的實例
  */
 @override
 _MenusDemoState createState() => new _MenusDemoState();
}
/*
 * 關聯State子類的實例
 * 繼承State:StatefulWidget(有狀態的控件)邏輯和內部狀態
 * 繼承TickerProviderStateMixin,提供Ticker對象
 */
class _MenusDemoState extends State<MenusDemo> with TickerProviderStateMixin {
 // 類成員,存儲底部導航欄的當前選擇
 int _currentIndex = 2;
 // 類成員,存儲底部導航欄的布局和行為:在點擊時會變大
 BottomNavigationBarType _type = BottomNavigationBarType.shifting;
 // 類成員,存儲NavigationIconView類的列表
 List<NavigationIconView> _navigationViews;
 /*
  * 在對象插入到樹中時調用
  * 框架將為它創建的每個State(狀態)對象調用此方法一次
  * 覆蓋此方法可以實現此對象被插入到樹中的位置的初始化
  * 或用于配置此對象上的控件的位置的初始化
  */
 @override
 void initState() {
  // 調用父類的內容
  super.initState();
  // 在存儲NavigationIconView類的列表里添加內容
  _navigationViews = <NavigationIconView>[
   /*
    * 創建NavigationIconView類的實例
    * 傳遞圖標參數
    * 傳遞標題參數
    * 傳遞顏色參數
    * 傳遞Ticker對象
    */
   new NavigationIconView(
    icon: new Icon(Icons.access_alarm),
    title: new Text('成就'),
    color: Colors.deepPurple[500],
    vsync: this,
   ),
   new NavigationIconView(
    icon: new CustomIcon(),
    title: new Text('行動'),
    color: Colors.deepOrange[500],
    vsync: this,
   ),
   new NavigationIconView(
    icon: new Icon(Icons.cloud),
    title: new Text('人物'),
    color: Colors.teal[500],
    vsync: this,
   ),
   new NavigationIconView(
    icon: new Icon(Icons.favorite),
    title: new Text('財產'),
    color: Colors.indigo[500],
    vsync: this,
   ),
   new NavigationIconView(
    icon: new Icon(Icons.event_available),
    title: new Text('設置'),
    color: Colors.pink[500],
    vsync: this,
   ),
  ];
  // 循環調用存儲NavigationIconView類的列表的值
  for (NavigationIconView view in _navigationViews)
   // 每次動畫控制器的值更改時調用偵聽器
   view.controller.addListener(_rebuild);
  // 底部導航欄當前選擇的動畫控制器的值為1.0
  _navigationViews[_currentIndex].controller.value = 1.0;
 }
 // 釋放此對象使用的資源
 @override
 void dispose() {
  // 調用父類的內容
  super.dispose();
  // 循環調用存儲NavigationIconView類的列表中的項
  for (NavigationIconView view in _navigationViews)
   // 調用此方法后,對象不再可用
   view.controller.dispose();
 }
 // 動畫控制器的值更改時的操作
 void _rebuild() {
  // 通知框架此對象的內部狀態已更改
  setState((){
   // 重建,以便為視圖創建動畫
  });
 }
 // 建立過渡堆棧
 Widget _buildTransitionsStack() {
  // 局部變量,存儲不透明度轉換的列表
  final List<FadeTransition> transitions = <FadeTransition>[];
  // 循環調用存儲NavigationIconView類的列表的值
  for (NavigationIconView view in _navigationViews)
   // 在存儲不透明度轉換的列表中添加transition函數的返回值
   transitions.add(view.transition(_type, context));
  // 對存儲不透明度轉換的列表進行排序
  transitions.sort((FadeTransition a, FadeTransition b) {
   final Animation<double> aAnimation = a.listenable;
   final Animation<double> bAnimation = b.listenable;
   // aValue:a的動畫值
   double aValue = aAnimation.value;
   // bValue:b的動畫值
   double bValue = bAnimation.value;
   /*
    * 將aValue與bValue進行比較
    * 返回一個負整數,aValue排序在bValue之前
    * 返回一個正整數,aValue排序在bValue之后
    */
   return aValue.compareTo(bValue);
  });
  // 返回值,創建層疊布局控件
  return new Stack(children: transitions);
 }
 // 覆蓋此函數以構建依賴于動畫的當前狀態的控件
 @override
 Widget build(BuildContext context) {
  // 局部變量,創建底部導航欄
  final BottomNavigationBar botNavBar = new BottomNavigationBar(
   /*
    * 在底部導航欄中布置的交互項:迭代存儲NavigationIconView類的列表
    * 返回此迭代的每個元素的底部導航欄項目
    * 創建包含此迭代的元素的列表
    */
   items: _navigationViews
    .map((NavigationIconView navigationView) => navigationView.item)
    .toList(),
   // 當前活動項的索引:存儲底部導航欄的當前選擇
   currentIndex: _currentIndex,
   // 底部導航欄的布局和行為:存儲底部導航欄的布局和行為
   type: _type,
   // 當點擊項目時調用的回調
   onTap: (int index) {
    // 通知框架此對象的內部狀態已更改
    setState((){
     // 當前選擇的底部導航欄項目,開始反向運行此動畫
     _navigationViews[_currentIndex].controller.reverse();
     // 更新存儲底部導航欄的當前選擇
     _currentIndex = index;
     // 當前選擇的底部導航欄項目,開始向前運行此動畫
     _navigationViews[_currentIndex].controller.forward();
    });
   }
  );
  // 實現基本的質感設計視覺布局結構
  return new Scaffold(
   // 質感設計應用欄
   appBar: new AppBar(
    // 應用欄中顯示的主要控件,包含程序當前內容描述的文本
    title: new Text('底部導航演示'),
    // 在標題控件后顯示的控件
    actions: <Widget> [
     // 創建一個顯示彈出式菜單的按鈕
     new PopupMenuButton<BottomNavigationBarType>(
      // 當用戶從此按鈕創建的彈出菜單中選擇一個值時調用
      onSelected: (BottomNavigationBarType value) {
       // 通知框架此對象的內部狀態已更改
       setState((){
        // 存儲底部導航欄的布局和行為:選擇值
        _type = value;
       });
      },
      // 點擊彈出菜單中顯示的項目時調用
      itemBuilder: (BuildContext context) => <PopupMenuItem<BottomNavigationBarType>> [
       /*
        * 彈出菜單中的顯示項目
        * 返回值:底部導航欄的布局和行為
        * 子控件:文本控件
        */
       new PopupMenuItem<BottomNavigationBarType>(
        value: BottomNavigationBarType.fixed,
        child: new Text('Fixed')
       ),
       new PopupMenuItem<BottomNavigationBarType>(
        value: BottomNavigationBarType.shifting,
        child: new Text('Shifting')
       )
      ]
     )
    ]
   ),
   // 主要內容
   body: new Center(
    // 主要內容:_buildTransitionsStack函數的返回值
    child: _buildTransitionsStack()
   ),
   // 水平的按鈕數組,沿著程序的底部顯示
   bottomNavigationBar: botNavBar,
  );
 }
}
// 程序入口
void main() {
 // 創建質感設計程序,并放置到主屏幕
 runApp(new MaterialApp(
  // 在窗口管理器中使用此應用程序的單行描述
  title: 'Flutter教程',
  // 程序的默認路由的控件
  home: new MenusDemo(),
 ));
}

看完上述內容,你們掌握使用Flutter怎么實現一個底部導航的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

出国| 马龙县| 常德市| 湘阴县| 盈江县| 景洪市| 柞水县| 邓州市| 来安县| 馆陶县| 旬阳县| 茶陵县| 济南市| 清水河县| 博客| 万盛区| 永年县| 营山县| 宁波市| 临高县| 通城县| 罗平县| 星座| 靖江市| 福安市| 云南省| 漾濞| 鄯善县| 鸡泽县| 滁州市| 汤原县| 景洪市| 郯城县| 武平县| 伊春市| SHOW| 称多县| 汕头市| 华安县| 台北市| 石棉县|