Related
#override
void initState() {
super.initState();
}
int selectedPage = 0;
void changePage(int index) {
setState(() {
selectedPage = index;
});
}
bottomNavigationBar: BottomNavigationBar(
showUnselectedLabels: true,
currentIndex: selectedPage,
onTap: showPage,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Main',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.category_outlined),
label: 'Category',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.book_online),
label: 'Photos',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.video_call),
label: 'Video',
backgroundColor: Colors.blue),
],
Widget showPage(int selectedPage) {
if (selectedPage == 0) {
return NewsViewDetail(id: '0');
} else if (selectedPage == 1) {
return NewsLoading(text: 'load');
}
return NewsLoading(text: '1');
}
When I tap first or second item on the there is no reaction from UI. It seems onTap does not navigate to different pages.
Could you please help me why this code is not working?
Edit: I think the problem causing Scaffold body. Current Scaffold body is:
body: TabBarView(
children: [
for (final tab in filteredList)
NewsView(
id: tab.id!,
),
],
),
How can I integrate showPage(_selectedIndex), into Scaffold Body without hurt the TabbarView?
here is the TabBarController
return DefaultTabController(
// length: snapshot.data!.data!.length,
length: filteredList.length,
child: Scaffold(
appBar: AppBar(
backgroundColor: (Colors.white),
iconTheme: const IconThemeData(color: Colors.black),
title: Transform.translate(
offset: const Offset(-24.0, 0.0),
child: Image.asset("assets/images/lo.png",
fit: BoxFit.contain, height: 22),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(30.00),
child: ColoredBox(
color: Colors.white,
child: TabBar(
labelColor: Colors.purple[100],
indicatorColor: Colors.purple,
isScrollable: true,
labelPadding:
const EdgeInsets.symmetric(horizontal: 8.0),
tabs: tabs),
),
),
),
```
Check it, it will be helped you to solve your solution
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyNavigationBar(),
);
}
}
class MyNavigationBar extends StatefulWidget {
MyNavigationBar({Key key}) : super(key: key);
#override
_MyNavigationBarState createState() => _MyNavigationBarState();
}
class _MyNavigationBarState extends State<MyNavigationBar>
with TickerProviderStateMixin {
int _selectedIndex = 0;
void changePage(int index) {
setState(() {
_selectedIndex = index;
});
}
Widget showPage(int selectedPage) {
if (selectedPage == 0) {
return Container(
child: Text('Main Page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
);
} else if (selectedPage == 1) {
return Container(
child: Text('Category page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
);
} else if (selectedPage == 2) {
return Container(
child: Text('Photo page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
);
}
return Container(
child: Text('video Page',
style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
);
}
TabController tabController;
#override
void initState() {
// TODO: implement initState
super.initState();
tabController = TabController(initialIndex: 0, length: 2, vsync: this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.0),
//This is for bottom border that is needed
border:
Border(bottom: BorderSide(color: Colors.grey, width: 0.8))),
child: TabBar(
indicatorWeight: 2,
controller: tabController,
indicatorColor: Colors.purple,
labelColor: Colors.purple,
unselectedLabelColor: Color(0xff002540).withOpacity(0.7),
tabs: [
Tab(
child: Text(
"First",
),
),
Tab(
child: Text(
"Second",
),
),
],
),
),
backgroundColor: Colors.green,
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height,
child: TabBarView(controller: tabController, children: [
Container(
child: Center(
child: showPage(_selectedIndex),
),
),
Container(
child: Center(
child: showPage(_selectedIndex),
),
),
]),
),
],
)),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Main',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.category_outlined),
label: 'Category',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.book_online),
label: 'Photos',
backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.video_call),
label: 'Video',
backgroundColor: Colors.blue),
],
type: BottomNavigationBarType.shifting,
currentIndex: _selectedIndex,
selectedItemColor: Colors.black,
iconSize: 40,
onTap: changePage,
elevation: 5),
);
}
}
Output:
main.dart
import 'package:flutter/material.dart';
import 'package:stray_animal_emergencyrescue/signUpPage.dart';
import './commons/commonWidgets.dart';
import 'package:stray_animal_emergencyrescue/loggedIn.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
//title: 'Flutter login UI',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//String showPasswordText = "Show Password";
bool obscurePasswordText = true;
#override
Widget build(BuildContext context) {
final passwordField = TextField(
obscureText: obscurePasswordText,
decoration: InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Password",
//border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: new Icon(Icons.remove_red_eye),
onPressed: () {
setState(() {
this.obscurePasswordText = !obscurePasswordText;
});
},
)),
);
final loginButon = Material(
//elevation: 5.0,
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => LogIn()),
);
},
child: Text('Login', textAlign: TextAlign.center),
),
);
final facebookContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Facebook', textAlign: TextAlign.center),
),
);
final googleContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Google ', textAlign: TextAlign.center),
),
);
final signUpButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormScreen()),
);
//print(MediaQuery.of(context).size.width);
},
child: Text('Sign Up ', textAlign: TextAlign.center),
),
);
return Scaffold(
appBar: AppBar(
title: Text("Animal Emergency App"),
),
body: Center(
child: Container(
//color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//SizedBox(height: 45.0),
getTextFieldWidget(),
SizedBox(height: 15.0),
passwordField,
sizedBoxWidget,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
facebookContinueButton,
SizedBox(width: 5),
googleContinueButton,
SizedBox(width: 5),
loginButon
],
),
/*loginButon,
signUpButton,*/
sizedBoxWidget,
const Divider(
color: Colors.black,
height: 20,
thickness: 1,
indent: 20,
endIndent: 0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
signUpButton
],
),
],
),
),
),
),
);
}
}
loggedIn.dart
import 'package:flutter/material.dart';
import './tabbarviews/emergencyresue/EmergencyHome.dart';
import './tabbarviews/animalcruelty/animalCrueltyHome.dart';
import './tabbarviews/bloodbank/bloodBankHome.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static List<Widget> _widgetOptions = <Widget>[
EmergencyHome(),
AnimalCrueltyHome(),
BloodBankHome()
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First app bar appearing'),
actions: <Widget>[
GestureDetector(
onTap: () {},
child: CircleAvatar(
//child: Text("SC"),
backgroundImage: AssetImage('assets/images/760279.jpg'),
//backgroundImage: ,
),
),
IconButton(
icon: Icon(Icons.more_vert),
color: Colors.white,
onPressed: () {},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new ListTile(title: Text("Primary")),
MyListTile(
"Home",
false,
"Your customized News Feed about people you follow, ongoing rescues, nearby activities, adoptions etc.",
3,
Icons.home,
true,
() {}),
MyListTile(
"News & Media Coverage",
false,
"News about incidents which need immediate action, changing Laws",
3,
Icons.home,
false,
() {}),
MyListTile(
"Report",
true,
"Report cases with evidences anonymously",
3,
Icons.announcement,
false,
() {}),
MyListTile(
"Blood Bank",
true,
"Details to donate blood ",
3,
Icons.medical_services,
false,
() {}),
],
),
),
body: _widgetOptions[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.pets),
label: 'Emergency Rescue',
),
BottomNavigationBarItem(
icon: Icon(Icons.add_alert),
label: 'Report Cruelty',
),
BottomNavigationBarItem(
icon: Icon(Icons.medical_services),
label: 'Blood Bank',
),
/*BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Safe Hands',
backgroundColor: Colors.blue),*/
],
onTap: _onItemTapped,
),
);
}
}
//Safe Hands
class MyListTile extends StatelessWidget {
final String title;
final bool isThreeLine;
final String subtitle;
final int maxLines;
final IconData icon;
final bool selected;
final Function onTap;
MyListTile(this.title, this.isThreeLine, this.subtitle, this.maxLines,
this.icon, this.selected, this.onTap);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
isThreeLine: isThreeLine,
subtitle:
Text(subtitle, maxLines: maxLines, style: TextStyle(fontSize: 12)),
leading: Icon(icon),
selected: selected,
onTap: onTap);
}
}
EmergencyHome.dart
import 'package:flutter/material.dart';
import './finishedAnimalEmergencies.dart';
import './reportAnimalEmergency.dart';
import './ongoingAnimalEmergencies.dart';
class EmergencyHome extends StatefulWidget {
#override
_EmergencyHomeState createState() => _EmergencyHomeState();
}
class _EmergencyHomeState extends State<EmergencyHome> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Second appBar appearing"),
bottom: TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
}
}
The issue I am facing is two appBar, I tried removing appBar from loggedIn.dart but Drawer hamburger icon is not showing, and I cannot remove appBar from emergencyHome.dart as I wont be able to add Tab bar. What is viable solution for this? Please help how to Structure by app and routes to easily manage navigation within app
Remove the appbar from EmergencyHome.dart
this will remove the second app title. But there will be that shadow from the first app bar so put elvation:0
so, this will look like one appbar now your drawer will also work.
you can use flexibleSpace in EmergencyHome.dart
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
flexibleSpace: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
You don't want to make two appbar to get the drawer property. Use DefaultTabController then inside that you can use scaffold.so, you can have drawer: Drawer() inside that you can also get a appbar with it with TabBar as it's bottom.
This is most suitable for you according to your use case.
i will put the full code below so you can copy it.
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
drawer: Drawer(),
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(
text: "report",
),
Tab(text: "ongoing"),
Tab(text: "completed"),
],
),
title: const Text('Tabs Demo'),
),
body: const TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
),
);
}
}
OUTPUT
Here is my main class with pageview
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
String strTotal = '0';
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
strTotal,
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
I am implementing pageview in my Flutter application. I want to update the amount in main class whenever user entered value in TextFormField from pageview.
Here AddItems is the page added with pageview and EditInvoice is the main class.
I am new to Flutter application development.
You can use the Provider Pattern:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderTest with ChangeNotifier {
String amount = '';
void updateAmount(String newAmount) {
amount = newAmount;
notifyListeners();
}
}
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context);
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
providerTest.amount.toString(),
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context, listen: false);
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
onChanged: (value) {
providerTest.updateAmount(value);
},
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
And at main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ProviderTest(),
child: MaterialApp(
home: EditInvoice(),
),
);
}
}
More info about Provider Pattern here:
Provider Pattern
you can give callback to from child widget to parent widget to update data,
you can use inherited widget or provider
I was wondering how can I show/hide a FloatingActionButton in a TabBarView.
So for example in my first tab, I wanna a FloatingActionButton, but in the second tab I wanna hide it.
So in my case my code is:
class Notifications extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
backgroundColor: kPink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: kBigSeparation),
child: DefaultTabController(
length: 2,
initialIndex: 0,
child: Padding(
padding: kPaddingTabBar,
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(kTinySeparation),
decoration: BoxDecoration(
color: kLightGrey,
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
child: TabBar(
tabs: <Tab>[
Tab(
text: AppLocalizations.of(context)
.translate('messages'),
),
Tab(
text: AppLocalizations.of(context)
.translate('notifications'),
)
],
unselectedLabelColor: Colors.black54,
labelColor: Colors.black,
unselectedLabelStyle: kBoldText,
labelStyle: kBoldText,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
),
),
const SizedBox(height: kMediumSeparation),
Expanded(
child: TabBarView(children: [
MessagesTab(),
NotificationsTab(),
]),
),
],
),
),
),
),
),
);
}
}
You can copy paste run full code below
Step 1 : You need to use TabController
Step 2 : Show/hide floatingActionButton based on tabIndex
code snippet
TabBar(
controller: _tabController,
tabs: <Tab>[
...
floatingActionButton: _tabController.index == 0
? FloatingActionButton(
backgroundColor: Colors.pink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
)
: Container(),
working demo
full code
import 'package:flutter/material.dart';
class Notifications extends StatefulWidget {
#override
_NotificationsState createState() => _NotificationsState();
}
class _NotificationsState extends State<Notifications>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this, initialIndex: 0);
_tabController.addListener(_switchTabIndex);
}
void _switchTabIndex() {
print(_tabController.index);
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: _tabController.index == 0
? FloatingActionButton(
backgroundColor: Colors.pink,
child: Icon(Icons.add),
onPressed: () => print(Localizations.localeOf(context)),
)
: Container(),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 2.0),
child: Padding(
padding: EdgeInsets.all(1.0),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
child: TabBar(
controller: _tabController,
tabs: <Tab>[
Tab(
text: 'messages',
),
Tab(
text: 'notifications',
)
],
unselectedLabelColor: Colors.black54,
labelColor: Colors.black,
//unselectedLabelStyle: kBoldText,
//labelStyle: kBoldText,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
),
),
const SizedBox(height: 10),
Expanded(
child: TabBarView(controller: _tabController, children: [
MessagesTab(),
NotificationsTab(),
]),
),
],
),
),
),
),
);
}
}
class MessagesTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("MessagesTab");
}
}
class NotificationsTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("NotificationsTab");
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Notifications(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
I have a Scaffold, within it I have a TabBar, TabBarView and a TextField.
The TabBar has 3 tabs (e.g. tabs A, B and C), the TabBarView has 3 views and this TextField is at the last tab (tab C).
Everything is working, but whenever I put the focus on the TextField to type something, the TabBar is changed from tab C to tab A. Very annoying. This should not happen. The TabBarView remains unchanged.
I created the controller in the initState. like this:
#override
void initState() {
super.initState();
widget._tabBarController =
new TabController(length: 3, vsync: this);
}
Any idea why it happens?
Code:
class AtendimentoOrtoWidget extends StatefulWidget {
TabController _tabBarController;
#override
_AtendimentoOrtoWidgetState createState() => _AtendimentoOrtoWidgetState();
}
class _AtendimentoOrtoWidgetState extends State<AtendimentoOrtoWidget>
with SingleTickerProviderStateMixin {
#override
void initState() {
super.initState();
widget._tabBarController =
new TabController(length: 3, vsync: this);
}
#override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: new DefaultTabController(
length: 3,
child: new Scaffold(
resizeToAvoidBottomPadding: false,
appBar: new AppBar(
toolbarOpacity: 0.5,
automaticallyImplyLeading: true,
backgroundColor: Colors.white,
elevation: 2.0,
title: new TabBar(
controller: widget._tabBarController,
unselectedLabelColor: Colors.black,
indicatorColor: Colors.black,
labelColor: Colors.black,
// indicatorWeight: 0.0,
isScrollable: true,
labelStyle: new TextStyle(
fontSize: 16.0,
fontFamily: 'Caecilia',
fontWeight: FontWeight.w700),
tabs: <Widget>[
new Tab(
text: "TAB A",
),
new Tab(
text: "TAB B",
),
new Tab(
text: "TAB C",
)
],
),
),
backgroundColor: Colors.white,
body: new TabBarView(
controller: widget._tabBarController,
children: <Widget>[
new Container(),
new Container(),
new TextField()
],
))));
}
}
I tried it. Check the below code. If you still facing the same issue then share your implementation.
import 'package:flutter/material.dart';
class TabScreen extends StatefulWidget {
#override
_TabScreenState createState() => _TabScreenState();
}
class _TabScreenState extends State<TabScreen> with SingleTickerProviderStateMixin {
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalObjectKey<ScaffoldState>('TabScreen');
TabController tabController;
#override
void initState() {
super.initState();
tabController = new TabController(length: 3, vsync: this);
}
#override
void dispose() {
super.dispose();
tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("Tab Demo"),
),
backgroundColor: Colors.white,
body: Column(
children: <Widget>[
TabBar(
controller: tabController,
tabs: <Widget>[
Tab(
child: Container(
child: new Text(
'A',
style: TextStyle(color: Colors.black),
),
),
),
Tab(
child: Container(
child: Text(
'B',
style: TextStyle(color: Colors.black),
),
),
),
Tab(
child: Container(
child: Text(
'C',
style: TextStyle(color: Colors.black),
),
),
)
],
),
Flexible(
child: TabBarView(
controller: tabController,
children: <Widget>[
Placeholder(),
Placeholder(),
ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(labelText: "Name"),
),
),
],
),
],
))
],
),
);
}
}