Flutter development practice-implementing custom bottomNavigationBar style awesome_bottom_bar

Flutter development practice-implementing custom bottomNavigationBar style awesome_bottom_bar

During the development process, you need to customize the bottomNavigationBar style. You can customize the implementation. The awesome_bottom_bar library is used here.

Insert image description here

一、awesome_bottom_bar

Introduce awesome_bottom_bar in pubspec.yaml

awesome_bottom_bar: ^1.2.2

2. Implement custom bottomNavigationBar

Switch interface using PageView.builder

PageView is a very important component. For example, most apps include Tab page changing effects, picture rotation, and Douyin up and down page switching video functions, etc., which can all be implemented using PageView.

PageView({
    
    
  Key? key,
  this.scrollDirection = Axis.horizontal, // 滑动方向
  this.reverse = false,
  PageController? controller,
  this.physics,
  List<Widget> children = const <Widget>[],
  this.onPageChanged,
  
  //每次滑动是否强制切换整个页面,如果为false,则会根据实际的滑动距离显示页面
  this.pageSnapping = true,
  //主要是配合辅助功能用的,后面解释
  this.allowImplicitScrolling = false,
  //后面解释
  this.padEnds = true,
})

Use PageView.builder to switch interfaces. When clicking different tabs, you can use PageController to switch.

PageView.builder(
          itemBuilder: (BuildContext context, int index) {
    
    
            return KeepAliveWrapper(
                child: subMainPages[index], keepAlive: true);
          },
          itemCount: subMainPages.length,
          controller: _pageController,
          physics: NeverScrollableScrollPhysics(),
          onPageChanged: (index) {
    
    
            _selectedIndex = index;
            _animationControllerList[_selectedIndex!].forward();
            _animationControllerList[_lastSelectedIndex!].reverse();
          },
        ),
      ),

bottomNavigationBar using default effect

bottomNavigationBar: BottomBarDefault(
        items: buildTabItems(context),
        backgroundColor: Colors.white,
        color: Colors.black87,
        colorSelected: Colors.amber,
        indexSelected: _selectedIndex,
        duration: Duration(milliseconds: 200),
        onTap: (int index) => setState(() {
    
    
          _lastSelectedIndex = _selectedIndex;
          _pageController.jumpToPage(index);
        }),
      ),

When a special style of bottomNavigationBar is needed, such as the following triangle style that will highlight after clicking

bottomNavigationBar: BottomBarInspiredInside(
        items: [
          TabItem(
            icon: Icons.home_outlined,
            title: S.of(context).home,
          ),
          TabItem(
            icon: Icons.qr_code_scanner_outlined,
            title: S.of(context).qrScan,
          ),
          TabItem(
            icon: Icons.nature_outlined,
            title: S.of(context).mine,
            count: Container(
              padding: EdgeInsets.all(3.0),
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.white,
                  width: 1.0,
                  style: BorderStyle.solid,
                ),
                color: Colors.red,
                borderRadius: BorderRadius.all(
                  Radius.circular(20.0),
                ),
                // gradient: LinearGradient(
                //   begin: Alignment.topLeft,
                //   end: Alignment.bottomRight,
                //   colors: [
                //     Colors.red.withOpacity(0.5),
                //     Colors.red.withOpacity(0.3),
                //     Colors.red.withOpacity(1.0),
                //   ],
                // ),
              ),
              child: Text(
                "99",
                style: TextStyle(
                    fontSize: 10,
                    color: Colors.white,
                    fontWeight: FontWeight.w500),
              ),
            ),
          )
        ],
        backgroundColor: Colors.lightBlue,
        color: Colors.white,
        colorSelected: Colors.white,
        indexSelected: _selectedIndex,
        duration: Duration(milliseconds: 200),
        onTap: (int index) => setState(() {
    
    
          _pageController.jumpToPage(index);
        }),
        itemStyle: ItemStyle.hexagon,
        chipStyle:
            const ChipStyle(isHexagon: true, background: Colors.blueAccent),
      ),

The complete example code is as follows

class MainTabNavigator extends StatefulWidget {
    
    
  const MainTabNavigator({
    
    Key? key}) : super(key: key);

  
  State<MainTabNavigator> createState() => _MainTabNavigatorState();
}

class _MainTabNavigatorState extends State<MainTabNavigator>
    with TickerProviderStateMixin {
    
    
  PageController _pageController = PageController();
  int _selectedIndex = 0;
  late DateTime _lastPressed;

  List<Widget> subMainPages = [];

  late List<AnimationController> _animationControllerList;
  late List<Animation<double>> _animationList;

  int? _lastSelectedIndex = 0;

  
  void initState() {
    
    

    // 设置默认的
    subMainPages = mainPages;
    super.initState();

    _animationControllerList = List<AnimationController>.empty(growable: true);
    _animationList = List<Animation<double>>.empty(growable: true);

    for (int i = 0; i < subMainPages.length; ++i) {
    
    
      _animationControllerList.add(AnimationController(
          duration: Duration(milliseconds: 200), vsync: this));
      _animationList.add(Tween(begin: 0.0, end: 5.0)
          .chain(CurveTween(curve: Curves.ease))
          .animate(_animationControllerList[i]));
    }

    WidgetsBinding.instance.addPostFrameCallback((_) {
    
    
      _animationControllerList[_selectedIndex!].forward();
    });
  }

  void animationDispose() {
    
    
    for (int i = 0; i < subMainPages.length; ++i) {
    
    
      _animationControllerList[i].dispose();
    }
  }

  
  void dispose() {
    
    
    // TODO: implement dispose
    animationDispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: WillPopScope(
        onWillPop: () async {
    
    
          if (_lastPressed == null ||
              DateTime.now().difference(_lastPressed) > Duration(seconds: 1)) {
    
    
            //两次点击间隔超过1秒则重新计时
            _lastPressed = DateTime.now();
            return false;
          }
          return true;
        },
        child: PageView.builder(
          itemBuilder: (BuildContext context, int index) {
    
    
            return KeepAliveWrapper(
                child: subMainPages[index], keepAlive: true);
          },
          itemCount: subMainPages.length,
          controller: _pageController,
          physics: NeverScrollableScrollPhysics(),
          onPageChanged: (index) {
    
    
            _selectedIndex = index;
            _animationControllerList[_selectedIndex!].forward();
            _animationControllerList[_lastSelectedIndex!].reverse();
          },
        ),
      ),
      // bottomNavigationBar: BottomBarDefault(
      //   items: buildTabItems(context),
      //   backgroundColor: Colors.white,
      //   color: Colors.black87,
      //   colorSelected: Colors.amber,
      //   indexSelected: _selectedIndex,
      //   duration: Duration(milliseconds: 200),
      //   onTap: (int index) => setState(() {
    
    
      //     _lastSelectedIndex = _selectedIndex;
      //     _pageController.jumpToPage(index);
      //   }),
      // ),
      bottomNavigationBar: BottomBarInspiredInside(
        items: [
          TabItem(
            icon: Icons.home_outlined,
            title: S.of(context).home,
          ),
          TabItem(
            icon: Icons.qr_code_scanner_outlined,
            title: S.of(context).qrScan,
          ),
          TabItem(
            icon: Icons.nature_outlined,
            title: S.of(context).mine,
            count: Container(
              padding: EdgeInsets.all(3.0),
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.white,
                  width: 1.0,
                  style: BorderStyle.solid,
                ),
                color: Colors.red,
                borderRadius: BorderRadius.all(
                  Radius.circular(20.0),
                ),
                // gradient: LinearGradient(
                //   begin: Alignment.topLeft,
                //   end: Alignment.bottomRight,
                //   colors: [
                //     Colors.red.withOpacity(0.5),
                //     Colors.red.withOpacity(0.3),
                //     Colors.red.withOpacity(1.0),
                //   ],
                // ),
              ),
              child: Text(
                "99",
                style: TextStyle(
                    fontSize: 10,
                    color: Colors.white,
                    fontWeight: FontWeight.w500),
              ),
            ),
          )
        ],
        backgroundColor: Colors.lightBlue,
        color: Colors.white,
        colorSelected: Colors.white,
        indexSelected: _selectedIndex,
        duration: Duration(milliseconds: 200),
        onTap: (int index) => setState(() {
    
    
          _pageController.jumpToPage(index);
        }),
        itemStyle: ItemStyle.hexagon,
        chipStyle:
            const ChipStyle(isHexagon: true, background: Colors.blueAccent),
      ),
      // bottomNavigationBar: FlashyTabBar(
      //   selectedIndex: _selectedIndex,
      //   showElevation: true,
      //   onItemSelected: (index) => setState(() {
    
    
      //     _pageController.jumpToPage(index);
      //   }),
      //   items: [
      //     FlashyTabBarItem(
      //       icon: Icon(Icons.home_outlined),
      //       title: Text(S.of(context).home),
      //     ),
      //     FlashyTabBarItem(
      //       icon: Icon(Icons.qr_code_scanner_outlined),
      //       title: Text(S.of(context).qrScan),
      //     ),
      //     FlashyTabBarItem(
      //       icon: Icon(Icons.nature_outlined),
      //       title: Text(S.of(context).mine),
      //     ),
      //   ],
      // ),      // bottomNavigationBar: BottomNavigationBar(
    );
  }

  List<TabItem> buildTabItems(BuildContext context) {
    
    
    TabItem homeItem = TabItem(
      icon: Icons.home_outlined,
      title: S.of(context).home,
      count: buildTabItem(context, 0),
    );
    TabItem qsItem = TabItem(
      icon: Icons.qr_code_scanner_outlined,
      title: S.of(context).qrScan,
      count: buildTabItem(context, 1),
    );

    TabItem discoveryItem = TabItem(
      icon: Icons.location_searching_outlined,
      title: S.of(context).discovery,
      count: buildTabItem(context, 2),
    );

    TabItem mineItem = TabItem(
      icon: Icons.nature_outlined,
      title: S.of(context).mine,
      count: buildTabItem(context, 3),
    );
    return [homeItem, qsItem, discoveryItem, mineItem];
  }

  Widget buildTabItem(BuildContext context, int index) {
    
    
    return AnimatedBuilder(
      animation: _animationList[index],
      builder: (BuildContext context, Widget? child) {
    
    
        return Container(
          margin: EdgeInsets.only(
            top: _animationList[index].value,
          ),
          child: child,
        );
      },
      child: buildTabItemCount(context),
    );
  }

  Widget buildTabItemCount(BuildContext context) {
    
    
    return Container(
      padding: const EdgeInsets.all(3.0),
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.white,
          width: 1.0,
          style: BorderStyle.solid,
        ),
        color: Colors.red,
        borderRadius: const BorderRadius.all(
          Radius.circular(30.0),
        ),
        // gradient: LinearGradient(
        //   begin: Alignment.topLeft,
        //   end: Alignment.bottomRight,
        //   colors: [
        //     Colors.red.withOpacity(0.5),
        //     Colors.red.withOpacity(0.3),
        //     Colors.red.withOpacity(1.0),
        //   ],
        // ),
      ),
      child: const Text(
        "99",
        style: TextStyle(
            fontSize: 10, color: Colors.white, fontWeight: FontWeight.w500),
      ),
    );
  }
}

3. Summary

Flutter development practice-customize bottomNavigationBar style.

https://blog.csdn.net/gloryFlow/article/details/132761946

Study and record, keep improving every day.

Guess you like

Origin blog.csdn.net/gloryFlow/article/details/132761946
Recommended