将自定义小部件添加到 Flutter TabBar 的活动选项卡

Posted

技术标签:

【中文标题】将自定义小部件添加到 Flutter TabBar 的活动选项卡【英文标题】:Adding a custom widget to active tab of Flutter TabBar 【发布时间】:2021-12-09 21:09:48 【问题描述】:

我需要 https://flutter.dev/docs/cookbook/design/tabs 中所述的 TabBar 和 TabView,但有一个转折点:我需要 ACTIVE 选项卡来显示额外的自定义小部件。

如果用户切换到不同的选项卡,我需要自定义小部件从先前活动的选项卡中消失,并且新的自定义小部件出现在新活动的选项卡上。

另一种解释方式:所有选项卡都需要托管我的自定义小部件的实例,但自定义小部件应隐藏在除活动选项卡之外的所有选项卡上。

请问如何实现?

非常感谢

【问题讨论】:

【参考方案1】:

这都是关于状态管理的。我使用AnimatedBuilderTabController 做了一个示例,但您可以自定义以满足您的需求。

请记住:think declaratively 这将帮助您创建具有任何业务逻辑的任何类型的屏幕。

步骤:

获取当前索引 在所有选项卡上的当前索引更改时监听 验证选项卡索引是否是当前选择的索引 如果是,则呈现自定义小部件 否则,只是忽略,不要构建任何东西

Dartpad Link

import 'package:flutter/material.dart';

void main() 
  runApp(const TabBarDemo());


class TabBarDemo extends StatefulWidget 
  const TabBarDemo(Key? key) : super(key: key);

  @override
  _TabBarDemoState createState() => _TabBarDemoState();


class _TabBarDemoState extends State<TabBarDemo>
    with SingleTickerProviderStateMixin 
  late final TabController _controller;

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

    _controller = TabController(length: 3, vsync: this, initialIndex: 0);
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            controller: _controller,
            tabs: [
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) 
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_car),
                        if (_controller.index == 0) const MyCustomWidget(),
                      ],
                    );
                  ,
                ),
              ),
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) 
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_transit),
                        if (_controller.index == 1) const MyCustomWidget(),
                      ],
                    );
                  ,
                ),
              ),
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) 
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_bike),
                        if (_controller.index == 2) const MyCustomWidget(),
                      ],
                    );
                  ,
                ),
              ),
            ],
          ),
          title: const Text('Tabs Demo'),
        ),
        body: TabBarView(
          controller: _controller,
          children: const [
            Icon(Icons.directions_car),
            Icon(Icons.directions_transit),
            Icon(Icons.directions_bike),
          ],
        ),
      ),
    );
  


class MyCustomWidget extends StatelessWidget 
  const MyCustomWidget(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Container(
      color: Colors.red,
      child: const Text('Your CustomWidget'),
    );
  

【讨论】:

谢谢,非常有帮助。有没有办法让每个 MyCustomWidget() 自己找出活动选项卡的索引,以便它可以显示/隐藏自己?这样可以避免每个选项卡中的重复代码“if (_controller.index == xxxx) const MyCustomWidget()” 我应该说“活动标签的索引和它自己的索引” 是的,您可以添加一个 for 循环来构建每个选项卡,您将使用循环的索引而不是原始索引,如 0、1、3、...【参考方案2】:

Tab( ) 小部件可以容纳任何小部件,而不仅仅是Texticon

首先,您需要确定选择了哪个选项卡。

然后,您需要执行“if”(?) 来决定要显示哪个小部件。

使用此代码:

int selectedTab=1;
    TabBar(
        onTap: (index) 
          selectedTab = index;
        ,

        tabs: [
          Tab(
              child: (selectedTab == 1) ? yourCustomWidget1 : yourWidget1
          ),
          Tab(
              child: (selectedTab == 2) ? yourCustomWidget2 : yourWidget2
          ),
        ]);

如果这不起作用,请告诉我

【讨论】:

谢谢,它很有帮助,但我很确定如果用户滑动 TabBarView 以进入另一个选项卡,onTap() 不会触发?

以上是关于将自定义小部件添加到 Flutter TabBar 的活动选项卡的主要内容,如果未能解决你的问题,请参考以下文章

将自定义小部件添加到 QStackedWidget

有没有办法将自定义 QGroupBox 添加到任何小部件/布局?

php 将自定义控件添加到现有Elementor窗口小部件

将自定义组件小部件动态添加到 Android 中的布局中

php DashboardWidgeteinfügen - 将自定义仪表板小部件添加到wordpress

如何将自定义彩色图像添加到 TabBarController 中的 tabBar?