美文网首页Flutter 实战
Flutter入门(17):Flutter 组件之 TabBar

Flutter入门(17):Flutter 组件之 TabBar

作者: Maojunhao | 来源:发表于2020-09-15 11:28 被阅读0次

    1. 基本介绍

    TabBar、TabBarView,TabController 提供了常见的多Tab切换的功能。本文接着 Flutter 组件之 TabBar 详解继续讲解。

    2. 示例代码

    代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。

    3. 属性介绍

    TabBarView属性 介绍
    children 子页面,注意保持 TabBarView.children 数量、DefaultTabController.length, TabBar.tabs 三者数量相同。
    controller TabController,联动控制,下文中自行感受一下,可以关掉 TabBar 或者 TabBarView 的 controller 属性感受一下。
    physics 滑动效果,如滑动到末端时,继续拉动,使用 ClampingScrollPhysics 实现Android下微光效果。使用 BouncingScrollPhysics 实现iOS下弹性效果。
    dragStartBehavior 启动时阻尼效果,默认为 DragStartBehavior.start

    4. TabBarView 组件

    4.1 容器创建

    优雅的编程,首先创建一个 tabbarview.dart 文件。先直接创建一个 TabBar 组件,Flutter 组件之 TabBar 详解 已经介绍的很详细了,不多叙述。

    import 'package:flutter/material.dart';
    
    class FMTabbarViewVC extends StatefulWidget {
      @override
      FMTabbarViewState createState() => FMTabbarViewState();
    }
    
    class FMTabbarViewState extends State<FMTabbarViewVC> {
      var pageDatas = [];
      TabController controller;
    
      @override
      void initState(){
        super.initState();
    
        initData();
        controller = TabController(length: pageDatas.length, vsync: ScrollableState());
      }
    
    
      void initData(){
        pageDatas.add({"title":"一年级英语", "content":["我是一年级英语一班", "我是一年级英语二班","我是一年级英语三班"]});
        pageDatas.add({"title":"二年级英语", "content":["我是二年级英语一班", "我是二年级英语二班","我是二年级英语三班"]});
        pageDatas.add({"title":"三年级英语", "content":["我是三年级英语一班", "我是三年级英语二班","我是三年级英语三班"]});
        pageDatas.add({"title":"四年级英语", "content":["我是四年级英语一班", "我是四年级英语二班","我是四年级英语三班"]});
        pageDatas.add({"title":"五年级英语", "content":["我是五年级英语一班", "我是五年级英语二班","我是五年级英语三班"]});
    
        setState(() {
    
        });
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return DefaultTabController(
          length: pageDatas.length,
          child: Scaffold(
            appBar: AppBar(
              title: Text('TabBar'),
              bottom: _tabBar(),
            ),
            body: Container(
              color: Colors.grey,
            ),
          ),
        );
      }
    
      TabBar _tabBar(){
        return TabBar(
          tabs: _tabs(),
          isScrollable: true,
          indicatorColor: Colors.red,
          indicatorWeight: 5,
          controller: controller,
          onTap: (index){
            print("点击了 index = ${index}");
          },
        );
      }
    
      List <Widget> _tabs(){
        List <Widget> tabList = [];
        pageDatas.forEach((page) {
          tabList.add(
            Tab(text: page["title"],),
          );
        });
        print(tabList);
        return tabList;
      }
    }
    
    tabbar.png

    4.2 创建 TabBarView

      Widget build(BuildContext context) {
        // TODO: implement build
        return DefaultTabController(
          length: pageDatas.length,
          child: Scaffold(
            appBar: AppBar(
              title: Text('TabBar'),
              bottom: _tabBar(),
            ),
            body: _tabBarView(),
          ),
        );
      }
    
      TabBarView _tabBarView(){
        return TabBarView(
          children: _tabViews(),
          controller: controller,
        );
      }
    
      List <Widget> _tabViews(){
        List <Widget> tabViewList = [];
        pageDatas.forEach((page) {
          var contents = page["content"];
          tabViewList.add(
            ListView(
              children: _listViewChildren(contents),
            ),
          );
        });
        print(tabViewList);
        return tabViewList;
      }
    
      List <Widget> _listViewChildren(List contents){
        List <Widget> children = [];
        contents.forEach((content) {
          children.add(
              ListTile(title: Text("${content}"),)
          );
        });
        return children;
      }
    

    到这里其实一个联动的自定义数据的 tabBarView 已经完成了。


    tabbarview one.png
    tabbarview three.png

    4.3 physics

    使用 physics 完成一些物理效果,使用 ClampingScrollPhysics 实现Android下微光效果。使用 BouncingScrollPhysics 实现iOS下弹性效果。

      TabBarView _tabBarView(){
        return TabBarView(
          children: _tabViews(),
          physics: BouncingScrollPhysics(
    
          ),
          controller: controller,
        );
      }
    

    这里就不截图了,建议滑到最后一页继续滑动感受一下。

    4.4 dragStartBehavior

    启动阻尼,默认为 DragStartBehavior.start,还有个 DragStartBehavior.down,编译后自行体验效果吧。

      TabBarView _tabBarView(){
        return TabBarView(
          children: _tabViews(),
          physics: BouncingScrollPhysics(
    
          ),
          dragStartBehavior: DragStartBehavior.down,
          controller: controller,
        );
      }
    

    4.5 常见报错

    Controller's length property (5) does not match the number of tabs (1) present in TabBar's tabs property.
    
    tabbarview error.png

    注意:当 TabBarView.children 数量与 Tabs 数量不同时,会报错。注意保持 TabBarView.children 数量、DefaultTabController.length, TabBar.tabs 三者数量相同。

    5. 技术小结

    • TabBarView 的属性较少。
    • TabBarView.children 数量、DefaultTabController.length, TabBar.tabs 三者数量必须相同。
    • TabBarView 可以理解为一个特殊的容器,主要的还是子控件的布局,可以使用任意组件。
    • 使用好 TabController 控制联动效果。

    相关文章

      网友评论

        本文标题:Flutter入门(17):Flutter 组件之 TabBar

        本文链接:https://www.haomeiwen.com/subject/opmzektx.html