Flutter : How do I make BottomAppBar of buttomNavigationBar appear in every screens I have? - flutter

I'm using BottomAppBar instead of BottomNavigationBar widget. And I want to make this bar appear in every screen I have. Again, I don't want to use BottomNavigationBar.
bottomNavigationBar: BottomAppBar(
child: Container(
height: 60,
width: width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// Home
MaterialButton(
onPressed: () {
setState(() {
currentScreen = HomeScreenWrapper();
currentTab = 0;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.home,
color: currentTab == 0 ? primaryColor : Colors.grey,
),
Text(
AppLocalizations.of(context).translate('HOME'),
style: TextStyle(
color: currentTab == 0 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
// Dashboard
MaterialButton(
onPressed: () {
setState(() {
currentScreen = PointScreenWrapper();
currentTab = 2;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
'assets/images/dashboard.svg',
color: currentTab == 2 ? primaryColor : null,
),
// Icon(
// // Icons.show_chart,
// Icons.dashboard,
// //Icons.crop_square,
// color: currentTab == 2 ? primaryColor : Colors.grey,
// ),
Text(
AppLocalizations.of(context).translate('DASHBOARD'),
style: TextStyle(
color: currentTab == 2 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
// //Make a dummy space between
SizedBox(
width: width / 5,
),
// Score
MaterialButton(
onPressed: () {
setState(() {
currentScreen = ChallengeScreen();
currentTab = 1;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
'assets/images/ranking.svg',
color: currentTab == 1 ? primaryColor : Colors.grey,
),
// Icon(
// Icons.star,
// color: currentTab == 1 ? primaryColor : Colors.grey,
// size: 30,
// ),
Text(
AppLocalizations.of(context).translate('RATING'),
style: TextStyle(
color: currentTab == 1 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
//
MaterialButton(
onPressed: () {
setState(() {
currentScreen = ProfileWrapper();
currentTab = 3;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
'assets/images/profile.svg',
color: currentTab == 3 ? primaryColor : Colors.grey,
),
// Icon(
// Icons.settings,
// color: currentTab == 3 ? primaryColor : Colors.grey,
// ),
Text(
AppLocalizations.of(context).translate('PROFILE'),
style: TextStyle(
color: currentTab == 3 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
],
),
),
shape: CircularNotchedRectangle(),
),
How do I do that? Please give me some pointer regarding this issue. I am looking forward to hearing from anyone of you. Thank you in advance...

You can copy paste run full code below
You can use PageView when click on MaterialButton call bottomTapped with index
code snippet
Widget buildPageView() {
return PageView(
controller: pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
Red(),
Blue(),
Yellow(),
Green(),
],
);
}
#override
void initState() {
super.initState();
}
void pageChanged(int index) {
setState(() {
currentTab = index;
});
}
void bottomTapped(int index) {
setState(() {
currentTab = index;
pageController.animateToPage(index,
duration: Duration(milliseconds: 500), curve: Curves.ease);
});
}
working demo
full code
import 'package:flutter/material.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 Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
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> {
double width;
Color primaryColor = Colors.blue;
int currentTab = 0;
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
Red(),
Blue(),
Yellow(),
Green(),
],
);
}
#override
void initState() {
super.initState();
}
void pageChanged(int index) {
setState(() {
currentTab = index;
});
}
void bottomTapped(int index) {
setState(() {
currentTab = index;
pageController.animateToPage(index,
duration: Duration(milliseconds: 500), curve: Curves.ease);
});
}
#override
Widget build(BuildContext context) {
width = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: buildPageView(),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 60,
width: width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// Home
MaterialButton(
onPressed: () {
bottomTapped(0);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.home,
color: currentTab == 0 ? primaryColor : Colors.grey,
),
Text(
'HOME',
style: TextStyle(
color: currentTab == 0 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
// Dashboard
MaterialButton(
onPressed: () {
bottomTapped(1);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network(
'https://picsum.photos/20/20?image=9',
color: currentTab == 1 ? primaryColor : null,
),
// Icon(
// // Icons.show_chart,
// Icons.dashboard,
// //Icons.crop_square,
// color: currentTab == 2 ? primaryColor : Colors.grey,
// ),
Text(
'DASHBOARD',
style: TextStyle(
color: currentTab == 1 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
// //Make a dummy space between
SizedBox(
width: width / 10,
),
// Score
MaterialButton(
onPressed: () {
bottomTapped(2);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network(
'https://picsum.photos/20/20?image=9',
color: currentTab == 2 ? primaryColor : Colors.grey,
),
// Icon(
// Icons.star,
// color: currentTab == 1 ? primaryColor : Colors.grey,
// size: 30,
// ),
Text(
'RATING',
style: TextStyle(
color: currentTab == 2 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
//
MaterialButton(
onPressed: () {
bottomTapped(3);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network(
'https://picsum.photos/20/20?image=9',
color: currentTab == 3 ? primaryColor : Colors.grey,
),
// Icon(
// Icons.settings,
// color: currentTab == 3 ? primaryColor : Colors.grey,
// ),
Text(
'PROFILE',
style: TextStyle(
color: currentTab == 3 ? primaryColor : Colors.grey,
fontSize: 10,
),
),
],
),
minWidth: width / 5,
),
],
),
),
shape: CircularNotchedRectangle(),
),
);
}
}
class Red extends StatefulWidget {
#override
_RedState createState() => _RedState();
}
class _RedState extends State<Red> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
);
}
}
class Blue extends StatefulWidget {
#override
_BlueState createState() => _BlueState();
}
class _BlueState extends State<Blue> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blueAccent,
);
}
}
class Yellow extends StatefulWidget {
#override
_YellowState createState() => _YellowState();
}
class _YellowState extends State<Yellow> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellowAccent,
);
}
}
class Green extends StatefulWidget {
#override
_GreenState createState() => _GreenState();
}
class _GreenState extends State<Green> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.greenAccent,
);
}
}

#Eren is right you cannot use same widget on every screen its against the flutter physics because its the scope of Scaffold field but you can use Common bottom-sheet class for every Page and pass that page context.

In flutter a good practice would be to create a widget and use that in every scaffold. Here is an example code I am using in my application
import 'package:flutter/material.dart';
class AppBottomNavigationBar extends StatelessWidget {
final int selectedIndex;
const AppBottomNavigationBar({
Key key,
#required this.selectedIndex,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.mail_outline),
title: Text('Messages'),
),
BottomNavigationBarItem(
icon: Icon(Icons.explore),
title: Text('Explore'),
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
title: Text('Profile'),
),
],
currentIndex: selectedIndex,
onTap: (int index) {
if (selectedIndex == index) {
return;
}
if (index == 0) {
Navigator.of(context).pushReplacementNamed('/home');
} else if (index == 1) {
Navigator.of(context).pushReplacementNamed('/messages');
} else if (index == 2) {
Navigator.of(context).pushReplacementNamed('/explore');
} else if (index == 3) {
Navigator.of(context).pushReplacementNamed('/profile');
}
},
);
}
}

Related

Null Check Operator Used On a Null Value? GetStorage in flutter give me this error

I am using GetStorage package in Flutter to check if the current user is login or not but it gives the error.
For example, when a user does not login it shows the null error and when I login it then it is filn, check if you can.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:mobihub_2/Screens/main_login.dart';
import 'package:mobihub_2/Screens/navigationscreens.dart/add.dart';
import 'navigationscreens.dart/adds.dart';
import 'navigationscreens.dart/chat.dart';
import 'navigationscreens.dart/home2.dart';
import 'navigationscreens.dart/person.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
// ignore: library_private_types_in_public_api
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final auth = FirebaseAuth.instance;
int currentTab = 0;
final List<Widget> screens = const [
Home2(),
Chat(),
Youradds(),
Account(),
];
final PageStorageBucket bucket = PageStorageBucket();
Widget currentScreen = const Home2();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade100,
body: PageStorage(
bucket: bucket,
child: currentScreen,
),
floatingActionButton: FloatingActionButton(
backgroundColor: const Color(0xFFFFDC3D),
elevation: 2.5,
onPressed: () {
if(FirebaseAuth.instance.currentUser != null){
Navigator.push(context,
MaterialPageRoute(builder: (context) => const AddItems()));
}else{
Navigator.push(context,
MaterialPageRoute(builder: (context) => MainLogin()));
}
},
child: const Icon(
Icons.add,
color: Colors.black,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
color: Colors.white,
shape: const CircularNotchedRectangle(),
notchMargin: 10,
child: SizedBox(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MaterialButton(
highlightElevation: 0.0,
highlightColor: Colors.white,
hoverColor: Colors.white,
hoverElevation: 0.0,
minWidth: 40,
onPressed: () {
setState(() {
currentScreen = const Home2();
currentTab = 0;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.home,
color: currentTab == 0
? const Color(0xFFFFDC3D)
: Colors.black,
size: 25,
),
Text(
'',
style: TextStyle(
color: currentTab == 0
? const Color(0xFFFFDC3D)
: Colors.white),
)
],
),
),
MaterialButton(
highlightElevation: 0.0,
highlightColor: Colors.white,
hoverColor: Colors.white,
hoverElevation: 0.0,
minWidth: 40,
onPressed: () {
setState(() {
if(FirebaseAuth.instance.currentUser != null){
currentScreen = const Chat();
currentTab = 1;
}else{
Navigator.push(context,
MaterialPageRoute(builder: (context) => MainLogin()));
}
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.chat,
color: currentTab == 1
? const Color(0xFFFFDC3D)
: Colors.black,
size: 25,
),
Text(
'',
style: TextStyle(
color: currentTab == 1
? const Color(0xFFFFDC3D)
: Colors.white),
)
],
),
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MaterialButton(
highlightElevation: 0.0,
highlightColor: Colors.white,
hoverColor: Colors.white,
hoverElevation: 0.0,
minWidth: 40,
onPressed: () {
setState(() {
if(FirebaseAuth.instance.currentUser != null){
currentScreen = const Youradds();
currentTab = 2;
}else{
Navigator.push(context,
MaterialPageRoute(builder: (context) => MainLogin()));
}
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.favorite,
color: currentTab == 2
? const Color(0xFFFFDC3D)
: Colors.black,
size: 25,
),
Text(
'',
style: TextStyle(
color: currentTab == 2
? const Color(0xFFFFDC3D)
: Colors.white),
)
],
),
),
MaterialButton(
highlightElevation: 0.0,
highlightColor: Colors.white,
hoverColor: Colors.white,
hoverElevation: 0.0,
autofocus: false,
minWidth: 40,
onPressed: () {
setState(() {
if(FirebaseAuth.instance.currentUser != null){
currentScreen = Account();
currentTab = 3;
}else{
Navigator.push(context,
MaterialPageRoute(builder: (context) => MainLogin()));
}
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.person,
color: currentTab == 3
? const Color(0xFFFFDC3D)
: Colors.black,
size: 25,
),
Text(
'',
style: TextStyle(
color: currentTab == 3
? const Color(0xFFFFDC3D)
: Colors.white),
)
],
),
)
],
)
],
),
),
),
);
}
}
I need help if anyone expert in Flutter checks my code and gives me the right answer. Thank you in advance.

flutter How to change text colour dynamically on tap?

I want to make a program where 2 options will be written on text and I want to make my program whenever the user choose one of those option the other option will be greyed out.
I've tried using text button, but it's still a bit wacky for my taste.
Try this:
class _MyHomePageState extends State<MyHomePage> {
int _selectIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: [
InkWell(
onTap: () {
setState(() {
_selectIndex = 0;
});
},
child: Text(
'Celcius',
style: TextStyle(
color: _selectIndex == 0 ? Colors.black : Colors.grey,
),
),
),
const Text(' | '),
InkWell(
onTap: () {
setState(() {
_selectIndex = 1;
});
},
child: Text(
'Fashrenheit',
style: TextStyle(
color: _selectIndex == 1 ? Colors.black : Colors.grey,
),
),
),
],
),
),
);
}
}
You can use stateful widget to change states when button is pressed.
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => _HomePageState();
}
enum Temperature { celcius, fahrenheit }
class _HomePageState extends State<HomePage> {
late Temperature _currentScale;
late num _currentTemp;
#override
void initState() {
super.initState();
_currentScale = Temperature.celcius;
_currentTemp = 24; //multiply by 1.8 add 32 C->F
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_currentScale == Temperature.celcius
? '$_currentTemp°C'
: '${_currentTemp * 1.8 + 32}°F',
style: Theme.of(context).textTheme.headline2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
child: Text(
'Celcius',
style: TextStyle(
color: _currentScale == Temperature.celcius
? Colors.red
: Colors.grey),
),
onPressed: () =>
setState(() => _currentScale = Temperature.celcius)),
const SizedBox(
width: 10,
),
TextButton(
child: Text('Fahrenheit',
style: TextStyle(
color: _currentScale == Temperature.fahrenheit
? Colors.red
: Colors.grey)),
onPressed: () => setState(
() => _currentScale = Temperature.fahrenheit))
],
)
],
),
),
),
);
}
}
You can try ToggleButton instead of TextButton
ToggleButton
You can try this one. I hope this is useful to you !
class MyHomePage extends StatelessWidget {
final RxInt _selectIndex = 0.obs;
MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Obx(
() => Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"25",
style: TextStyle(
fontSize: 30,
color: _selectIndex.value == 0 ? Colors.grey : Colors.black,
),
),
const SizedBox(
height: 10,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
_selectIndex.value = 0;
},
child: Text(
'Celcius',
style: TextStyle(
color: _selectIndex.value == 0 ? Colors.black : Colors.grey,
),
),
),
const Text(' | '),
InkWell(
onTap: () {
_selectIndex.value = 1;
},
child: Text(
'Fashrenheit',
style: TextStyle(
color: _selectIndex.value == 1 ? Colors.black : Colors.grey,
),
),
),
],
),
],
),
),
),
);
}
}

Flutter change AppBottomNavigation body by tapping on button on another state

I have an AppBottomNavigation for five different states. In the first state, HomeScreen, I have a button. By tapping on this button, the state is to be changed to the third element of the AppBottomNavigation.How exactly can I implement this? I have already tried several times to call the method "bottomTapped" with index 2 via ScannderDummy. Unfortunately without success.
app_bottom_navigation.dart
class AppBottomNavigation extends StatefulWidget {
#override
_AppBottomNavigationState createState() => _AppBottomNavigationState();
}
class _AppBottomNavigationState extends State<AppBottomNavigation> {
int _selectedIndex = 0;
List<dynamic> menuItems = [
...
];
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
onPageChanged: (index) {
pageChanged(index);
},
children: <Widget>[
HomeScreen(),
CategoryScreen(),
ScannerScreen(),
CategoryScreen(),
ProfileSettingsScreen(),
],
);
}
pageChanged(int index) {
setState(() {
_selectedIndex = index;
});
}
bottomTapped(int index) {
setState(() {
_selectedIndex = index;
pageController.jumpToPage(index);
});
}
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark));
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.white,
showUnselectedLabels: true,
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed,
selectedLabelStyle: GoogleFonts.outfit(
textStyle:
TextStyle(height: 1.5, fontSize: 10, fontWeight: FontWeight.bold),
),
unselectedLabelStyle: GoogleFonts.outfit(
textStyle: TextStyle(
height: 1.5,
fontSize: 10,
),
),
items: menuItems.map((i) {
return BottomNavigationBarItem(
icon: (i['icon']),
activeIcon: (i['icon']),
label: i['label'],
);
}).toList(),
currentIndex: _selectedIndex,
selectedItemColor: primaryColor,
onTap: (index) {
bottomTapped(index);
},
),
body: buildPageView(),
);
}
}
scanner_dummy.dart (Element from home_screen.dart)
class ScannerDummy extends StatelessWidget {
final AppBottomNavigation bn = new AppBottomNavigation();
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
},
child: Container(
margin:
EdgeInsets.only(top: 6, bottom: 28.0, left: 28.0, right: 28.0),
padding: EdgeInsets.symmetric(
horizontal: 16.0,
),
height: 125,
width: double.infinity,
decoration: BoxDecoration(
color: darkGrey,
borderRadius: BorderRadius.all(Radius.circular(15)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
LineIcons.retroCamera,
color: Colors.white,
size: 35.0,
),
Text(
'Artikel scannen & verkaufen',
textAlign: TextAlign.right,
style: GoogleFonts.outfit(
textStyle: TextStyle(
color: Colors.white,
fontSize: 16,
height: 2,
)),
),
],
)),
);
}
}
Thank you very much for your help.
Play with this widget. I am using callback method.
class ItemB extends StatefulWidget {
final VoidCallback callback;
ItemB({Key? key, required this.callback}) : super(key: key);
#override
State<ItemB> createState() => _ItemBState();
}
class _ItemBState extends State<ItemB> {
#override
Widget build(BuildContext context) {
return Column(
children: [
Text("B"),
ElevatedButton(
onPressed: widget.callback,
child: Text("switch Tab"),
),
],
);
}
}
class HomeWidgetX extends StatefulWidget {
const HomeWidgetX({Key? key}) : super(key: key);
#override
State<HomeWidgetX> createState() => _HomeWidgetXState();
}
class _HomeWidgetXState extends State<HomeWidgetX> {
int currentTab = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: [
Text("A"),
ItemB(
callback: () {
setState(() {
currentTab = 0;
});
},
)
][currentTab]),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentTab,
onTap: (value) {
currentTab = value;
setState(() {});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.abc),
label: "",
),
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
label: "",
),
],
),
);
}
}

Is there a way to control the leading element behavior of NavigationRail in Flutter?

Flutter recently launched their v1.17 (latest stable release) and in that they have included a new widget "Navigation Rail".
Though this widget is still in its early stages(and I'm expecting a bit more additional properties like padding for NavigationRailDestination) it gives a whole new perspective to orthodox navigation.
So while Implementing this widget I've encountered a problem to which I'm searching for a workaround maybe a solution(if anybody has one!).
And that problem is when we try to implement the toggle between leading elements and the navigationRailDestinations using setState(){...} , the toggling happens only once and not for the whole lifecycle of the app.
I'm struggling to implement it please help!.
Here's the code snippet:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int _selectedIndex = 0, menuColor = 0xFfFCCFA8;
final padding = 8.0;
//bool leadingProfileFlag = false, leadingSettingsFlag = false, contentFlag = true;
String profilePic, contentView = "dash";
getView(String contentView,int selectedIndex,int menuColor) {
switch (contentView) {
case 'MenuRails.selectedIndex':
return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
case '' : return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
case '2' : return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
case 'settings': return Expanded(child: Container());
case 'profile' : return Expanded(child: Container());
default: return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xff28292E),
resizeToAvoidBottomPadding: false,
body: Row(
children: <Widget>[
NavigationRail(
leading: Column(
children: <Widget>[
SizedBox(
height: 38,
),
InkWell(
splashColor: Color(0xffFCCFA8),
onTap: () {
setState(() {
contentView = 'profile';
});
},
child: Center(
child: CircleAvatar(
radius: 16,
backgroundImage: profilePic != null
? NetworkImage(profilePic)
: AssetImage('assets/dummy_profile.png'),
),
),
),
SizedBox(
height: 88,
),
RotatedBox(
quarterTurns: -1,
child: GestureDetector(
onTap: (){
setState(() {
contentView = 'settings';
});
},
child: IconButton(
icon: Icon(Icons.tune),
color: Color(0xffFCCFA8),
onPressed: () {
setState(() {});
},
),
),
)
],
),
backgroundColor: Color(0xff2D3035),
groupAlignment: 1.0,
minWidth: MediaQuery.of(context).size.width * 0.07,
elevation: 8.0,
minExtendedWidth: MediaQuery.of(context).size.width * 0.4,
selectedIndex: _selectedIndex,
onDestinationSelected: (int index) {
setState(() {
_selectedIndex = index;
contentView = _selectedIndex.toString();
});
},
selectedLabelTextStyle: TextStyle(
color: Color(0xffFCCFA8),
fontSize: 13,
letterSpacing: 0.8,
decoration: TextDecoration.underline,
decorationThickness: 2.0,
),
unselectedLabelTextStyle: TextStyle(
fontSize: 13,
letterSpacing: 0.8,
),
labelType: NavigationRailLabelType.all,
destinations: [
buildRotatedTextRailDestination("Dashboard", padding),
buildRotatedTextRailDestination("Shop", padding),
buildRotatedTextRailDestination("Service", padding),
],
/*
trailing: Column(
children: <Widget>[
SizedBox(height: 15,),
Icon(
Icons.exit_to_app,//Logout icon
color: Colors.white70,
),
SizedBox(height: 10,)
],
),
*/
),
//VerticalDivider(thickness: 1, width: 1),
// This is the main content.
getView(contentView,_selectedIndex,menuColor),
],
),
);
}
Widget menuRail() {
}
NavigationRailDestination buildRotatedTextRailDestination(
String text, double padding) {
return NavigationRailDestination(
icon: SizedBox.shrink(),
label: Padding(
padding: EdgeInsets.symmetric(vertical: padding),
child: RotatedBox(
quarterTurns: -1,
child: Text(text),
),
),
);
}
}
// ignore: must_be_immutable
class MenuRails extends StatefulWidget {
int menuColor;
final int selectedIndex;
MenuRails({this.menuColor,this.selectedIndex});
#override
_MenuRailsState createState() => _MenuRailsState();
}
class _MenuRailsState extends State<MenuRails> {
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
color: Colors.black54,
child: Column(
children: <Widget>[
SizedBox(height: MediaQuery.of(context).size.height * 0.07),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(
Icons.clear_all,
color: Color(widget.menuColor),
),
onPressed: () {
setState(() {
if (widget.menuColor == 0xFfFCCFA8)
widget.menuColor = 0xffffffff;
else
widget.menuColor = 0xFfFCCFA8;
});
},
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.07,
)
],
),
SizedBox(height: MediaQuery.of(context).size.height * 0.02),
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(
MediaQuery.of(context).size.width * 0.08, 0, 0, 0),
child: ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(55)),
child: Container(
color: Color(0xfffff9c4),
height: MediaQuery.of(context).size.height,
// Here we have to write code for content.
child: Center(
child: Text(
'selectedIndex: $widget.selectedIndex',
),
),
),
),
),
)
],
),
),
);
}
}
Try using Navigation Rails with PageView inside the Expanded widget
class NavRail extends StatefulWidget {
#override
_NavRailState createState() => _NavRailState();
}
class _NavRailState extends State<NavRail> {
int selectedIndex = 0;
PageController pageController = PageController();
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
NavigationRail(
labelType: NavigationRailLabelType.all,
selectedIconTheme: IconThemeData(color: Colors.green),
unselectedIconTheme: IconThemeData(color: Colors.blueGrey),
selectedLabelTextStyle: TextStyle(color: Colors.green),
unselectedLabelTextStyle: TextStyle(color: Colors.blueGrey),
selectedIndex: selectedIndex,
onDestinationSelected: (index) {
setState(() {
selectedIndex = index;
pageController.animateToPage(index,
duration: Duration(milliseconds: 200),
curve: Curves.easeIn);
});
},
destinations: [
NavigationRailDestination(
icon: Icon(Icons.home),
label: Text('Home'),
),
NavigationRailDestination(
icon: Icon(Icons.info),
label: Text('About'),
),
NavigationRailDestination(
icon: Icon(Icons.message),
label: Text('Feedback'),
),
],
),
Expanded(
child: PageView(
controller: pageController,
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
color: Colors.blue,
),
Container(
color: Colors.green,
),
Container(
color: Colors.indigo,
),
],
))
],
),
);
}
}

Cart counter is not updating on going back in flutter

i am adding item to cart on cart screen but when i go back to product for adding more products, the counter is not updating on my bottomNavigation bar ,as far as i know the activity is already in stack so its not refreshing , i can do it in native android (java) on invalidateOptionMenu() function ,which refresh appbar,but i don't know how to do it in flutter and also here its bottom navigation.
i already tried this code on backpressed functionn
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context){
return MainScreen();
},
),
);
on willpopscope,
any help will be appreciated.below is main screen
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: onPageChanged,
children: <Widget>[
Home(),
FavoriteScreen(),
SearchScreen(),
CartScreen(),
Profile(),
],
),
bottomNavigationBar: BottomAppBar(
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(width:7),
IconButton(
icon: Icon(
Icons.home,
size: 24.0,
),
color: _page == 0
? Theme.of(context).accentColor
: Theme
.of(context)
.textTheme.caption.color,
onPressed: ()=>_pageController.jumpToPage(0),
),
IconButton(
icon:Icon(
Icons.favorite,
size: 24.0,
),
color: _page == 1
? Theme.of(context).accentColor
: Theme
.of(context)
.textTheme.caption.color,
onPressed: ()=>_pageController.jumpToPage(1),
),
IconButton(
icon: Icon(
Icons.search,
size: 24.0,
color: Theme.of(context).primaryColor,
),
color: _page == 2
? Theme.of(context).accentColor
: Theme
.of(context)
.textTheme.caption.color,
onPressed: ()=>_pageController.jumpToPage(2),
),
IconButton(
icon: IconBadge(
icon: Icons.shopping_cart,
size: 24.0,
),
color: _page == 3
? Theme.of(context).accentColor
: Theme
.of(context)
.textTheme.caption.color,
onPressed: ()=>_pageController.jumpToPage(3),
),
IconButton(
icon: Icon(
Icons.person,
size: 24.0,
),
color: _page == 4
? Theme.of(context).accentColor
: Theme
.of(context)
.textTheme.caption.color,
onPressed: ()=>_pageController.jumpToPage(4),
),
SizedBox(width:7),
],
),
color: Theme.of(context).primaryColor,
shape: CircularNotchedRectangle(),
),
floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
elevation: 4.0,
child: Icon(
Icons.search,
),
onPressed: ()=>_pageController.jumpToPage(2),
),
),
);
IconBadge
class IconBadge extends StatefulWidget {
final IconData icon;
final double size;
static int counteer;
IconBadge({Key key, #required this.icon, #required this.size})
: super(key: key);
#override
_IconBadgeState createState() => _IconBadgeState();
}
class _IconBadgeState extends State<IconBadge> {
//List _users;
static int count ;
Future countForBadge() async{
var db = new DatabaseHelper();
count = await db.getCount();
print("Count: $count");
//print("khAN NNNN $counteer");
}
#override
void initState() {
// TODO: implement initState
super.initState();
countForBadge();
}
#override
Widget build(BuildContext context) {
if (count == null){
count = 0;
}
print("Count lande: $count");
return Stack(
children: <Widget>[
Icon(
widget.icon,
size: widget.size,
),
Positioned(
right: 0.0,
child: Container(
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 13,
minHeight: 13,
),
child: Padding(
padding: EdgeInsets.only(top: 1),
child:Text(
"$count",
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
),
),
],
);
}
}
I've replaced some screen with a simple Container().
If I understand your question, this is the solution using VoidCallBack:
main.dart
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:issue_counter_cart/cart_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
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> {
int _page;
int _counter = 0;
PageController _pageController;
#override
void initState() {
super.initState();
_pageController = PageController();
}
#override
void dispose() {
_pageController.dispose();
super.dispose();
}
void _increaseCart() {
setState(() {
_counter++;
});
}
void _decreaseCart() {
setState(() {
_counter--;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: _pageController,
// onPageChanged: onPageChanged,
children: <Widget>[
Container(),
Container(),
Container(),
CartScreen(
increaseCart: () => _increaseCart(),
decreaseCart: () => _decreaseCart(),
),
Container(),
],
),
bottomNavigationBar: BottomAppBar(
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(width: 7),
IconButton(
icon: Icon(
Icons.home,
size: 24.0,
),
color: _page == 0
? Theme.of(context).accentColor
: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(0),
),
IconButton(
icon: Icon(
Icons.favorite,
size: 24.0,
),
color: _page == 1
? Theme.of(context).accentColor
: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(1),
),
IconButton(
icon: Icon(
Icons.search,
size: 24.0,
color: Theme.of(context).primaryColor,
),
color: _page == 2
? Theme.of(context).accentColor
: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(2),
),
IconButton(
icon: Badge(
badgeContent: Text(_counter.toString()),
child: Icon(Icons.shopping_cart),
),
color: _page == 3
? Theme.of(context).accentColor
: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(3),
),
IconButton(
icon: Icon(
Icons.person,
size: 24.0,
),
color: _page == 4
? Theme.of(context).accentColor
: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(4),
),
SizedBox(width: 7),
],
),
color: Theme.of(context).primaryColor,
shape: CircularNotchedRectangle(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
cart_screen.dart
import 'package:flutter/material.dart';
class CartScreen extends StatefulWidget {
final VoidCallback increaseCart;
final VoidCallback decreaseCart;
CartScreen({this.increaseCart, this.decreaseCart});
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Column(
children: <Widget>[
RaisedButton(
onPressed: widget.increaseCart,
child: Text('Increase cart'),
),
RaisedButton(
onPressed: widget.decreaseCart,
child: Text('Decrease cart'),
),
],
),
),
);
}
}
To simplify the code I've used the bagdes package