Show Bottom Modal Sheet above the Bottom Navigation Bar - flutter

Here in the below image I have added showModalBottomSheet on clicking on the item of "Bottom Navigation Bar", but the BottomNavigationBar is hidden by the modal sheet, So I want to make it visible even the bottom sheet is present. Can anyone please anyone help me out.
This is my bottom navigation code:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{showBrandsBottomSheet(context)}
else if (newIndex == 2)
{showCategoryBottomSheet(context)}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
Here is my code for bottom model sheet:
showBrandsBottomSheet(BuildContext context) {
return showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
),
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (BuildContext _) {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight,
child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: Key('builder ${_selected.toString()}'), //a
scrollDirection: Axis.vertical,
// shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTile(
// tilePadding: const EdgeInsets.all(0),
key: Key(index.toString()), //attention
initiallyExpanded: index == _selected, //attention
collapsedIconColor: Colors.blue,
iconColor: Colors.blue,
backgroundColor: Colors.white,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: ((newState) {
if (newState) {
setState(() {
const Duration(seconds: 20000);
_selected = index;
});
} else {
setState(() {
_selected = -1;
});
}
}),
));
},
),
),
],
),
),
);
},
);
}

set useRootNavigator=true.This will display model sheet above all other content.
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) {
return BottomBarView(
);
});

Finally, this question helped me in getting this done.
Here is my working code:
Widget _bottomNavigationBar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
key: scaffoldState,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.branding_watermark_outlined),
label: 'Brands',
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
label: 'Category',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
)
],
currentIndex: _selectedIndex,
selectedItemColor: AppColors.blue,
onTap: (newIndex) => {
if (newIndex == 1)
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showBrandsBottomSheet(),
))
}
else if (newIndex == 2)
{
{
_scaffoldKey.currentState?.showBottomSheet((_) => Container(
child: showCategoryBottomSheet(),
))
}
}
else
{
setState(() {
_selectedIndex = newIndex;
})
}
});
}
showBrandsBottomSheet:
showBrandsBottomSheet() {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height / 2,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5, top: 3),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Align(
alignment: Alignment.topRight, child: Icon(Icons.close)),
),
),
Container(
color: Colors.white,
height: 350,
child: ListView.builder(
key: UniqueKey(),
scrollDirection: Axis.vertical,
itemCount: brandList.length,
itemBuilder: (BuildContext context, int index) {
cardKeyList.add(GlobalKey(debugLabel: "index :$index"));
return Theme(
data: Theme.of(context)
.copyWith(dividerColor: Colors.white),
child: ExpansionTileCard(
key: cardKeyList[index],
initiallyExpanded: false,
title: Text(
brandList[index],
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
fontWeight: FontWeight.w600),
),
children: <Widget>[
Container(
color: Colors.blue[50],
child: Column(
children: _buildExpandableBrands(brandList),
),
),
],
onExpansionChanged: (value) {
if (value) {
Future.delayed(const Duration(milliseconds: 200),
() {
for (var i = 0; i < cardKeyList.length; i++) {
if (index != i) {
cardKeyList[i].currentState?.collapse();
}
}
});
}
},
));
},
),
),
],
),
),
);
}
Now it is started showing above the bottom navigation.

Related

Flutter : Incorrect use of ParentDataWidget

I have a screen layout like newsfeed instagram
When I come to this screen I got issue like this
problem
I have parent screen where place the bottom bar :
return Scaffold(
body: homeScreenItems[_page],
bottomNavigationBar: Offstage(
offstage: isSwipeLeft,
child: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
label: '',
backgroundColor: primaryColor,
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
),
label: '',
backgroundColor: primaryColor),
BottomNavigationBarItem(
icon: Icon(
Icons.video_camera_back_outlined,
),
label: '',
),
BottomNavigationBarItem(
icon: Icon(
Icons.favorite,
),
label: '',
backgroundColor: primaryColor,
),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
),
label: '',
backgroundColor: primaryColor,
),
],
onTap: onPageChanged,
currentIndex: _page,
backgroundColor: (_page != 2) ? primaryColor : blackColor,
type: BottomNavigationBarType.fixed,
selectedItemColor: (_page != 2) ? blackColor : primaryColor,
unselectedItemColor: secondaryColor,
),
),
);
This is the place where I code of newsfeed:
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor:
width > webScreenSize ? webBackgroundColor : primaryColor,
appBar: width > webScreenSize
? null
: AppBar(
backgroundColor: primaryColor,
centerTitle: false,
title: SvgPicture.asset(
'assets/ic_instagram.svg',
color: blackColor,
height: 32,
),
actions: [
IconButton(
icon: const Icon(
Icons.add_box_outlined,
color: blackColor,
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.messenger_outline_rounded,
color: blackColor,
),
onPressed: onPress,
),
],
automaticallyImplyLeading: false,
),
body: PageStorage(
bucket: bucketGlobal,
child: ListView.builder(
itemBuilder: (context, index) {
return ItemFeed(
userModel: DataDefault.userModelDemo,
index: index,
);
},
itemCount: DataDefault.userModelDemo.length,
key: PageStorageKey<String>('listFeed'),
shrinkWrap: true,
padding: EdgeInsets.all(5),
scrollDirection: Axis.vertical,
),
),
);
Finally is where I placed feed_Item:
Widget buildFeedItem(List userModel, int index) {
return Column(
children: [
//header
Row(
children: [
CircleAvatar(
backgroundImage: AssetImage(
userModel[index]['userAvaUrl'],
),
),
SizedBox(
width: 5,
),
Text(
userModel[index]['userName'],
),
],
),
SizedBox(
height: 15,
),
//image post
GestureDetector(
onDoubleTap: () {
setState(() {
isLikeAnimating = true;
isHeartAnimating = true;
});
},
child: Stack(
alignment: Alignment.center,
children: [
// list postUrl
SliderImage(
listPost: userModel[index]['postUrl'],
),
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isLikeAnimating ? 1 : 0,
child: LikeAnimation(
isAnimating: isLikeAnimating,
child: Icon(
Icons.favorite,
color: isHeartAnimating ? errorColor : primaryColor,
size: 100,
),
duration: const Duration(
milliseconds: 400,
),
onEnd: () {
setState(() {
isLikeAnimating = false;
});
},
),
),
],
),
),
SizedBox(
height: 10,
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
// color: blueColor,
child: Row(
children: [
//icon like
CustomIcon(
child: Icon(
isHeartAnimating
? Icons.favorite_rounded
: Icons.favorite_border,
color: isHeartAnimating ? errorColor : blackColor,
size: 30,
),
onPress: () {
setState(() {
isLikeAnimating = true;
isHeartAnimating = !isHeartAnimating;
});
},
isAnimating: isLikeAnimating,
onEnd: () {
setState(
() {
isLikeAnimating = false;
},
);
},
),
SizedBox(
width: 10,
),
//icon comment
CustomIcon(
child: Icon(
Icons.chat_bubble_outline,
color: blackColor,
size: 30,
),
onPress: () {
setState(() {
isCommentAnimating = true;
});
},
isAnimating: isCommentAnimating,
onEnd: () {
setState(
() {
isCommentAnimating = false;
},
);
},
),
SizedBox(
width: 10,
),
//icon share
CustomIcon(
child: Icon(
Icons.send,
color: blackColor,
size: 30,
),
onPress: () {
setState(() {
isShareAnimating = true;
});
},
isAnimating: isShareAnimating,
onEnd: () {
setState(
() {
isShareAnimating = false;
},
);
},
),
//icon save
Expanded(
child: Align(
alignment: Alignment.bottomRight,
child: CustomIcon(
child: Icon(
isSave
? Icons.bookmark_added_rounded
: Icons.bookmark_border,
color: isSave ? saveColor : blackColor,
size: 30,
),
onPress: () {
setState(() {
isSaveAnimating = true;
isSave = !isSave;
});
},
isAnimating: isSaveAnimating,
onEnd: () {
setState(
() {
isSaveAnimating = false;
},
);
},
),
),
),
],
),
),
),
],
);
}
#override
Widget build(BuildContext context) {
return Container(
key: PageStorageKey<String>('listFeed'),
child: buildFeedItem(
widget.userModel,
widget.index,
),
);
}
Where did I do wrong? Please help me
Positioned need a StackParentData as it's parent.
But Column is not.
Put Positioned in Stack may resolve your problem.

How to import and use a function from another dart file in flutter

I am making a app in which I am using package snake bottom navigation and advanced drawer. Both are configured fine in a file but I'm having issue when when I want to use the function on a new page to open and close the drawer. I am unable to import it to my HomePage file where I am making the home page of the app. This code
void _handleMenuButtonPressed() {
_advancedDrawerController.showDrawer();
}
is the one creating issue in the drawer screen onpressed and on valuelistener.
Here is my Dashboard code which contains bottom nav and drawer:
class Dashboard extends StatefulWidget {
const Dashboard({Key? key}) : super(key: key);
#override
State<Dashboard> createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
final _advancedDrawerController = AdvancedDrawerController();
int _selectedIndex = 0;
final PageController _pageController = PageController();
ShapeBorder? bottomBarShape = const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(25)),
);
SnakeBarBehaviour snakeBarStyle = SnakeBarBehaviour.floating;
EdgeInsets padding = const EdgeInsets.all(12);
SnakeShape snakeShape = SnakeShape.circle;
bool showSelectedLabels = true;
bool showUnselectedLabels = true;
Color selectedColor = Colors.black;
Gradient selectedGradient =
const LinearGradient(colors: [Colors.red, Colors.amber]);
Color unselectedColor = Colors.black;
Gradient unselectedGradient =
const LinearGradient(colors: [Colors.black, Colors.black]);
Color? containerColor;
List<Color> containerColors = [
const Color(0xFFFDE1D7),
const Color(0xFFE4EDF5),
const Color(0xFFE7EEED),
const Color(0xFFF4E4CE),
];
#override
Widget build(BuildContext context) {
return AdvancedDrawer(
backdropColor: kblue,
controller: _advancedDrawerController,
animationCurve: Curves.easeInOut,
animationDuration: const Duration(milliseconds: 300),
animateChildDecoration: true,
rtlOpening: false,
disabledGestures: false,
childDecoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
),
drawer: SafeArea(
child: Container(
color: kblue,
child: ListTileTheme(
textColor: Colors.white,
iconColor: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 128.0,
height: 128.0,
margin: const EdgeInsets.only(
top: 24.0,
bottom: 64.0,
),
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Image.asset(
'assets/logo.png',
scale: 3,
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.home),
title: const Text(
'Home',
style: TextStyle(),
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.account_circle_rounded),
title: const Text(
'Profile',
style: TextStyle(),
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.notifications),
title: const Text(
'Notifications',
style: TextStyle(),
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.bug_report),
title: const Text(
'Report a bug',
style: TextStyle(),
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.logout),
title: const Text(
'Logout',
style: TextStyle(),
),
),
const Spacer(),
DefaultTextStyle(
style: const TextStyle(
fontSize: 12,
),
child: GestureDetector(
onTap: () {},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 16.0,
),
child: const Text(
'Terms of Service | Privacy Policy',
style: TextStyle(),
),
),
),
),
],
),
),
),
),
child: Scaffold(
extendBodyBehindAppBar: true,
resizeToAvoidBottomInset: true,
extendBody: true,
bottomNavigationBar: SnakeNavigationBar.color(
behaviour: snakeBarStyle,
snakeShape: snakeShape,
shape: bottomBarShape,
padding: padding,
snakeViewColor: selectedColor,
selectedItemColor: snakeShape == SnakeShape.indicator
? selectedColor
: Colors.orange,
unselectedItemColor: Colors.black,
showUnselectedLabels: showUnselectedLabels,
showSelectedLabels: showSelectedLabels,
currentIndex: _selectedIndex,
onTap: (index) => setState(() => _selectedIndex = index),
items: const [
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'tickets'),
BottomNavigationBarItem(
icon: Icon(Icons.person), label: 'calendar'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'home'),
BottomNavigationBarItem(
icon: Icon(Icons.person), label: 'microphone'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'search'),
],
selectedLabelStyle: const TextStyle(fontSize: 14),
unselectedLabelStyle: const TextStyle(fontSize: 10),
),
body: PageView(
controller: _pageController,
children: const <Widget>[
HomePage(),
HomePage(),
HomePage(),
HomePage(),
HomePage(),
],
onPageChanged: (page) {
setState(() {
_selectedIndex = page;
});
},
),
),
);
}
void _handleMenuButtonPressed() {
_advancedDrawerController.showDrawer();
}
}
Code to HomePage which contains the button to open and close the drawer and thats where the issue is:
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: SafeArea(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
onPressed: _handleMenuButtonPressed,
icon: ValueListenableBuilder<AdvancedDrawerValue>(
valueListenable: _advancedDrawerController,
builder: (_, value, __) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 250),
child: Icon(
value.visible ? Icons.clear : Icons.menu,
key: ValueKey<bool>(value.visible),
),
);
},
),
),
],
),
),
],
),
),
),
);
}
}
You can do it this way. There's no need to separate the files when you can do in one
class Dashboard extends StatefulWidget {
const Dashboard({Key? key}) : super(key: key);
#override
State<Dashboard> createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
final _advancedDrawerController = AdvancedDrawerController();
int _selectedIndex = 0;
final PageController _pageController = PageController();
ShapeBorder? bottomBarShape = const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
);
SnakeBarBehaviour snakeBarStyle = SnakeBarBehaviour.floating;
EdgeInsets padding = const EdgeInsets.only(top: 0);
SnakeShape snakeShape = SnakeShape.circle;
final double elevation = 4;
bool showSelectedLabels = true;
bool showUnselectedLabels = true;
Color selectedColor = Colors.white;
Gradient selectedGradient =
const LinearGradient(colors: [Colors.blue, Colors.pink]);
Color unselectedColor = Colors.black;
Gradient unselectedGradient =
const LinearGradient(colors: [Colors.black, Colors.black]);
Color? containerColor;
List<Color> containerColors = [
const Color(0xFFFDE1D7),
const Color(0xFFE4EDF5),
const Color(0xFFE7EEED),
const Color(0xFFF4E4CE),
];
#override
Widget build(BuildContext context) {
return AdvancedDrawer(
backdropColor: kblue,
controller: _advancedDrawerController,
animationCurve: Curves.easeInOut,
animationDuration: const Duration(milliseconds: 300),
animateChildDecoration: true,
rtlOpening: false,
disabledGestures: false,
childDecoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
),
drawer: SafeArea(
child: Container(
color: kblue,
child: ListTileTheme(
textColor: Colors.white,
iconColor: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 128.0,
height: 128.0,
margin: const EdgeInsets.only(
top: 24.0,
bottom: 64.0,
),
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Image.asset(
'assets/logo.png',
scale: 3,
),
),
ListTile(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const Dashboard()));
},
leading: const Icon(Icons.home),
title: const Text(
'Home',
style: TextStyle(),
),
),
ListTile(
onTap: () {},
leading: const Icon(Icons.account_circle_rounded),
title: const Text(
'Profile',
style: TextStyle(),
),
),
ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const NotificationsScreen()));
},
leading: const Icon(Icons.notifications),
title: const Text(
'Notifications',
style: TextStyle(),
),
),
ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ReportBug()));
},
leading: const Icon(Icons.bug_report),
title: const Text(
'Report a bug',
style: TextStyle(),
),
),
ListTile(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const LoginPage()));
},
leading: const Icon(Icons.logout),
title: const Text(
'Logout',
style: TextStyle(),
),
),
const Spacer(),
DefaultTextStyle(
style: const TextStyle(
fontSize: 12,
),
child: GestureDetector(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const TermsandPolicies()));
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 16.0,
),
child: const Text(
'Terms of Service | Privacy Policy',
style: TextStyle(),
),
),
),
),
],
),
),
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: const Color(0xFFFAFAFA),
elevation: 0,
centerTitle: true,
title: const Text(
'Dhrop',
style: TextStyle(
letterSpacing: 1,
color: Colors.black,
),
),
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: _handleMenuButtonPressed,
icon: ValueListenableBuilder<AdvancedDrawerValue>(
valueListenable: _advancedDrawerController,
builder: (_, value, __) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 250),
child: Icon(
value.visible ? Icons.clear : Icons.menu,
color: Colors.black,
key: ValueKey<bool>(value.visible),
),
);
},
),
),
),
extendBodyBehindAppBar: true,
resizeToAvoidBottomInset: true,
extendBody: true,
bottomNavigationBar: SnakeNavigationBar.color(
backgroundColor: kblue,
behaviour: snakeBarStyle,
snakeShape: snakeShape,
shape: bottomBarShape,
padding: const EdgeInsets.only(
bottom: 15,
left: 10,
right: 10,
),
snakeViewColor: selectedColor,
selectedItemColor:
snakeShape == SnakeShape.indicator ? selectedColor : kblue,
unselectedItemColor: Colors.black,
showUnselectedLabels: showUnselectedLabels,
showSelectedLabels: showSelectedLabels,
currentIndex: _selectedIndex,
onTap: (index) => setState(() => _selectedIndex = index),
items: [
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(
Icons.home,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const HomePage()));
},
),
// label: 'Home',
),
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(
Icons.search,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SearchPage()));
},
),
// label: 'Search',
),
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(
Icons.message,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MessagesPage()));
},
),
// label: 'Messages',
),
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(
Icons.luggage,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DropPage()));
},
),
// label: 'Drop',
),
],
selectedLabelStyle: const TextStyle(fontSize: 12),
unselectedLabelStyle: const TextStyle(fontSize: 14),
),
body: PageView(
controller: _pageController,
children: const <Widget>[
HomePage(),
SearchPage(),
MessagesPage(),
DropPage()
],
onPageChanged: (page) {
setState(() {
_selectedIndex = page;
});
},
),
),
);
}
void _handleMenuButtonPressed() {
_advancedDrawerController.showDrawer();
}
}

How can I make the on pressed function lead to a webpage?

I have this bit of code and I want the onPressed function for all options on my menu to open a url. I'm not entirely familar with this so I need a little help.
Here is my code below
class NewProfile extends StatefulWidget {
const NewProfile({Key key, this.scaffoldKey}) : super(key: key);
final GlobalKey<ScaffoldState> scaffoldKey;
_NewProfileState createState() => _NewProfileState();
}
class _NewProfileState extends State<NewProfile> {
Widget _menuHeader() {
final state = context.watch<AuthState>();
if (state.userModel == null) {
return ConstrainedBox(
constraints: BoxConstraints(minWidth: 200, minHeight: 100),
child: Center(
child: Text(
'Login to continue',
style: TextStyles.onPrimaryTitleText,
),
),
).ripple(() {
_logOut();
// Navigator.of(context).pushNamed('/signIn');
});
} else {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 120,
width: 120,
margin: EdgeInsets.only(left: 17, top: 10),
decoration: BoxDecoration(
border: Border.all(color: kPrimaryColor, width: 2),
borderRadius: BorderRadius.circular(200),
image: DecorationImage(
image: customAdvanceNetworkImage(
state.userModel.profilePic ?? Constants.dummyProfilePic,
),
fit: BoxFit.cover,
)),
),
SizedBox(
height: 20,
),
ListTile(
onTap: () {
Navigator.push(context,
ProfilePage.getRoute(profileId: state.userModel.userId));
},
title: Row(
children: <Widget>[
UrlText(
text: state.userModel.displayName ?? "",
style: TextStyles.onPrimaryTitleText
.copyWith(color: Colors.black, fontSize: 20),
),
SizedBox(
width: 3,
),
state.userModel.isVerified ?? false
? customIcon(context,
icon: AppIcon.blueTick,
istwitterIcon: true,
iconColor: AppColor.primary,
size: 18,
paddingIcon: 3)
: SizedBox(
width: 0,
),
],
),
subtitle: customText(
state.userModel.userName,
style: TextStyles.onPrimarySubTitleText
.copyWith(color: Colors.black54, fontSize: 15),
),
trailing: customIcon(context,
icon: AppIcon.arrowDown,
iconColor: AppColor.primary,
paddingIcon: 20),
),
Container(
alignment: Alignment.center,
child: Row(
children: <Widget>[
SizedBox(
width: 17,
),
_tappbleText(context, '${state.userModel.getFollower}',
' Connections', 'FollowerListPage'),
SizedBox(width: 10),
_tappbleText(context, '${state.userModel.getFollowing}',
' Mentors', 'FollowingListPage'),
],
),
),
],
),
);
}
}
Widget _tappbleText(
BuildContext context, String count, String text, String navigateTo) {
return InkWell(
onTap: () {
var authstate = context.read<AuthState>();
List<String> usersList;
authstate.getProfileUser();
Navigator.pop(context);
switch (navigateTo) {
case "FollowerListPage":
usersList = authstate.userModel.followersList;
break;
case "FollowingListPage":
usersList = authstate.userModel.followingList;
break;
default:
}
Navigator.push(
context,
FollowerListPage.getRoute(
profile: authstate.userModel, userList: usersList));
},
child: Row(
children: <Widget>[
customText(
'$count ',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 17),
),
customText(
'$text',
style: TextStyle(color: AppColor.darkGrey, fontSize: 17),
),
],
),
);
}
ListTile _menuListRowButton(String title,
{Function onPressed, IconData icon, bool isEnable = false}) {
return ListTile(
onTap: () {
if (onPressed != null) {
onPressed();
}
},
leading: icon == null
? null
: Padding(
padding: EdgeInsets.only(top: 5),
child: customIcon(
context,
icon: icon,
size: 25,
iconColor: isEnable ? AppColor.darkGrey : AppColor.lightGrey,
),
),
title: customText(
title,
style: TextStyle(
fontSize: 20,
color: isEnable ? AppColor.secondary : AppColor.lightGrey,
),
),
);
}
Positioned _footer() {
return Positioned(
bottom: 0,
right: 0,
left: 0,
child: Column(
children: <Widget>[
Divider(height: 0),
Row(
children: <Widget>[
TextButton(
onPressed: () {
Navigator.push(
context,
ScanScreen.getRoute(
context.read<AuthState>().profileUserModel));
},
child: Image.asset(
"assets/images/qr.png",
height: 25,
),
),
],
),
],
),
);
}
void _logOut() {
final state = Provider.of<AuthState>(context, listen: false);
Navigator.pop(context);
state.logoutCallback();
}
// ignore: unused_element
void _navigateTo(String path) {
Navigator.pop(context);
Navigator.of(context).pushNamed('/$path');
}
#override
Widget build(BuildContext context) {
return Center(
child: SafeArea(
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 45),
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Container(
child: _menuHeader(),
),
Divider(),
_menuListRowButton('Profile',
icon: AppIcon.profiles, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Help Center',
icon: AppIcon.helped, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Terms of Service',
icon: AppIcon.agreement, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Privacy Policy',
icon: AppIcon.privacy, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Cookie Use',
icon: AppIcon.cookies, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
Divider(),
_menuListRowButton('Logout',
icon: AppIcon.logout, onPressed: _logOut, isEnable: true),
],
),
),
_footer()
],
),
),
);
}
}
I want them to open to different urls on the web. If there is anything I should add such as dependencies or import any packages, please let me know.
You can navigate to a webpage with the Url Launcher package.
Future<void> launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}

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.

Flutter: How can I keep to my selected navigator when I'll go to a new screen and go back

I'm having a problem right now in my bottom navigation in flutter.
I have four navigation "Community, Feeds, Activity, Profile".
In my "Feeds" navigation I have a button named "View Profile" everytime I click that button it directs me to a new screen using
"Navigator.push(context, MaterialPageRoute())"
and I notice it auto generates a "<-" or "back arrow" icon on the appbar.
The problem is everytime I click that "back arrow", it redirects me to the first option on my navigation bar.
Not on the "Feeds" navigation.
Any tips how to fix this?
Here is my bottom navigation code:
_getPage(int page) {
switch (page) {
case 0:
return NewsFeed();
case 1:
return OrgAndNews();
case 2:
return MyActivity();
case 3:
return Profile();
}
}
int currentPage = 0;
void _onBottomNavBarTab(int index) {
setState(() {
currentPage = index;
});
}
return Scaffold(
body: Container(
child: _getPage(currentPage),
),
bottomNavigationBar: Container(
height: _height * .09,
child: BottomNavigationBar(
backgroundColor: Color(0xFFFFFFFF),
fixedColor: Color(0xFF121A21),
unselectedItemColor: Color(0xFF121A21),
currentIndex: currentPage,
onTap: _onBottomNavBarTab,
items: [
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.users),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('Community', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),
),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.newspaper),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Center(
child: Text('Feeds', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.listUl),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('My Activity', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.userAlt),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('Profile', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
],
),
),
);
My code for the page when you click the "View Profile":
class OrgProfile extends StatefulWidget {
OrgProfile(this.orgName) : super();
final String orgName;
#override
_OrgProfileState createState() => _OrgProfileState();
}
class _OrgProfileState extends State<OrgProfile> {
#override
final db = Firestore.instance;
Container buildItem(DocumentSnapshot doc) {
return Container(
child: Column(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: CircleAvatar(
radius: 70,
),
),
),
Text(
'${doc.data['Email']}',
style: TextStyle(color: Colors.black),
)
],
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.orgName),
),
body: StreamBuilder<QuerySnapshot>(
stream: db
.collection('USERS')
.where('Name of Organization', isEqualTo: widget.orgName)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList());
} else {
return SizedBox();
}
}),
);
}
}
My code when i click the "View Profile" button:
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new
OrgProfile(
doc.data['Name of Organization'])));
},
My feeds UI:
My View Profile UI:
Have you used MaterialPage Route With Builder Like This?
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new MyToDoThunder(),
),
)
Homepage Code :-
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
//
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
var db = DatabaseHelper();
int _selectedIndex = 0;
List<bool> textColorChange = [true, false, false, false];
final _widgetOptions = [
StatusPageRedux(),
RequestPage(),
NotificationPage(),
DashboardPage(),
];
_bottomNavigationView() {
return new Theme(
isMaterialAppTheme: true,
data: Theme.of(context)
.copyWith(canvasColor: Theme.of(context).primaryColor),
child: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
currentIndex: _selectedIndex,
fixedColor: Colors.white,
items: [
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Status.svg', height: 20.0, color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Status.svg', height: 20.0, color: Colors.white30),
title: new Text(
'Status',
style: TextStyle(
color: textColorChange[0] ? Colors.white : Colors.white30),
),
),
new BottomNavigationBarItem(
title: new Text(
'Requests',
style: TextStyle(
color: textColorChange[1] ? Colors.white : Colors.white30),
),
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Requests.svg', height: 20.0, color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Requests.svg',
height: 20.0,
color: Colors.white30),
),
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Notifications.svg',
height: 20.0,
color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Notifications.svg',
height: 20.0,
color: Colors.white30),
title: new Text(
'Notifications',
style: TextStyle(
color: textColorChange[2] ? Colors.white : Colors.white30),
),
),
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/dashboard.svg',
height: 20.0,
color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/dashboard.svg',
height: 20.0,
color: Colors.white30),
title: new Text(
'Dashboard',
style: TextStyle(
color: textColorChange[3] ? Colors.white : Colors.white30),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(child: _widgetOptions.elementAt(_selectedIndex)),
bottomNavigationBar: _bottomNavigationView(),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
for (int i = 0; i < textColorChange.length; i++) {
if (index == i) {
textColorChange[i] = true;
} else {
textColorChange[i] = false;
}
}
});
}
}
You will have to add your way back to the stack.
Try the below appbar in you 'tuloung duloung' title page, it should do the trick.
Note if your homescreen has tabs its advised to pass the index of the page you want to reach on exiting 'tuloung duloung'.
Let me know if it helps.
AppBar(
backgroundColor: Colors.transparent,
centerTitle: false,
brightness: Brightness.dark,
title: Container(
width: 150,
child: Row(
children:[
IconButton(icon:Icons.back_arrow,
onpressed:() =>
Navigator.pushReplacementNamed(context, '/Your Home_Screen');
),
Text('tuloung duloung',
style: TextStyle(
fontWeight: FontWeight.w400,
color: theme.primaryColor,
)),
]
),
),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: theme.primaryColor,
),
actions:[ Container(
width: 150,
child: FlatButton.icon(
label: Text('Done'),
icon: Icon(Icons.check_circle),
onPressed: () => {
setState(() {
takingsnap = true;
_captureImage();
})
}),
),
]
),