Flutter feature discovery - DescribedFeatureOverlay for BottomNavigationBarItems - flutter

I'm using the package feature_discovery at version ^0.12.1. In order to display the feature discovery overlay, I need to wrap the BottomNavigationBarItem with a DescribedFeatureOverlay. However the BottomNavigationBar's items require a list of type BottomNavigationBarItem:
Scaffold(
[...]
bottomNavigationBar: BottomAppBar(
[...]
child: BottomNavigationBar(
[...]
items: [
DescribedFeatureOverlay( // This does not work because items requires type BottomNavigationBarItem
[...]
child: BottomNavigationBarItem(
icon: Icon(item.icon),
label: item.title,
),
),
],
),
),
);
The valid code would be like this:
Scaffold(
[...]
bottomNavigationBar: BottomAppBar(
[...]
child: BottomNavigationBar(
[...]
items: [
BottomNavigationBarItem( // need to wrap this with DescribedFeatureOverlay
icon: Icon(item.icon),
label: item.title,
),
],
),
),
);
I've been trying for so long now to find a solution to this.
How can I wrap the BottomNavigationBarItem with the DescribedFeatureOverlay?
Is this a limitation of Flutter or is there a way of doing this?
Do I need to copy, extend and modify the BottomNavigationBar class and use that one in order to achieve this?

As workaround you can wrap icon widget of BottomNavigationBarItem
like that
BottomNavigationBarItem(
icon: DescribedFeatureOverlay(
featureId: item.featureId,
title: Text(item.title),
description: Text(item.description),
backgroundColor: item.color,
tapTarget: Icon(item.icon),
child: Icon(item.icon),
),
label: item.title,
);

Related

Unformatted BottomNavigationBar Flutter

I created a simple bottom navigation bar, (my code below)...
bottomNavigationBar: BottomNavigationBar(
backgroundColor: COLOR_WHITE,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.account_circle_rounded),
label: 'Profile',
),
BottomNavigationBarItem(
label: 'something', icon: Icon(Icons.star)),
],
)
...but then I really wanted to click on the icons, so I tried adding an Icon Button for its onPressed() method.
bottomNavigationBar: BottomNavigationBar(
backgroundColor: COLOR_WHITE,
items: [
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(Icons.account_circle_rounded),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => ProfileScreen(userID :widget.userID)),
);
},
),
label: "Profile"
),
BottomNavigationBarItem(
label: 'something', icon: Icon(Icons.star)),
],
),
It gets all ugly, and I wanted the paddings and size all around to remain the same, but since I didn't add code to change those features, I don't get why it happened in the first place. Can someone help me solve it? Thanks!!
BottomNavigationBar has an onTap method you can use to trigger your callbacks so you don't need an IconButton. onTap gives you the index of the item tapped so you can map it to the appropriate page. You can also update the currentIndex property on the BottomNavigatorBar to highlight the appropriate item.
See this documentation for BottomNavigationBar for a good example: https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html
the mistake you have made was in the first BottomNavigationBarItem you have IconButton Widget and in second Icon widget... both having different styles by default(flutter developers gave default values for padding size etc)... so below code will work. i implemented locally and checked as well..
BottomNavigationBar(
backgroundColor: Colors.white,
items: [
BottomNavigationBarItem(
icon: IconButton(
icon: const Icon(Icons.account_circle_rounded),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) =>
ProfileScreen(userID:widget.userID)),
);
},[enter image description here][1]
),
label: "Profile"
),
BottomNavigationBarItem(
label: 'something', icon: IconButton(
icon: const Icon(Icons.star),
onPressed: () {
},
),),
],
)
enter image description here

How to prevent iphone notch from overlapping content in bookmarked desktop app?

I'm using SafeArea to display a bottom navigation bar :
SafeArea(
child: ScaffoldMessenger(
child: Scaffold(
body: _tabs[index],
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Theme.of(context).primaryColor,
unselectedItemColor: Colors.grey,
showUnselectedLabels: true,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today), label: "Agenda"),
BottomNavigationBarItem(
icon: Icon(Icons.people), label: "Patients"),
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet), label: "Comptes"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "Réglages"),
],
currentIndex: index,
onTap: (i) => context.read(navigationIndexProvider).index = i,
),
),
),
);
When bookmarked on iphone desktop, the safe area does not prevent the notch from overlapping the bottom navbar.
Here is the result :
How to properly prevent notch from overlapping the bottom bar ?
In SAFEAREA widget there is an argument -bottom
Set this bottom either true or false.
SafeArea(
bottom:true,
child:ScaffoldMessanger()
)
I don't remember the correct one, you can check both and let us know which one works for you.
I think since you're using bottomNavigationBar, the SafeArea should not be wrapped around Scaffold. It should be wrapped by Scaffold like this:
Scaffold(
body: SafeArea(child:
_tabs[index] ...
I think you should only wrap Scaffold with SafeArea when you're not using any kind of bottomNavigationBar

How to make Ink effect fill all the space in a BottomNavigationBarItem

I'm making a simple Flutter app with a BottomNavigationBar and the label in my BottomNavigationBarItem exceeds the ink effect created when I tap on it . For some reason, it seems to be covering the icon only and not the label as well.
How can I change this behavior to accommodate the label as well? I would also prefer to have a more rectangular shape for the ink reaction.
Edit:
My code for the navigation bar
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.blue[900],
unselectedItemColor: Colors.black87,
onTap: onTabTapped,
showUnselectedLabels: true,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.collections),
title: Text('Collections'),
),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
title: Text('Recent'),
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz),
title: Text('More'),
),
],
),
Current Behavior
Expected Behavior
After a few tries I figured that changing splashFactory could do the trick.
MaterialApp(
theme: ThemeData(
splashFactory: InkRipple.splashFactory,
),
)
After fiddling around with the flutter standard library, I now realised that BottomNavigationBarItem isn't a widget, but a container class to encapsulate the information that BottomNavigationBar need for its items.
Unfortunately, you will need to override BottomNavigationBar and create your own CustomBottomNavigationBar to do what you want.
The good news is that this is incredibly easy, since you only have to change one line of code. :)
I copied the code from $FLUTTER_HOME/packages/flutter/lib/src/material/bottom_navigation_bar.dart and made only one adjustment: at line 480, I changed InkResponse to InkWell and now it works as you wished.
With InkResponse:
With InkWell:
I suggest you to create an override folder in your project with the overridden classes, this is how I do it (I have overridden the default bottom sheet class):
Then, you can just import your overridden classes like this:
import 'package:your_project/widgets/override/bottom_navigation_bar.dart' as BottomNavigationBarOverride;
And use it like so:
bottomNavigationBar: BottomNavigationBarOverride.BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.blue[900],
unselectedItemColor: Colors.black87,
onTap: onTabTapped,
showUnselectedLabels: true,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.collections),
title: Text('Collections'),
),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
title: Text('Recent'),
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz),
title: Text('More'),
),
],
),
Old response
If you provide more code, I could help you out more.
Judging by the picture that you provided, this is intended behavior as bottom navigation itens aren't intended to be large. They are intend to be swift and clean as the material spec suggests:
If you intend to make only one "option", I suggest that you change your widget to a FlatButton. But be warned, this is against the spec as, for usability purposes, bottom navigation itens should contain at least 3 options and at max 5 options.

Error when loading an image from the assets

I am trying to use a PNG file as an icon image.
I have an assets folder in the root of my project.
The file's path is assets/icons/Dumbbell.png.
I loaded my assets in the pubspec file:
flutter:
uses-material-design: true
assets:
- assets/icons/
And in a Stateful widget's state I'm trying to use it:
#override
Widget build(BuildContext context) {
return Scaffold(
...
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
title: Text('Workout'),
icon: Image.asset(
'assets/icons/Dumbbell.png',
),
),
],
),
);
}
I just can't make it work!
EDIT: I removed the const keyword and added another BottomNavigationBarItem and now everything is working perfectly!
To fix your issue, just remove the const keyword because your icon is not constant and also you need at least two BottomNavigationBarItem widgets to make it work:
items: [
BottomNavigationBarItem(
title: Text('Workout'),
icon: Image.asset(
'assets/icons/Dumbbell.png',
),
),
BottomNavigationBarItem(
title: Text('Another item'),
icon: Image.asset(
'assets/icons/Dumbbell.png',
),
),
],
More info here: https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html
try this..
use ImageIcon class instead of Image.asset
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: ImageIcon(AssetImage("assets/mascot.png")),
title: Text("workout"),
),
],
),
try again with this demo
Image(image: AssetImage('assets/images/intro_0.jpg'),fit: BoxFit.fitWidth,)
diegoveloper's words is right. and BottomNavigationBar need two more items.
those code worked:
bottomNavigationBar:BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
title: Text('Workout'),
icon: Image(image: AssetImage('assets/images/intro_0.jpg'),fit: BoxFit.fitWidth,),
),
BottomNavigationBarItem(
title: Text('Workout'),
icon: Image(image: AssetImage('assets/images/intro_0.jpg'),fit: BoxFit.fitWidth,),
),
],
),

Flutter BottomNavigationBarItem accepts only Icon and no other widgets?

In our Flutter Cupertino project, we need to show a badge on one of the bottom bar icons. How many articles are already in the shopping cart to be precise.
I've tried different widgets and solutions provided here, but the BottomNavigationBarItem accepts only icon: Icon(..) and nothing else. If I, for example, put icon: Stack(..) instead of the icon: Icon(..), there are error messages shown, for example
"Invalid const value..."
Here is some sample code:
class CupertinoStoreHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('Kühlschrank'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text('Konto'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('Warenkorb'),
),
],
),
So if I can not put anything instead of the Icon(..). No other widget, no Stack(..).
Why? How can I put some other widget, like for example Badge(..):
badges: ^1.0.2
import 'package:badges/badges.dart';
This question is different from the possible duplicate, because I already tried the solution posted there and still can not use Stack(..) but only Icon(..).
I tried reproducing the problem, but it does work after changing a few things. First of all the icon property accepts a Widget and therefore not only an Icon, so this is not the problem.
I did notice however, in items: const <BottomNavigationBarItem>[ you should remove the const keyword as it is not necessary and also not constant.
And lastly, you need to add a tab builder to CupertinoTabScaffold this basically returns what's displayed above the bottom navigation bar.
Your final code then looks like this:
return CupertinoTabScaffold(
tabBuilder: (BuildContext context, int i) {
return CupertinoActivityIndicator();
},
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Badge(
badgeContent: Text('3'),
child: Icon(Icons.settings),
),
title: Text('Kühlschrank'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text('Konto'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('Warenkorb'),
),
],
),
);