15 Flutter TabBarView和TabBar 定义顶部 Tab 切换

Flutter TabBarView和TabBar 定义顶部 Tab 切换

1.属性

TabBar属性	说明
tabs	一系列标签控件
controller	标签选择变化控制器
isScrollable	是否可滚动,默认false
indicatorColor	指示器颜色
indicatorWeight	指示器粗细
indicator	指示器,可自定义形状等样式
indicatorSize	指示器长短,tab:和tab一样长,label:和标签label 一样长
labelColor	标签颜色
labelStyle	标签样式
labelPadding	标签padding
unselectedLabelColor	未选中标签颜色
unselectedLabelStyle	未选中标签样式
TabBarView属性说明:
children	一系列子控件,如果和TabBar一起使用注意和TabBar的长度一样
controller	控制器,如果和TabBar一起使用注意和TabBar使用同一个controller

____tabs 不可缺少,必要items

——controller不可缺少,与tabs进行一一对应,显示相应的页面

——isScrollable:是否可以滚动,是指tab是否可以滚动显示,而不是指左右滑动,默认false

——label选中颜色

——unSelectedLabelColor:未选中颜色

2.第一种实现方式

import 'package:flutter/material.dart';

class AppBarDemoPage extends StatelessWidget {
  const AppBarDemoPage({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: Text("AppBarDemoPage"),
          backgroundColor: Colors.red,
          centerTitle: true,
          bottom: TabBar(
            tabs: <Widget>[Tab(text: "热门"), Tab(text: "推荐")],
          ),
        ),
        body: TabBarView(
          children: <Widget>[
            ListView(
              children: <Widget>[
                ListTile(title: Text("tab1")),
                ListTile(title: Text("tab1")),
                ListTile(title: Text("tab1"))
              ],
            ),
            ListView(
              children: <Widget>[
                ListTile(title: Text("tab2")),
                ListTile(title: Text("tab2")),
                ListTile(title: Text("tab2"))
              ],
            )
          ],
        ),
      ),
    );
  }
}

3第二种实现方式

import 'package:flutter/material.dart';

class TabBarControllerPage extends StatefulWidget {
  TabBarControllerPage({Key key}) : super(key: key);

  _TabBarControllerPageState createState() => _TabBarControllerPageState();
}

class _TabBarControllerPageState extends State<TabBarControllerPage> with SingleTickerProviderStateMixin {

  TabController _tabController;

  @override
  void dispose() {   //生命周期函数
    // TODO: implement dispose
    super.dispose();
    _tabController.dispose();
  }

  @override
  void initState() {   //生命周期函数
    // TODO: implement initState
    super.initState();
    _tabController=new TabController(
      vsync: this,
      length: 10
    );
    //进行切换监听
    _tabController.addListener((){
      print(_tabController.index);
    });
  }  


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TabBarControllerPage"),
        bottom: TabBar(
          controller: this._tabController,  //注意
          isScrollable: true,
          labelColor: Colors.red,
          unselectedLabelColor: Colors.green,
          tabs: <Widget>[
            Tab(text:"热销"),
            Tab(text:"推荐"),
            Tab(text:"热销"),
            Tab(text:"推荐"),
            Tab(text:"热销"),
            Tab(text:"推荐"),
            Tab(text:"热销"),
            Tab(text:"推荐"),
            Tab(text:"热销"),
            Tab(text:"推荐"),
          ],
        ),
      ),
      body: TabBarView(
        controller: this._tabController,  //注意
        children: <Widget>[
          Center(child: Text("热销")),
          Center(child: Text("推荐")),
          Center(child: Text("热销")),
          Center(child: Text("推荐")),
          Center(child: Text("热销")),
          Center(child: Text("推荐")),
          Center(child: Text("热销")),
          Center(child: Text("推荐")),
          Center(child: Text("热销")),
          Center(child: Text("推荐"))
        ],
      ),
    );
  }
}

4.拓展,如何实现底部导航栏,类似BottomNavigatorBarItem功能

import 'package:flutter/material.dart';

/**
 * 有状态StatefulWidget
 *  继承于 StatefulWidget,通过 State 的 build 方法去构建控件
 */

main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("container组件"),
        ),
        body: BotomeMenumTabBarPage(),
      ),
    );
  }
}

class BotomeMenumTabBarPage extends StatefulWidget {
  //通过构造方法传值
  BotomeMenumTabBarPage();

  //主要是负责创建state
  @override
  BotomeMenumTabBarPageState createState() => BotomeMenumTabBarPageState();
}

/**
 * 在 State 中,可以动态改变数据
 * 在 setState 之后,改变的数据会触发 Widget 重新构建刷新
 */
class BotomeMenumTabBarPageState extends State<BotomeMenumTabBarPage>
    with SingleTickerProviderStateMixin {
  BotomeMenumTabBarPageState();

  TabController tabController;

  @override
  void initState() {
    ///初始化,这个函数在生命周期中只调用一次
    super.initState();
    tabController = new TabController(
        initialIndex: currentIndex, length: pages.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    //构建页面
    return buildBottomTabScaffold();
  }

  //当前显示页面的
  int currentIndex = 2;

  //点击导航项是要显示的页面
  final pages = [
    ChildItemView("1"),
    ChildItemView("2"),
    ChildItemView("3"),
    ChildItemView("4")
  ];

  Widget buildBottomTabScaffold() {
    return new Scaffold(
      body: new TabBarView(controller: tabController, children: pages),
      bottomNavigationBar: new Material(
        color: Colors.blue,
        child: new TabBar(
          controller: tabController,
          tabs: <Tab>[
            new Tab(text: "首页", icon: new Icon(Icons.home)),
            new Tab(text: "视频", icon: new Icon(Icons.find_in_page)),
            new Tab(text: "新闻", icon: new Icon(Icons.message)),
            new Tab(text: "我的", icon: new Icon(Icons.person)),
          ],
          indicatorWeight: 0.1,
        ),
      ),
    );
  }

  /*切换页面*/
  void _changePage(int index) {
    /*如果点击的导航项不是当前项  切换 */
    if (index != currentIndex) {
      setState(() {
        currentIndex = index;
      });
    }
  }
}

//子页面
class ChildItemView extends StatefulWidget {
  String _title;

  ChildItemView(this._title);

  @override
  _ChildItemViewState createState() => _ChildItemViewState();
}

class _ChildItemViewState extends State<ChildItemView> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(child: Text(widget._title)),
    );
  }
}
您可以使用`IndexedStack`和`TabBar`组件来实现无动画切换的`TabBarView`效果。首先,将`TabBar`和`TabBarView`包装在一个`IndexedStack`中,并将当前选中的tab索引传递给`IndexedStack`的`index`属性。然后,使用`TabBar`的`onTap`回调来更新选中的tab索引。这样,当切换tab时,`IndexedStack`会根据当前选中的tab索引显示相应的页面,实现无动画切换效果。 以下是一个示例代码: ```dart import 'package:flutter/material.dart'; class MyTabBarView extends StatefulWidget { @override _MyTabBarViewState createState() => _MyTabBarViewState(); } class _MyTabBarViewState extends State<MyTabBarView> with SingleTickerProviderStateMixin { TabController _tabController; int _currentIndex = 0; @override void initState() { super.initState(); _tabController = TabController(length: 3, vsync: this); _tabController.addListener(() { setState(() { _currentIndex = _tabController.index; }); }); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TabBarView'), ), body: Column( children: [ TabBar( controller: _tabController, tabs: [ Tab(text: 'Tab 1'), Tab(text: 'Tab 2'), Tab(text: 'Tab 3'), ], onTap: (index) { setState(() { _currentIndex = index; }); }, ), Expanded( child: IndexedStack( index: _currentIndex, children: [ Container( color: Colors.red, child: Center(child: Text('Page 1')), ), Container( color: Colors.blue, child: Center(child: Text('Page 2')), ), Container( color: Colors.green, child: Center(child: Text('Page 3')), ), ], ), ), ], ), ); } } void main() { runApp(MaterialApp(home: MyTabBarView())); } ``` 在这个示例中,我们使用`TabBar`来显示选项卡,`IndexedStack`用来根据当前选中的tab索引显示相应的页面。当用户点击选项卡时,我们使用`onTap`回调来更新选中的tab索引,从而实现切换页面的效果。由于使用了`IndexedStack`,切换时没有动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值