flutter 自定义tabbar 给tabbar添加背景功能

flutter 自带的tabbar BottomNavigationBar有长按水波纹效果,不可以添加背景图片功能,如果有这方面的需求,就需要自定义tabbar了

自定义图片 我们使用BottomAppBar 设定宽高,内部的UI就可以完全自定义 测试了一下,基本能达到想要的效果

废话不多了,直接上代码了

import 'package:flutter/material.dart';
import 'home.dart';
import 'category.dart';
import 'activity.dart';
import 'mine.dart';

class TabbarPage extends StatefulWidget {
  @override
  _TabbarPageState createState() => _TabbarPageState();
}

class _TabbarPageState extends State<TabbarPage> {
 PageController _pageController;

  List images = [
    ['assets/tab_icon_home.png', 'assets/tab_icon_home_selected.png'],
    ['assets/tab_icon_category.png', 'assets/tab_icon_category_selected.png'],
    ['assets/tab_icon_collect.png', 'assets/tab_icon_collect_selected.png'],
    ['assets/tab_icon_profile.png', 'assets/tab_icon_profile_selected.png'],
  ];

  final List _titles = ['首页', '好物', '双11', '我的'];

  final List<Widget> _tabBodies = [
    HomePage(),
    CategoryPage(),
    ActivityPage(),
    MinePage(),
  ];

  int _currentIndex = 0;

  void initState() {
    super.initState();
    this._pageController =PageController(initialPage: _currentIndex, keepPage: true);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // body: IndexedStack(
      //   index: _currentIndex,
      //   children: _tabBodies,
      // ),
      body: PageView(
        children: _tabBodies,
        controller: _pageController,
        // physics: NeverScrollableScrollPhysics(),
      ),
      // bottomNavigationBar: BottomNavigationBar(
      //   backgroundColor: Colors.brown,
      //   type: BottomNavigationBarType.fixed,
      //   currentIndex: _currentIndex,
      //   items: getItems(),
      //   onTap: (index) {
      //     setState(() {
      //       _currentIndex = index;
      //       // _pageController.jumpToPage(index);
      //     });
      //   },
      // ),
      bottomNavigationBar: _bottomAppBar(),
    );
  }

  BottomAppBar _bottomAppBar() {
    double width = MediaQuery.of(context).size.width;
    double height = 60;

    return BottomAppBar(
      child: Container(
        //设置背景
        decoration: BoxDecoration(
          image: DecorationImage(
            fit: BoxFit.cover,
            repeat: ImageRepeat.noRepeat,
            image: AssetImage('assets/tab_festival_background_android.png'),
          ),
        ),
        width: width,
        height: height,
        child: Row(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: _customItems(),
        ),
      ),
    );
  }

  /*获取tab图片*/
  Widget getTabIcon(int index) {
    if (_currentIndex == index) {
      return Image.asset(
        images[index][1],
        width: 30,
        fit: BoxFit.fitHeight,
      );
    }
    return Image.asset(images[index][0], width: 30, fit: BoxFit.fitHeight);
  }

/*获取tab文字*/
  Text getTabText(int index) {
    if (_currentIndex == index) {
      return Text(
        _titles[index],
        style: TextStyle(color: Color(0xFFEA164B), fontSize: 11),
      );
    }

    return Text(
      _titles[index],
      style: TextStyle(color: Color(0xFF8228CF), fontSize: 11),
    );
  }

  /*获取tabbatItem*/
  List<BottomNavigationBarItem> getItems() {
    return [
      BottomNavigationBarItem(
        icon: getTabIcon(0),
        title: getTabText(0),
      ),
      BottomNavigationBarItem(icon: getTabIcon(1), title: getTabText(1)),
      BottomNavigationBarItem(icon: getTabIcon(2), title: getTabText(2)),
      BottomNavigationBarItem(icon: getTabIcon(3), title: getTabText(3)),
    ];
  }

  List<Widget> _customItems() {
    double width = MediaQuery.of(context).size.width;
    //均分成4分
    double itemWidth = width / 4.0;
    return images.map((img) {
      int index = images.indexOf(img);
      return GestureDetector(
        onTap: () {
          setState(() {
            _currentIndex = index;
            _pageController.jumpToPage(index);
          });
        },
        child: Container(
          color: Colors.transparent,
          width: itemWidth * 0.8,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              getTabIcon(index),
              getTabText(index),
            ],
          ),
        ),
      );
    }).toList();
  }
}

tabbar中通过pageView来实现页面的持久保存,细节参考

posted @ 2019-11-05 15:57  qqcc1388  阅读(3220)  评论(0编辑  收藏  举报