I need a TabBar and TabView as outlined in https://flutter.dev/docs/cookbook/design/tabs, but there is a twist: I need the ACTIVE tab to show an additional, custom widget.
If the user switches to a different tab, I need the custom widget to disappear from the previously active tab and a NEW custom widget to appear on the newly active tab.
Another way to explain this: all tabs need to host an instance of my custom widget, but the custom widgets should be hidden on all but the active tab.
How to achieve this please?
Many thanks
CodePudding user response:
Tab( )
widget can hold any widget, not just Text
and icon
First, you need to identify which tab was selected.
Then, you need to perform an "if" (?) to decide which widget to display.
Use this code:
int selectedTab=1;
TabBar(
onTap: (index) {
selectedTab = index;
},
tabs: [
Tab(
child: (selectedTab == 1) ? yourCustomWidget1 : yourWidget1
),
Tab(
child: (selectedTab == 2) ? yourCustomWidget2 : yourWidget2
),
]);
Let me know if this does not work
CodePudding user response:
It's all about state management. I did a sample using AnimatedBuilder
with a TabController
but you can customize to fill your needs.
Keep in mind: think declaratively this will help you to create any type of screen with any business logic.
Steps:
- Get the current index
- Listen when current index changes on all tabs
- Verify if the tab index is the current index selected
- If so, render the custom widget
- Otherwise, just ignore, don't build anything
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'),
);
}
}