Fiutter- 案例2 (Home页面)

前言

Home页面是通过BottomNavigationBar去进行切换的,当BottomNavigationBar选中第一个的时候则会打开我们的Home页面

Home页面

微信图片_20220604120715.jpg

创建Home页面

首先需要创建Home页面在BottomNavigationBar切换到第一个的时候展示,而且在实际使用中,我们不希望每次切换到HomePage都创建一个新的,而是需要它持久化,所以我们的Body部分需要使用到PageView

创建一个空的HomePage

class HomePage extends StatefulWidget {

  @override
  State createState() {
    return HomePageState();
  }
}

class HomePageState extends State with SingleTickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
    return Text('Home');
  }

}

修改下之前创好的Mainpage

class MainPage extends StatefulWidget {
  final String title;
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State {
  int currentIndex = 0;

  var _pageController = PageController();

  var pages = [
    HomePage(),
    Text('1'),
    Text('2'),
    Text('3'),
    Text('4'),
  ];

  void onNavigationChanged(int index) {
    setState(() {
      currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.

    return Scaffold(
      body: PageView.builder(
        physics: NeverScrollableScrollPhysics(),
        itemBuilder: (context, index) => pages[index],
        controller: _pageController,
        itemCount: pages.length,
        onPageChanged: onNavigationChanged,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
          BottomNavigationBarItem(icon: Icon(Icons.book), label: '书影音'),
          BottomNavigationBarItem(icon: Icon(Icons.group), label: '小组'),
          BottomNavigationBarItem(icon: Icon(Icons.store), label: '市集'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: '我')
        ],
        currentIndex: currentIndex,
        unselectedItemColor: Colors.grey,
        selectedItemColor: Colors.green,
        type: BottomNavigationBarType.fixed,
        onTap: (index){
          _pageController.jumpToPage(index);
        },
      ),
    );
  }
}

其中currentIndex表示BottomNavigationBar当前切换到位置的一个状态

使用PageView.builder去构建一个PageView
physics: NeverScrollableScrollPhysics()表示不允许左右滑动
itemBuilder表示当前PageView需要根据Index显示什么内容,这里的index指的是PageView
itemCount表示页面的数量
onPageChanged 表示当页面改变的时候会回调的函数,我们设置了不能滑动,所以页面切换只能是手动的

BottomNavigationBar中的onTap我们通过PageController手动切换了PageView的页面

此时当BottomNavigationBar默认选中第一个的时候就会打开HomePage(),并且重复切换不会创建新的HomePage实例,这样就可以保存HomePage的状态

HomePage

AppBar
顶部是使用AppBar构成的,并且可以左右切换的动态,推荐也是AppBar的一部分,所以我们首先需要对AppBar进设置

class HomePageState extends State with SingleTickerProviderStateMixin,AutomaticKeepAliveClientMixin {
  TabController? _tabController;
  
  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
  }

  @override
  void dispose() {
    _tabController?.dispose();
    super.dispose();
  }

  AppBar homePageAppBar() {
    return AppBar(
        backgroundColor: Colors.white,
        elevation: 1,
        leading: Icon(Icons.menu, color: Colors.green),
        actions: [
          Container(
            alignment: Alignment.center,
            child: Icon(Icons.mail_outline, color: Colors.green),
            padding: EdgeInsets.only(left: 16, right: 16),
          )
        ],
        centerTitle: true,
        titleSpacing: 0,
        title: GestureDetector(
          child: Container(
            height: 35,
            alignment: Alignment.center,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(10)),
                color: Color(0x12000000)),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(
                  Icons.search,
                  color: Colors.black26,
                ),
                Text('绝命律师 第六季',
                    style: TextStyle(color: Colors.black26, fontSize: 15))
              ],
            ),
          ),
          onTap: () => {},
        ),
        bottom:   PreferredSize(
            preferredSize: const Size.fromHeight(45),
            child: Container(
                alignment: Alignment.centerLeft,
                child: TabBar(
                  isScrollable: true,
                  controller: _tabController,
                  labelColor: Colors.black,
                  indicatorColor: Colors.black,
                  indicatorSize: TabBarIndicatorSize.label,
                  labelStyle:
                  TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  unselectedLabelStyle:
                  TextStyle(fontSize: 20, fontWeight: FontWeight.normal),
                  labelPadding: EdgeInsets.only(left: 20, right: 20),
                  tabs: [Tab(text: '动态'), Tab(text: '推荐')],
                ))));
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
        appBar: homePageAppBar(),
        body: TabBarView(
          children: [Tab(text: '动态'), Tab(text: '推荐')],
          controller: _tabController,
        ));
  }

  @override
  bool get wantKeepAlive => true;
}

homePageAppBar函数是用来返回一个AppBar的对象,分别设置了这些主要属性

backgroundColor 背景颜色
elevation 阴影高度
leading 左边widget
actions 右边的widget
titleSpacing title左右的距离
centerTitle title是否居中
title title的widget

还有一个比较重要的bottm属性是用来设置TabBar的样式,我们一般也可以直接返回一个TabBar默认是直接横向撑开并且居中的,但是由于我们的TabBar是一个居左的样式所以做了个限定

Body
Body部分就属于TabBar的切换内容,所以在body部分直接使用了可以合TabBar联动的TabBarView即可,他们使用一个相同的Controller

欢迎关注Mike的

Android 知识整理

你可能感兴趣的:(Fiutter- 案例2 (Home页面))