将自定义小部件添加到 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】:这都是关于状态管理的。我使用AnimatedBuilder
和TabController
做了一个示例,但您可以自定义以满足您的需求。
请记住: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( )
小部件可以容纳任何小部件,而不仅仅是Text
和icon
首先,您需要确定选择了哪个选项卡。
然后,您需要执行“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 的活动选项卡的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将自定义 QGroupBox 添加到任何小部件/布局?