in-app bottom bar I want to add an underline for specifically selected icon. Is there any way for BottomNavigationBarItem or do I need to use a different widget?
class CustomAppBottomBar extends StatefulWidget {
const CustomAppBottomBar({Key? key}) : super(key: key);
#override
State<CustomAppBottomBar> createState() => _CustomAppBottomBarState();
}
class _CustomAppBottomBarState extends State<CustomAppBottomBar> {
int _currentIndex = 0;
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
showUnselectedLabels: true,
showSelectedLabels: true,
type: BottomNavigationBarType.fixed,
selectedItemColor: RJDriverColors.primary,
unselectedItemColor: RJDriverColors.bottomBarSecondary,
selectedFontSize: 12,
unselectedFontSize: 12,
currentIndex: _currentIndex,
onTap: (value) {
setState(() {
_currentIndex = value;
});
},
Try using 'TabBar' and use onTap as onChanged since they are both of type ValueChanged<int>
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late final TabController controller;
#override
void initState() {
controller = TabController(length: 4, vsync: this);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
bottomNavigationBar: TabBar(
controller: controller,
unselectedLabelColor: Colors.grey,
labelColor: Colors.blue,
onTap: (index) {},
tabs: const [
Tab(icon: Icon(Icons.menu_rounded)),
Tab(icon: Icon(Icons.piano)),
Tab(icon: Icon(Icons.car_rental_rounded)),
Tab(icon: Icon(Icons.settings_rounded)),
],
),
);
}
}
Using Tabbar with DefaultTabController you can get your desired result. I'm sharing a reference code you can customize it as per your need.
return DefaultTabController(
length: 4,
child: Scaffold(
body: TabBarView(
children: [
Center(
child: Text("1st Screen"),
),
Center(
child: Text("2nd Screen"),
),
Center(
child: Text("3rd Screen"),
),
Center(
child: Text("4th Screen"),
),
],
),
bottomNavigationBar: TabBar(
labelColor: Colors.red,
tabs: [
Tab(child: Icon(Icons.more_vert_sharp),),
Tab(child: Icon(Icons.local_play_sharp),),
Tab(child: Icon(Icons.directions_car),),
Tab(child: Icon(Icons.home),),
]),
),
);
Related
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'package:whatsapp_clone/chatScreen.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin{
late TabController _tabcontroller;
#override
void initState(){
super.initState();
_tabcontroller=TabController(length: 4, vsync: this, initialIndex: 1);
}
#override
void dispose(){
_tabcontroller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xff075E54),
title: const Text('Whatsapp Clone'),
actions: [IconButton(onPressed: (){}, icon: const Icon(Icons.search)),
PopupMenuButton(onSelected: (value){print(value);},
itemBuilder: (BuildContext context){return [
PopupMenuItem(child: Text('New Group'),value: 'New Group'),
PopupMenuItem(child: Text('New Broadcast'),value: 'New Broadcast'),
PopupMenuItem(child: Text('Whatsapp web'),value: 'Whatsapp web'),
PopupMenuItem(child: Text('Starred messages'),value: 'Starred messages'),
PopupMenuItem(child: Text('Settings'),value: 'Settings')
];
}
),
],
bottom: TabBar(
controller: _tabcontroller,
tabs: const [
Tab(icon: Icon(Icons.camera_alt)),
Tab(text:'CHAT'),
Tab(text: 'STATUS'),
Tab(text: 'CALLS')
],
indicatorColor: Colors.white,
),
),
body: TabBarView(controller: _tabcontroller,
children: const [
Text('camera'),
ChatPage(),
Text('status'),
Text('calls')
],
),
);
}
}
I want to show the chatscreen which is at 1 index, when opening the app, and i have given the initial index to 1 also, but whenever i open my app, although the chat tabbar was selected but the content was showing from first screen. how can i solve this problem
Any code example is welcome, thanks!
TabBar does this animation by default...
You can look at its source code from the IDE or here to see how it's done.
This page has documentation, video, and examples if you want to use it directly in your app.
Here is the code sample.
You can use TabBar widget.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this, initialIndex: 0);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text("Demo"),
bottom: TabBar(
controller: _tabController,
indicatorColor: Colors.white,
tabs: [
Tab(
text: "Wellbeing",
),
Tab(
text: "Cleaning",
),
Tab(
text: "Self-care",
),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
Center(child: Text("Wellbeing")),
Center(child: Text("Cleaning")),
Center(child: Text("Self-care")),
],
),
);
}
}
I'm trying to mount BottomNavigationBar to TabBarView. How to set the index of TabBarView so I can display 2nd item (search page)? should I use Ontap and switch case? still how to set the index?
body: SafeArea(
// child: (pages[currentIndex1]),
child: TabBarView(
children: <Widget>[
Home(),
Search(),
].toList(),
// controller: ,
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentIndex1,
type: BottomNavigationBarType.shifting,
showUnselectedLabels: false,
showSelectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
backgroundColor: Colors.blue),
],
you need to provide TabController on TabBarView, then you can switch tabItems using this controller.
you can check this example
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Text("home"),
);
}
}
class Search extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Text("Search"),
);
}
}
class NavTest extends StatefulWidget {
NavTest({Key? key}) : super(key: key);
#override
_NavTestState createState() => _NavTestState();
}
class _NavTestState extends State<NavTest> with SingleTickerProviderStateMixin {
final widgets = [
Home(),
Search(),
];
int currentIndex1 = 0;
late TabController controller;
#override
void initState() {
super.initState();
controller = TabController(length: widgets.length, vsync: this);
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
// child: (pages[currentIndex1]),
child: TabBarView(
children: widgets,
controller: controller,
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentIndex1,
type: BottomNavigationBarType.shifting,
showUnselectedLabels: false,
showSelectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.blue,
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
backgroundColor: Colors.blue,
),
],
onTap: (value) {
setState(() {
// currentIndex1 = value;
controller.index = value;
});
},
),
);
}
}
I use tabBar,
I want to change appBar title when a tab is selected, but I get a error.
code that I get error.
Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.clear, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
title: TabBarView(
children: [Text("Album"), Text("사진"), Text("동영상")],
),
backgroundColor: Colors.white,
),
bottomNavigationBar: TabBar(
tabs: [
Tab(text: "앨범"),
Tab(text: "사진"),
Tab(text: "동영상"),
],
labelColor: Colors.black,
indicatorColor: Colors.black,
unselectedLabelColor: Colors.black26,
),
),
If I get rid of appBar title, I don't get error.
How to solve this problem?
You can add TabController and add a listener so that whenever you are switching the Tab, the setState() kicks in and the appBar title change.
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
TabController _controller;
final List<Tab> _tab = [new Tab(text: "First",), Tab(text: "Second",), Tab(text: "Third",)];
var _currentTab;
#override
void initState() {
// TODO: implement initState
super.initState();
_controller = new TabController(length: _tab.length, vsync: this);
_currentTab = _tab[0];
_controller.addListener(_selectedTab);
}
void _selectedTab() {
setState(() {
_currentTab = _tab[_controller.index];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text(_currentTab.text),
),
bottomNavigationBar: TabBar(controller: _controller,tabs: _tab),
);
}
}
How can I disable TabView animation when Tab in TabBar clicked ?
I added
physics: NeverScrollableScrollPhysics()
for TabView but that doesn't apply for TabBar.
I'm using DefaultTabController.
Based on a very good answer on github about this issue, which achieves something similar to what your looking for (but with a bottomNavigationBar) here I share with you another workaround. It consists of combining a DefaultTabController with a PageView, a PageController and a simple index. Try this out.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tabs with no animation',
theme: ThemeData.dark(),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
PageController _pageController;
final int currentTab = 0;
#override
void initState() {
// TODO: implement initState
_pageController = PageController(initialPage: currentTab);
super.initState();
}
final List<Tab> myTabs = <Tab>[
Tab(text: 'One'),
Tab(
text: 'Two',
),
];
var tabs = [
TabOne(),
TabTwo(),
];
#override
Widget build(BuildContext context) {
var pageView = PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: tabs,
);
return DefaultTabController(
length: myTabs.length,
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
automaticallyImplyLeading: false,
title: Center(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.grey.shade800,
),
width: 200,
height: 50,
child: TabBar(
onTap: (index) {
_pageController.jumpToPage(index);
},
unselectedLabelColor: Colors.white,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.black),
tabs: myTabs,
),
),
),
),
body: pageView),
);
}
}
class TabOne extends StatelessWidget {
const TabOne({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text('Tab one')),
);
}
}
class TabTwo extends StatelessWidget {
const TabTwo({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text('Tab two')),
);
}
}
Doing so, you have a something identical to a TabBarView but without animation.
I don't think there's a way to disable the transition animation on TabBarView. As a workaround, you can use a Container that'll return different pages depending on the tab selected.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
#override
void initState() {
super.initState();
tabController = TabController(length: 4, vsync: this);
}
var _homeScaffoldKey = Key("Scaffold Key");
var tabController;
var currentPage = 0;
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _homeScaffoldKey,
body: _getCustomContainer(),
bottomNavigationBar: new Material(
color: Colors.blue,
child: new TabBar(
isScrollable: true,
indicatorColor: Color.fromRGBO(255, 25, 255, 0.0),
controller: tabController,
onTap: (value) {
setState(() {
currentPage = value;
});
},
tabs: <Widget>[
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
new Tab(
icon: new Icon(Icons.accessibility),
),
],
),
),
);
}
_getCustomContainer() {
switch (currentPage) {
case 0:
return page1();
case 1:
return page2();
case 2:
return page3();
case 3:
return page4();
}
}
page1() => Container(
color: Colors.redAccent,
child: Center(
child: Text("Page 1"),
),
);
page2() => Container(
color: Colors.greenAccent,
child: Center(
child: Text("Page 2"),
),
);
page3() => Container(
color: Colors.blueAccent,
child: Center(
child: Text("Page 3"),
),
);
page4() => Container(
color: Colors.yellowAccent,
child: Center(
child: Text("Page 4"),
),
);
}
Demo
Seems like this can be achieved using DefaultTabController easily as of 2022.
Here is my solution to this:
class _TabPageState extends State<TabPage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
// when initializing the `TabController` set `animationDuration` as `zero`.
_tabController =
TabController(length: 3, vsync: this, animationDuration: Duration.zero);
}
#override
Widget build(BuildContext context) {
return Container(
color: ColorPalette.white,
child: SafeArea(
top: false,
child: DefaultTabController(
length: 3,
child: Builder(builder: (context) {
return Scaffold(
bottomNavigationBar: TabBar(
controller: _tabController, // set the tab controller of your `TabBar`
enableFeedback: false,
onTap: (index) {
setState(() {});
},
indicatorColor: Colors.transparent,
tabs: [
TabItem(
selectedIndex: _tabController.index,
index: 0,
assetName: Assets.tabHome),
TabItem(
selectedIndex: _tabController.index,
index: 1,
assetName: Assets.tabCare),
TabItem(
selectedIndex: _tabController.index,
index: 2,
assetName: Assets.tabProfile),
],
),
body: Center(
child: TabBarView(
controller: _tabController, // set the controller of your `TabBarView`
physics: const NeverScrollableScrollPhysics(),
children: const [
ParentHomePage(),
ParentCarePage(),
ParentAccountPage()
],
),
),
);
}),
),
),
);
}
}
You Can Fix It by Go to MaterialApp and type
theme:new ThemeData(
splashColor:Colors.blue,
highlightColor: Colors.blue
)
what it mean if your tab background color blue you will change splashColor and highlightColor to blue that mean the animation doesn't disabled but it doesn't appear because the animation splashcolor and highlight will be blue such as Tab Background , I Hope I Help You