I am trying to create a tab bar in Flutter that mimics the label style seen on Microsoft Edge's tabs. Specifically, I want to achieve the following effects:
Edge-like Label Design:
- The label should have a distinct background color or border that makes it stand out.
Dynamic Behavior:
- The label should dynamically adjust its size and position based on the selected tab.
- The label should smoothly animate when switching between tabs.
I am currently using Flutter's TabBar
and TabBarView
for tab navigation, but I am unsure how to implement this kind of label effect. Here's a simplified version of my current code:
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('Edge-like TabBar'),
bottom: TabBar(
tabs: [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
Tab(text: 'Tab 3'),
],
),
),
body: TabBarView(
children: [
Center(child: Text('Content 1')),
Center(child: Text('Content 2')),
Center(child: Text('Content 3')),
],
),
),
);
What I Have Tried
- I have explored customizing the
TabBar
using theindicator
property, but it only affects the underline or background of the selected tab, not the label itself. - I looked into using
Stack
orPositioned
widgets to overlay a custom label, but I couldn't figure out how to make it dynamically follow the selected tab. - I considered using a
PageView
with custom animations, but it seems like overkill for this use case.
I am trying to create a tab bar in Flutter that mimics the label style seen on Microsoft Edge's tabs. Specifically, I want to achieve the following effects:
Edge-like Label Design:
- The label should have a distinct background color or border that makes it stand out.
Dynamic Behavior:
- The label should dynamically adjust its size and position based on the selected tab.
- The label should smoothly animate when switching between tabs.
I am currently using Flutter's TabBar
and TabBarView
for tab navigation, but I am unsure how to implement this kind of label effect. Here's a simplified version of my current code:
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('Edge-like TabBar'),
bottom: TabBar(
tabs: [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
Tab(text: 'Tab 3'),
],
),
),
body: TabBarView(
children: [
Center(child: Text('Content 1')),
Center(child: Text('Content 2')),
Center(child: Text('Content 3')),
],
),
),
);
What I Have Tried
- I have explored customizing the
TabBar
using theindicator
property, but it only affects the underline or background of the selected tab, not the label itself. - I looked into using
Stack
orPositioned
widgets to overlay a custom label, but I couldn't figure out how to make it dynamically follow the selected tab. - I considered using a
PageView
with custom animations, but it seems like overkill for this use case.
1 Answer
Reset to default 0It's kind of layout like that change it according to your need
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: EdgeStyleTabBar(),
);
}
}
class EdgeStyleTabBar extends StatefulWidget {
@override
_EdgeStyleTabBarState createState() => _EdgeStyleTabBarState();
}
class _EdgeStyleTabBarState extends State<EdgeStyleTabBar> with SingleTickerProviderStateMixin {
late TabController _tabController;
List<String> tabs = ["New Tab", "Another Tab", "Third Tab"];
@override
void initState() {
super.initState();
_tabController = TabController(length: tabs.length, vsync: this);
}
void closeTab(int index) {
if (tabs.length > 1) {
setState(() {
tabs.removeAt(index);
_tabController = TabController(length: tabs.length, vsync: this);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
appBar: AppBar(
backgroundColor: Colors.black87,
title: const Text("Edge-Style Tabs"),
bottom: PreferredSize(
preferredSize: Size.fromHeight(30),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(8),
),
child: TabBar(
controller: _tabController,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(
color: Colors.grey[800],
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.all(4),
labelColor: Colors.white,
unselectedLabelColor: Colors.white70,
tabs: List.generate(tabs.length, (index) {
return Tab(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.tab, size: 16, color: Colors.white), // Tab icon
SizedBox(width: 6),
Text(tabs[index]),
SizedBox(width: 6),
GestureDetector(
onTap: () => closeTab(index),
child: Icon(Icons.close, size: 16, color: Colors.white),
),
],
),
);
}),
),
),
),
),
body: TabBarView(
controller: _tabController,
children: tabs.map((tab) => Center(child: Text(tab, style: TextStyle(color: Colors.white)))).toList(),
),
);
}
}