How can I keep showing bottomNavigationBar in nested page? - flutter

there is shopping app, and there is 4 items in bottomNavBar.
in home page, fetch all categories and shown in page, when pressed on category, he should see the products in category. but how can I keep bottom navigation bar when I want to navigate him into next pages?
this is myBottomNavigationBar code:
Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
icon: Icon(
Icons.search,
color: Constants.blackBackgroundColor,
),
onPressed: () {})
],
),
body: IndexedStack(
index: _mainController.tabIndex,
children: [
HomePage(),
OfferPage(),
CartPage(),
ProfilePage(),
],
),
bottomNavigationBar: bottomNavigationBar(context),
);

Don't know if this is what you're looking for but here is one way of achieving it.
List<dynamic> _screens = [ HomePage(), OfferPage(),CartPage(), ProfilePage()];
int _index = 0;
PageController controller = PageController();
Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
icon: Icon(
Icons.search,
color: Constants.blackBackgroundColor,
),
onPressed: () {})
],
),
body: PageView.builder(
itemCount: 4,
controller: controller,
onPageChanged: (page) {
setState(() {
_index = page;
});
},
itemBuilder: (context, position) {
return Container(
color: Colors.white,
child: Center(child: _screens[position]),
);
}),
bottomNavigationBar: bottomNavigationBar(context),
);

Related

Why I'm getting two app bar in home screen in flutter?

I have made multiple screens and these screen have separate appBar in flutter but my home Screen getting two appBar! How can remove it in flutter?
I have tried several things but I'm still getting two screen.
Here is image link
enter image description here
Home Screen And Category Screen have same appBar code
Here Is Code of Home Screen appBar
appBar: AppBar(
title: const Text('Online Survey'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate:CustomSearchDelegate(),);
},
),
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) => DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) =>
SingleChildScrollView(
child: Column(
children: [
ListTile(
leading: const Icon(Icons.color_lens),
title: const Text('Dark Theme'),
subtitle: const Text(
'Better for eyesight and battery life'),
trailing: IconButton(
onPressed: () {},
icon: const Icon(Icons.toggle_off_rounded)),
),
const ListTile(
leading: Icon(Icons.restaurant_menu),
title: Text('Display Item'),
subtitle: Text('List(small item)'),
),
const ListTile(
leading: Icon(Icons.lock),
title: Text('Privacy Policy'),
subtitle: Text('App Terms & Policy'),
),
const ListTile(
leading: Icon(Icons.rate_review),
title: Text('Rate Us'),
subtitle: Text('Leave a review on the Google Play'),
),
const ListTile(
leading: Icon(Icons.more),
title: Text('More Apps'),
subtitle: Text('More Apps form developer'),
),
const ListTile(
leading: Icon(Icons.info_rounded),
title: Text('About'),
subtitle:
Text('App Info, Build Version, Copyright'),
),
],
),
//sheetButtons(),
),
),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(30))),
isScrollControlled: true,
isDismissible: true,
// barrierColor: Colors.blue.shade100,
enableDrag: true,
elevation: 7,
);
},
icon: const Icon(Icons.more_vert)),
],
primary: true,
),
Please post the entire Scaffold code if you need to pinpoint the anomaly.
The code you shared isn't enough to find the bug since its above this tree level.
However from my experience,
Guess 1: You have implemented Home screen with AppBar and Category is a sub widget of Home screen and has its AppBar.
Guess 2:
You have implemented AppBar in appBar and body of Scaffold.
Do check and update your question. Thanks!
You are using the Bottom Navigation which is causing the issue. The Bottom navigation page contains a Scaffold with an AppBar and the other screen you are using has a separate AppBar. To resolve the issue you either need to remove the AppBar from the Bottom Navigation Screen or remove the AppBar from the individual screen.
I think you Extracted Widgets from root widget's body!
Example:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Online Survey'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
//showSearch(context: context, delegate:CustomSearchDelegate(),);
},
),
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) => DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) =>
SingleChildScrollView(
child: Column(
children: [
ListTile(
leading: const Icon(Icons.color_lens),
title: const Text('Dark Theme'),
subtitle: const Text(
'Better for eyesight and battery life'),
trailing: IconButton(
onPressed: () {},
icon: const Icon(Icons.toggle_off_rounded)),
),
const ListTile(
leading: Icon(Icons.restaurant_menu),
title: Text('Display Item'),
subtitle: Text('List(small item)'),
),
const ListTile(
leading: Icon(Icons.lock),
title: Text('Privacy Policy'),
subtitle: Text('App Terms & Policy'),
),
const ListTile(
leading: Icon(Icons.rate_review),
title: Text('Rate Us'),
subtitle: Text('Leave a review on the Google Play'),
),
const ListTile(
leading: Icon(Icons.more),
title: Text('More Apps'),
subtitle: Text('More Apps form developer'),
),
const ListTile(
leading: Icon(Icons.info_rounded),
title: Text('About'),
subtitle:
Text('App Info, Build Version, Copyright'),
),
],
),
//sheetButtons(),
),
),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(30))),
isScrollControlled: true,
isDismissible: true,
// barrierColor: Colors.blue.shade100,
enableDrag: true,
elevation: 7,
);
},
icon: const Icon(Icons.more_vert)),
],
primary: true,
),
body: Exc(), ////here is the main body of widgets.
);
}
}
class Exc extends StatelessWidget {
const Exc({
super.key,
});
#override
Widget build(BuildContext context) {
////you returned another Scaffold and an appBar! this caused another
////appbar.
////return something else instead of Scaffold.
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemBuilder: (context, index) => const Padding(
padding: EdgeInsets.all(8),
child: Text('Testing Chats'),
),
itemCount: 10),
);
}
}
Output:

Flutter how to hide Cupertino bottom navigation bar at next page

I currently working on a project need to build with Cupertino widget. Everything is fine until I trying not to display bottom navigation bar at next page, but the bottom navigation bar still bring forward from previous page. Below is my example code.
class PageOne extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person), label: 'Person'),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.mail), label: 'Mail'),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.flag), label: 'Flag'),
],
),
tabBuilder: (context, index) {
return CupertinoTabView(
routes: {
'p2': (context) => PageTwo(),
},
builder: (context) {
return CupertinoPageScaffold(
backgroundColor: Colors.white,
child: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, 'p2');
},
child: Text('Next Page'),
),
],
),
));
},
);
},
);
}
}
class PageTwo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
color: Colors.white,
child: Column(children: [
Text('Page 2'),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Back'),
),
]),
),
);
}
}
Found the solutions.
First solution.
Just repace
Navigator.pushNamed(context,'p2');
to
Navigator.of(context, rootNavigator: true).pushNamed('p2');
Second solution
Remove the CupertinoTabView from tabBuilder if not necessary to use it
tabBuilder: (context, index) {
return CupertinoPageScaffold(
backgroundColor: Colors.white,
child: Center(
child: Column(
children: [
SizedBox(
height: 50.0,
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, 'p2');
},
child: Text('Next Page'),
),
],
),
),
);
},
imprtant: must set routes for class CupertinoApp
Navigator.of(context, rootNavigator: true).pushReplacement(MaterialPageRoute(builder: (context) => YourScreen()));

why flutter BottomNavigationBar changes the icon but does not change the page?

Im new to coding and flutter and I have been trying to make my bottomNavigationBar change pages from home page to chatroom but what ever I try is not working , I watched many videos but their bottomNavigationBar is inside their body and when I apply what they are doing I get the red line under my padding right after body and return Scaffold( right under this parenthesis before my appBar: image link is at the end of the code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:trading/core/const.dart';
import 'package:trading/models/apartment_model.dart';
import 'package:trading/pages/chat.dart';
import 'package:trading/pages/detail_page.dart';
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
var data = ApartmentModel.list;
int _selectedIndex = 0;
List<Widget> `enter code here`pages=[
Homepage(),
Chatroom(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
"find your product",
style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.black38,
),
onPressed: () {}),
IconButton(
icon: Icon(
Icons.filter_list,
color: Colors.black38,
),
onPressed: () {}),
],
),
bottomNavigationBar:
BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
selectedItemColor: AppColors.stylecolor,
unselectedItemColor: Colors.black38,
currentIndex: _selectedIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text("datsa")),
BottomNavigationBarItem(
icon: Icon(Icons.chat), title: Text("data"),),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text("data")),
],
),
body:
pages.elementAt(_selectedIndex),
Padding(
padding: EdgeInsets.all(16.0),
child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"65 result in your area",
style: TextStyle(color: Colors.black38),
),
Expanded(
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => DetailPage(
data[index]
),
),
);
},
child: _buildItem(context, index));
},
),
),
// Container( child: _builBottomNavigationBar),
],
),
),
);
}
here is a pic of the red line that I was saying
body can take one widget not more, you assign pages and padding if you want both you must use a column
You have to make a List of Widgets containing your pages, and in the body you populate the Widget according to the Selected Index.
Example:
List<Widget> pages=[
Dashboard(),
Profile(),
Settings(),
];
then show the page in the body as:
body:
pages.elementAt(_selectedIndex),

How can I make BottomNavigationBar NOT stick on top of keyboard flutter?

So I wanted to make the sticking of BottomNavigationBar on the keyboard stop.
I have tried:
resizeToAvoidBottomPadding: false; (or true both not working),
The problem with the bottomnavigationbar sticking to my keyboard is when I try to type something, the suggestions are not clearly visible and also it has a nested app bar on another page, which in-turn make it very difficulty to type and see the suggestions.
Here is my code:
#override
void initState() {
super.initState();
getUser();
//PostController().getUser(widget.auth.getCurrentUser());
pages = [Home(), Search(), NewPostPage(), Notifications(), Profile()];
}
#override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: true,
body: Home(context),
);
}
Widget Home(context) {
var bottomOptions = <BottomNavigationBarItem>[];
for (var i = 0; i < widget.bottomItems.length; i++) {
var d = widget.bottomItems[i];
bottomOptions.add(
new BottomNavigationBarItem(
icon: d.icon,
title: Padding(
padding: const EdgeInsets.fromLTRB(3, 3, 3, 0),
child: new Text(d.title, style: TextStyle(fontSize: 12.0)),
),
),
);
}
return Scaffold(
appBar: AppBar(
title: Text(title),
leading: Container(
alignment: Alignment.centerLeft,
child: IconButton(
icon: Icon(Icons.motorcycle),
onPressed: () {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, anim1, anim2) => Finder(),
transitionsBuilder: (context, anim1, anim2, child) =>
FadeTransition(opacity: anim1, child: child),
transitionDuration: Duration(seconds: 0),
));
}),
),
body: isLoading
? CollectionScaleTransition(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Icon(Icons.add_circle, size: 10, color: Colors.blue),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Icon(Icons.add_circle, size: 10, color: Colors.blue),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Icon(Icons.add_circle, size: 10, color: Colors.blue),
),
],
)
: PageView(
controller: pageController,
children: pages,
onPageChanged: onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: BottomNavigationBar(
showUnselectedLabels: true,
items: bottomOptions,
currentIndex: currentIndex,
selectedFontSize: 9,
unselectedFontSize: 9,
type: BottomNavigationBarType.fixed,
onTap: (index) {
setState(() {
onTap(index);
currentIndex = index;
});
},
),
);
}
}
How to make it stop appearing when I try to type on my text-field?
Thank you in Advance!
resizeToAvoidBottomPadding property is deprecated. We need to use resizeToAvoidBottomInset instead. More details here.
Also, I tried to recreate your case but was unable to replicate the issue you mentioned. I took some of your code and used it my sample, as below:
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text('test'),
leading: Container(
alignment: Alignment.centerLeft,
child: IconButton(
icon: Icon(Icons.motorcycle),
onPressed: () {}),
)),
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0, // this will be set when a new tab is tapped
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('Home'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.mail),
title: new Text('Messages'),
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text('Profile')
)
],
),
body: Center(
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a search term'
),
))
);
With above code, when I tap on textfield, the bottom nav didn't show and I was able to type in properly.
Hope this helps.

My app closed when i pressed back from navigation drawer selected item in flutter

I have navigation drawer, i select one item from it and after i select second item when i pressed back after selecting second item app got closed i need to go on first item when i pressed back .
#override
Widget build(BuildContext context) {
List<Widget> drawerOptions = [];
for (var i = 0; i < drawerItems.length; i++) {
var d = drawerItems[i];
drawerOptions.add(new ListTile(
leading: new Icon(d.icon),
title: new Text(
d.title,
style: new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400),
),
selected: i == _selectedIndex,
onTap: () => _onSelectItem(i),
));
}
return new Scaffold(
appBar: SearchBar(
loader: QuerySetLoader<ProductModel>(
querySetCall: _getItemListForQuery,
itemBuilder: _buildItemWidget,
loadOnEachChange: true,
animateChanges: true,
),
defaultBar: AppBar(
title: Text('Home'),
),
),
drawer: new Drawer(
child: SingleChildScrollView(
child: new Column(
children: <Widget>[
DecoratedBox(
position: DecorationPosition.background,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/bac_image.png'),
fit: BoxFit.cover),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(20.0),
child: new Image(
image: new AssetImage("assets/blik_mobile.png"),
height: 100,
width: 100,
),
),
Column(children: drawerOptions)
],
),
)
],
),
),
),
body: _getDrawerItemScreen(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
onTap: (int index) {
setState(() {
this.index = index;
// Navigator.of(context).pop();
});
_navigateToScreens(index);
},
type: BottomNavigationBarType.fixed,
currentIndex: index,
items: [
BottomNavigationBarItem(
title: Text('Home'),
icon: Icon(
Icons.home,
color: Colors.black,
)),
BottomNavigationBarItem(
title: Text('Categories'),
icon: Icon(Icons.dashboard, color: Colors.black)),
BottomNavigationBarItem(
title: Text('Cart'),
icon: Icon(Icons.shopping_cart, color: Colors.black)),
BottomNavigationBarItem(
title: Text('WishList'),
icon: Icon(Icons.favorite, color: Colors.black)),
BottomNavigationBarItem(
title: Text('Profile'),
icon: Icon(Icons.person, color: Colors.black)),
],
),
);
}
on select item of drawer
_onSelectItem(int index) {
setState(() {
_selectedIndex = index;
_getDrawerItemScreen(_selectedIndex);
});
Navigator.of(context).pop();
}
get selected drawer screen method is here
_getDrawerItemScreen(int pos) {
switch (pos) {
case 0:
return new FirstScreen(drawerItem: drawerItems[_selectedIndex]);
case 1:
return new OrderHistory(drawerItem: drawerItems[_selectedIndex]);
case 2:
return new WalletScreen(
drawerItem: drawerItems[_selectedIndex],
);
case 3:
return new AddressList(drawerItem: drawerItems[_selectedIndex]);
case 5:
return new AboutUs(drawerItem: drawerItems[_selectedIndex]);
// return new AddAddress(drawerItem: drawerItems[_selectedIndex],);
default:
return new FirstScreen(drawerItem: drawerItems[_selectedIndex]);
}
}
i want to handle back after selecting any of item from my navigation drawer .
If you need to control screen stack, you can use
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
detail reference https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31
If you want to handle back button
you can wrap your Scaffold with WillPopScope
return WillPopScope(
onWillPop: () => _exitApp(context),
child: Scaffold(
appBar: AppBar(
title: Text("Navigation Demo"),
and ask user Do you want to exit this application or current screen
Future<bool> _exitApp(BuildContext context) {
return showDialog(
context: context,
child: AlertDialog(
title: Text('Do you want to exit this application?'),
content: Text('We hate to see you leave...'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('No'),
),
FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text('Yes'),
),
],
),
) ??
false;
}
detail reference https://codingwithjoe.com/flutter-navigation-how-to-prevent-navigation/