flutter页面滚动TabBar+TabBarView

3 阅读1分钟

需求:实现页面和标签栏的点击跳转以及左右滑动跳转功能

注意点

必须保证TabBar、TabBarView、TabController传入的length为相同值且>=0

TabBar+TabBarView

  • 联合DefaultTabController

    DefaultTabController(
     length:lists.length,
     child:Scaffold(/// 根据UI规范写法,Column更自由
       appBar:AppBar(
         title:'xxx',
         bottom:TarBar(
           tabs:lists.map(item=>item.name).toList,
    
         )
       ),
       home:TarBarView()
     )
    )
    
  • 自定义Controller

  TabController? _tabController;
  
    void _initTabController(int length) {
    _tabController?.removeListener(_handleTabChanged);
    _tabController?.dispose();

    if (length == 0) {
      _tabController = null;
      return;
    }

    _tabController = TabController(
      length: length,
      vsync: this,
      initialIndex: _safeIndex,
    );

    _tabController!.addListener(_handleTabChanged);
    }
  
  @override
  void initState() {
    super.initState();
    _initTabController(widget.tabs.length);
  }
  
    @override
  void dispose() {
    _tabController?.removeListener(_handleTabChanged);
    _tabController?.dispose();
    super.dispose();
  }
  
  @override 
  void buildContent(){
      return Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
          color: backgroundColor,
          child: TabBar(
            controller: _tabController, 
            onTap: (index) {
              if (widget.selectedIndex != index) {
                widget.onTabChanged(index);
              }
            },
            isScrollable: true,
            tabAlignment: TabAlignment.start,
            tabs: widget.tabs.map((e) => Tab(text: e)).toList(),
            dividerColor: Colors.white.withValues(alpha: 0.1),
            indicatorSize: TabBarIndicatorSize.label,
            indicatorPadding: const EdgeInsets.symmetric(horizontal: 16),
            indicator: BoxDecoration(
              borderRadius: BorderRadius.circular(1.5),
              border: Border(
                bottom: BorderSide(
                  color: widget.selectedLabelColor ?? Colors.white,
                  width: 2.w,
                ),
              ),
            ),
            labelColor: widget.selectedLabelColor ?? Colors.white,
            unselectedLabelColor:
                widget.unselectedLabelColor ?? Colors.white.withValues(alpha: 0.6),
            labelStyle: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
            dividerHeight: 0.5,
          ),
        );
          },

        widget.center ?? const SizedBox.shrink(),

        Expanded(
          child: TabBarView(
            controller: _tabController,
            children: widget.children,
          ),
        ),
      ],
    );
  }