Related
I am using Default Sidebar but getting error while scroll
'The $controllerForError is currently attached to more than one '
'ScrollPosition.',
here is Sidebar Widget
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bgimage.jpg"),
fit: BoxFit.cover),
color: Colors.blue,
),
child: Center(
child: Column(
children: [
Text(
'${store.user['name']}',
style: TextStyle(color: Colors.white, fontSize: 25),
),
Lottie.asset(
'assets/lottie/coin.json',
width: 50,
height: 50,
),
Text(
'${store.user['wallet']}',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
)),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.popAndPushNamed(context, '/home');
},
),
ListTile(
leading: Icon(Icons.assessment_outlined),
title: Text('Loss/Profit'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Results'),
onTap: () {
Navigator.popAndPushNamed(context, '/result');
},
),
ListTile(
leading: Icon(Icons.supervised_user_circle),
title: Text('Referrals'),
onTap: () {
Navigator.pop(context);
},
),
],
);
}
}
Using in homepage
drawer: Drawer(
child: Sidebar(),
),
where is scroll position is using multiple
by default drawer is already scrollable. i think the cause of not being able to scroll is not in the drawer
I have been trying to make the bottom navigation bar persisting on all page screens but it looks like it is only persisting for the pages that are on the bottom navigation only i.e HomeScreen(), DiscoverScreen(), GivingScreen(), EventsScreen() and SettingsScreen(). Other pages are not getting the bottom navigation. Here is the code of my bottom navigation bar. How can I add the bottom nav bar on all pages I have in the app?
class CustomBottomNavBar extends StatefulWidget {
const CustomBottomNavBar({Key key}) : super(key: key);
#override
_CustomBottomNavBarState createState() => _CustomBottomNavBarState();
}
class _CustomBottomNavBarState extends State<CustomBottomNavBar> {
int currentIndex = 0;
final screens = [
HomeScreen(),
DiscoverScreen(),
GivingScreen(),
EventsScreen(),
SettingsScreen(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: currentIndex,
children: screens,
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: kPrimaryColor,
selectedItemColor: kSelectedItemColor,
iconSize: kBottomNavIconSize,
unselectedItemColor: kAlternativeColor,
selectedFontSize: kBottomNavFontSize,
unselectedFontSize: kBottomNavFontSize,
showUnselectedLabels: true,
showSelectedLabels: true,
currentIndex: currentIndex,
onTap: (index) => setState(() => currentIndex = index),
items: [
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.mic_fill,
),
label: 'Sermons',
),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.wand_stars_inverse,
),
label: 'Discover',
),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.heart_fill,
),
label: 'Giving',
),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.calendar_today,
),
label: 'Events',
),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.gear_alt_fill,
),
label: 'Settings',
),
],
),
);
}
}
Here is a picture of a view that has a bottom nav
Here is a picture of a view that has not a bottom nav
import 'package:church_app/components/widgets/animated_like_button.dart';
import 'package:church_app/components/widgets/custom_bottom_nav_bar.dart';
import 'package:church_app/components/widgets/navigation_drawer.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:church_app/utilities/constants.dart';
import 'package:church_app/components/widgets/action_and_text.dart';
class SermonDescriptionScreen extends StatefulWidget {
#override
_SermonDescriptionScreenState createState() =>
_SermonDescriptionScreenState();
}
class _SermonDescriptionScreenState extends State<SermonDescriptionScreen> {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
endDrawer: NavigationDrawer(),
appBar: AppBar(
leading:
(ModalRoute.of(context)?.canPop ?? false) ? BackButton() : null,
iconTheme: IconThemeData(color: kPrimaryColor),
elevation: 0,
title: Text(
'Protect The Vessel',
style: kMainStyling,
),
centerTitle: true,
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SafeArea(
left: true,
right: true,
top: true,
bottom: true,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 250,
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey[300],
blurRadius: 30,
offset: Offset(0, 10),
),
],
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/images/pastor.jpg'),
),
),
),
addVSpace(30),
Container(
margin: EdgeInsets.only(left: 10, right: 10, bottom: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Protect The Vessel',
style: kDescriptionTitle,
softWrap: true,
),
addVSpace(3),
Text(
'Pastor James Wiseman',
style: kMainStyling.copyWith(
color: kPrimaryColor.withOpacity(.8),
),
softWrap: true,
),
addVSpace(3),
Row(
children: [
Text(
'Jan 25, 2021',
style: kMainStyling.copyWith(
color: kPrimaryColor.withOpacity(.8),
),
softWrap: true,
),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: kPrimaryColor,
),
width: 8,
height: 8,
),
),
Container(
child: AnimatedLikeButton(),
),
],
),
addVSpace(20),
Text(
'Are you protecting what matters? In Protect What Matters, Pastor James Wiseman reminds us that we are vessels that can either foster bitterness or make way for the healing hand of God in our lives.',
style: kMainStyling,
softWrap: true,
textAlign: TextAlign.justify,
maxLines: 6,
),
addVSpace(30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ActionAndText(
correspondingIcon:
CupertinoIcons.arrow_down_to_line_alt,
correspondingText: 'Download',
gesture: () {},
),
ActionAndText(
correspondingIcon: CupertinoIcons.heart,
correspondingText: 'Like',
gesture: () {},
),
ActionAndText(
correspondingIcon: CupertinoIcons.play,
correspondingText: 'Listen',
gesture: () {
Navigator.pushNamed(context, '/playerScreen');
},
),
ActionAndText(
correspondingIcon: CupertinoIcons.square_arrow_up,
correspondingText: 'Share',
gesture: () {},
),
],
),
],
),
),
],
),
),
),
),
);
}
}
to get this you can use pageView with bottomNavigationBar... this is a sample code. this will give idea how to go about it..
Scaffold buildAuthScreen() {
return Scaffold(
body: PageView(
scrollDirection: Axis.horizontal,
children: [
Timeline(),
ActivityFeedItem(),
Search(),
Upload(),
Profile(
currentUser: _auth.currentUser.uid,
),
],
controller: _pageController,
onPageChanged: (value) {
setState(() {
pageIndex = value;
});
},
physics: BouncingScrollPhysics(),
),
bottomNavigationBar: CurvedNavigationBar(
key: _bottomNavigationKey,
index: pageIndex,
height: 50.0,
color: Theme.of(context).primaryColor,
items: [
Icon(Icons.whatshot, color: Colors.white),
Icon(Icons.notifications_active, color: Colors.white),
Icon(Icons.search, color: Colors.white),
Icon(Icons.photo_camera, color: Colors.white),
Icon(Icons.account_circle, color: Colors.white),
],
animationDuration: Duration(milliseconds: 200),
buttonBackgroundColor: Theme.of(context).accentColor,
backgroundColor: Colors.white,
onTap: (int pageIndex1) {
_pageController.animateToPage(pageIndex1,
duration: Duration(microseconds: 300), curve: Curves.bounceInOut);
},
),
);
}
Use custom_navigator 0.3.0 package from pub dev website
You can use this package https://pub.dev/packages/persistent_bottom_nav_bar for persistent bottom navigator in all Screen,
And when try to navigate to new screen use this below navigator function,
pushNewScreen(
context,
screen: MainScreen(),
withNavBar: true, // OPTIONAL VALUE. True by default.
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
The problem with inbuilt BottomNavigationBar doesn't have ability to show to every screen,there is plugin called Presistant_bottom_nav_bar,here is some sample code for more checkout other properties of PersistentTabView,animation,state,hide bottombar when keyboard comes up kind of stuff
Also checkout this material guideline do's and don'ts bottom-navigation if you are not interested in using the plugin
PersistentTabController _controller =PersistentTabController(initialIndex:
0);
//Screens for each nav items.
List<Widget> _NavScreens() {
return [
HomeScreen(),
DiscoverScreen(),
GivingScreen(),
EventsScreen(),
SettingsScreen(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.mic_fill),
title: ("Home"),
activeColor: CupertinoColors.activeBlue,
inactiveColor: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.wand_stars_inverse),
title: ("Discover"),
activeColor: CupertinoColors.activeGreen,
inactiveColor: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.heart_fill),
title: ("Giving"),
activeColor: CupertinoColors.systemRed,
inactiveColor: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.calendar_today),
title: ("Events"),
activeColor: CupertinoColors.systemIndigo,
inactiveColor: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.gear_alt_fill),
title: ("Settings"),
activeColor: CupertinoColors.systemIndigo,
inactiveColor: CupertinoColors.systemGrey,
),
];
}
#override
Widget build(BuildContext context) {
return Center(
child: PersistentTabView(
controller: _controller,
screens: _NavScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white,
handleAndroidBackButtonPress: true,
resizeToAvoidBottomInset: true,
hideNavigationBarWhenKeyboardShows: true,
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
),
popAllScreensOnTapOfSelectedTab: true,
navBarStyle: NavBarStyle.style9,
),
);
}
You can use this navigate and use the BottomNavigationBar with navigator provided by the plugin
pushNewScreen(
context,
screen: SubScreenNames(),
withNavBar: true,
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
I have the following Flutter bottom navigation bar
And I would like to add a top-line or boarder for active items like so
Is that even possible, my code is straight forward.
#override
Widget build(BuildContext context) {
return Scaffold(
body: _tabs[_tabIndex],
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.white,
selectedLabelStyle: TextStyle(fontSize: 14),
selectedItemColor: Theme.of(context).accentColor,
unselectedLabelStyle: TextStyle(fontSize: 14.0),
unselectedItemColor: Color(0xff546481),
type: BottomNavigationBarType.fixed,
showSelectedLabels: true,
showUnselectedLabels: true,
currentIndex: _tabIndex,
onTap: (int index) {
setState(() {
_tabIndex = index;
});
},
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: 'HOME',
),
BottomNavigationBarItem(
icon: Icon(Icons.history_outlined),
label: 'HISTORY',
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: 'PROFILE',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_outlined),
label: 'SETTINGS',
),
],
),
);
}
}
there are some packages can achieve this effect:
titled_navigation_bar
bottomNavigationBar: TitledBottomNavigationBar(
currentIndex: 2, // Use this to update the Bar giving a position
onTap: (index){
print("Selected Index: $index");
},
items: [
TitledNavigationBarItem(title: Text('Home'), icon: Icons.home),
TitledNavigationBarItem(title: Text('Search'), icon: Icons.search),
TitledNavigationBarItem(title: Text('Bag'), icon: Icons.card_travel),
TitledNavigationBarItem(title: Text('Orders'), icon: Icons.shopping_cart),
TitledNavigationBarItem(title: Text('Profile'), icon: Icons.person_outline),
]
)
bottom_indicator_bar
class _HomePageState extends State<HomePage> {
final List<BottomIndicatorNavigationBarItem> items = [
BottomIndicatorNavigationBarItem(icon: Icons.home),
BottomIndicatorNavigationBarItem(icon: Icons.search),
BottomIndicatorNavigationBarItem(icon: Icons.settings),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Indicator Bottom Bar"),
backgroundColor: Colors.teal,
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
],
),
),
bottomNavigationBar: BottomIndicatorBar(
onTap: (index) => {},
items: items,
activeColor: Colors.teal,
inactiveColor: Colors.grey,
indicatorColor: Colors.teal,
),
);
}
}
You can use a TabBar instead of a BottomNavigationBar using a custom decoration:
class TopIndicator extends Decoration {
#override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _TopIndicatorBox();
}
}
class _TopIndicatorBox extends BoxPainter {
#override
void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
Paint _paint = Paint()
..color = Colors.cyan
..strokeWidth = 5
..isAntiAlias = true;
canvas.drawLine(offset, Offset(cfg.size!.width + offset.dx, 0), _paint);
}
}
Then pass the decoration to the TapBar using TapBar(indicator: TopIndicator ...).
To use the TabBar as the Scaffold.bottomNavigationBar, you will most likely want to wrap it in a Material to apply a background color:
Scaffold(
bottomNavigationBar: Material(
color: Colors.white,
child: TabBar(
indicator: TopIndicator(),
tabs: const <Widget>[
Tab(icon: Icon(Icons.home_outlined), text: 'HOME'),
...
],
),
),
...
)
Thanks Ara Kurghinyan for the original idea.
Column(
children: [
pageIndex == 2
? Container(
height: 5.w,
width: 35.h,
alignment: Alignment.center,
// margin: const EdgeInsets.only(left: 5),
decoration: const BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
3,
),
bottomRight: Radius.circular(3)),
),
// height: 5,
// width: 35,
)
: SizedBox(
height: 5.w,
width: 35.h,
),
SizedBox(
height: 4.h,
),
Flexible(
child: Container(
height: 25.h,
width: 25.w,
// alignment: Alignment.lerp(
// Alignment.bottomLeft, Alignment.bottomRight, 1),
decoration: BoxDecoration(
// color: Colors.red,
border: Border.all(
width: 1,
color: Colors.black,
),
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: IconButton(
iconSize: 25,
alignment: Alignment.center,
padding: const EdgeInsets.only(top: 4, bottom: 4),
visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
enableFeedback: false,
onPressed: () {
setState(() {
pageIndex = 2;
});
},
icon: pageIndex == 2
? Image.asset(
'assets/icons/icons8-alarm-50.png',
height: 24.h,
color: Colors.black,
// size: 35.sm,
)
: Image.asset(
'assets/icons/icons8-alarm-50.png',
color: Colors.black,
// size: 35.sm,
)),
),
),
pageIndex == 2
? Container(
height: 15.h,
width: 60.w,
alignment: Alignment.lerp(
Alignment.centerLeft, Alignment.centerRight, 0.75),
child: Text(
'Reminder',
style: GoogleFonts.lato(
textStyle: const TextStyle(
fontSize: 12, fontWeight: FontWeight.bold),
),
),
)
: Container(),
],
),
In my flutter app I have a RaisedButton widget on the first page of my BottomNavigationBar. This page contains a button that should take the user to the fourth and final page of app that also happens to be the fourth page on the BottomNavigationBar (I know this is silly but customer requirements are what they are). This is my RaisedButton:
Padding(
padding: const EdgeInsets.only(top: 20),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
height: MediaQuery.of(context).size.width * 0.15,
child: RaisedButton(
textColor: Colors.white,
color: Constants.secondaryYellow,
child: new AlignText(
alignmentDirection: Alignment.center,
fontSize: 22,
fontWeight: FontWeight.normal,
text: 'Go to Settings',
textColour: Constants.primaryWhite,
),
onPressed: () {
navigationBar.onTap(3);
},
splashColor: Constants.secondaryLightBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0))),
),
)
The BottomNavigationBar key is instantiated in the stateful widget just above the build function like so
final BottomNavigationBar navigationBar = navBarGlobalKey.currentWidget;
If I navigate to a different screen, come back to the home page and then press the button, the button works as intended. However, if the button is the first press I make in the app then the onTap function returns the following error in the console
The getter 'onTap' was called on null.
Receiver: null
Tried calling: onTap
Here is my BottomNavigationBar:
BottomNavigationBar(
key: navBarGlobalKey,
onTap: onTapped,
currentIndex: currentIndex,
fixedColor: Constants.secondaryLightBlue,
backgroundColor: Colors.white,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.dashboard),
title: new Text('Page 1'),
activeIcon: new Icon(
Icons.dashboard,
color: Constants.secondaryLightBlue,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.apps),
title: new Text('Page 2'),
activeIcon: new Icon(
Icons.apps,
color: Constants.secondaryLightBlue,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.people),
title: new Text('Page 3'),
activeIcon: new Icon(
Icons.people,
color: Constants.secondaryLightBlue,
)),
BottomNavigationBarItem(
icon: new Icon(Icons.question_answer),
title: new Text('Page 4'),
activeIcon: new Icon(
Icons.question_answer,
color: Constants.secondaryLightBlue,
)),
],
)
The variable navigationBar being called in the onTap is a global variable in main.dart and attached as the key of the BottomNavigationBar
GlobalKey navBarGlobalKey = GlobalKey(debugLabel: 'bottomAppBar');
void main() {
runApp(
MaterialApp(
theme: ThemeData(primaryColor: Color.fromRGBO(35, 40, 55, 1)),
home: SampleApp(),
),
);
}
I've a bottomnavigation bar that has a color. When I clicked on the last button, the color change to white ...
The last button show some card i can swipe.
For that i use the code here : https://github.com/devefy/Flutter-Story-App-UI
i've tried to change return container() whith something else, but nothing was heplful.
here is my code
void _onItemTapped(int index) {
setState(() {
if (edifice != null) _selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.unEdifice.vocable),
backgroundColor: color_edifices,
),
body: Center(
child: edifice == null
? CircularProgressIndicator()
: _selectedIndex == 5
? SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
CardScrollWidget(currentPage),
Positioned.fill(
child: PageView.builder(
itemCount: edifice.commentaires.length,
controller: controller,
reverse: true,
itemBuilder: (context, index) {
return Container(
);
},
),
)
],
),
],
),
)
: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: color_edifices,
icon: Icon(GaeoIcons.church, color: Colors.white),
title: Text('Edifice', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.location_on, color: Colors.white),
title: Text('Adresses', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.group, color: Colors.white),
title: Text('Responsables', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.truck, color: Colors.white),
title: Text('Distributions', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.group, color: Colors.white),
title: Text('Contacts', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.comment, color: Colors.white),
title: Text('Commentaires', style: buttonTextStyle),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}`
You can see what i mean with the pictures included
Thanks for your help
I have tried to simulate your case with Story App UI
please try to
1. add BottomNavigationBar 's backgroundColor
2. test with BottomNavigationBarType.fixed and fixedColor
also reference Flutter BottomNavigationBar Colors
code snippet
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.brown,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.white,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: Colors.white,
icon: Icon(Icons.access_time, color: Colors.white),
title: Text('Edifice', ),
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm, color: Colors.white),
title: Text('Adresses', ),
),
],
)
Test result of Story App UI with BottomNavigationBar