Flutter 自定TabBarView

2019-10-30  本文已影响0人  小米Metre

实现Tab标签点击和tab内容联动,调用简单。

效果图:


tab.gif

tab_bar_page_view.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

typedef OnTabChanged = Function(int index);

///@describe 自定义TabBarView
///
///@author mi
///
///@time 2019/10/29
// ignore: must_be_immutable
class TabBarPageView extends StatefulWidget{

  //Tab标签
  List<String> tabTexts;

  //Tab标签对应的Page
  List<Widget> pages;

  //Tab切换回调
  OnTabChanged onTabChanged;

  TabBarPageView({@required this.tabTexts,@required this.pages,this.onTabChanged});

  @override
  State<StatefulWidget> createState() => TabBarViewState();

}

class TabBarViewState extends State<TabBarPageView> with SingleTickerProviderStateMixin{


  TabController _controller;

  int _currentIndex = 0;

  @override
  void initState() {
    super.initState(); 

    if(widget.pages == null){
      throw  StateError('pages cannot be null.');
    }

    if(widget.tabTexts == null){
      throw  StateError('tabTexts cannot be null.');
    }

    if(widget.pages.length != widget.tabTexts.length){
      throw  StateError('pages and tabTexts are not equal in length.');
    }
    _controller = TabController(length: widget.tabTexts.length,vsync: this);

    _controller.addListener((){

      if(widget.onTabChanged != null){

        if(_currentIndex == _controller.index)return;

        widget.onTabChanged(_controller.index);
        _currentIndex = _controller.index;
      }

    });

    if(widget.onTabChanged != null){
      widget.onTabChanged(_currentIndex);
    }

  }

  @override
  Widget build(BuildContext context) {

    return DefaultTabController(
      length: widget.pages.length,
      child: new Scaffold(
        appBar: TabBar(
          controller: _controller,
          labelColor: Theme.of(context).primaryColor,
          labelStyle: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),
          unselectedLabelColor: Colors.grey,
          unselectedLabelStyle: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),
          indicatorColor: Theme.of(context).primaryColor,
          //isScrollable false:平分宽度,true:tab可滚动
          isScrollable: false,
          indicatorSize: TabBarIndicatorSize.tab,
          tabs: widget.tabTexts.map((String name){
            return Tab(text: name);
          }).toList(),
        ),
        body: TabBarView(
          controller: _controller,
          children: widget.pages.map((widget){
            return widget;
          }).toList(),
        ),
      ),
    );
  }
}

调用方式:

    //定义Tab标签
    var tabTexts = ["全部", "待支付", "已完成"];

    //定义ab标签对应的Page
    var pages = [
      Center(child: Text("内容(全部)")),
      Center(child: Text("内容(待支付)")),
      Center(child: Text("内容(已完成)"))
    ];
     //调用
    TabBarPageView(tabTexts: tabTexts, pages: pages,onTabChanged: (index){
      print("onTabChanged-->index:$index");
    });

上一篇下一篇

猜你喜欢

热点阅读