BottomNavigationBar // Controlling Height with SizedBox leads to overflow - flutter

The goal:
Instead of using the hard coded height for the BottomNavigationBar, I want to size it as a fraction of the screen height.
My approach so far: I figured out that I can wrap the BottomNavigationBar in a SizedBox and control the height that way. Code at the botom.
The problem: I get overflows with the BottomNavigationBarItems on various devices.
I tried scaling the icons using the height of the SizedBox, but I need to make the items pretty small to avoid the overflow so that is not an option.
The code:
final bottomNavHeight = MediaQuery.of(context).size.heigth * 0.085;
bottomNavigationBar: SizedBox(
height: bottomNavHeight,
child: BottomNavigationBar(
onTap: _selectPage,
iconSize: bottomNavHeight * 0.45,
showSelectedLabels: false,
showUnselectedLabels: false,
currentIndex: _selectedPageIndex,
type: BottomNavigationBarType.fixed,
items: [
//home
BottomNavigationBarItem(
icon: Icon(Icons.home, color: _customColorScheme['Icon 1']),
activeIcon:
Icon(Icons.home, color: _customColorScheme['Icon 2']),
label: '',
),
//favorite
BottomNavigationBarItem(
icon:
Icon(Icons.favorite, color: _customColorScheme['Icon 1']),
activeIcon:
Icon(Icons.favorite, color: _customColorScheme['Icon 2']),
label: '',
),
//loockback
BottomNavigationBarItem(
icon: Icon(Icons.bar_chart,
color: _customColorScheme['Icon 1']),
activeIcon: Icon(Icons.bar_chart,
color: _customColorScheme['Icon 2']),
label: '',
),
//info & support
BottomNavigationBarItem(
icon: Icon(Icons.info, color: _customColorScheme['Icon 1']),
activeIcon:
Icon(Icons.info, color: _customColorScheme['Icon 2']),
label: '',
),

you can use like this like css break
final bottomNavHeight = getMyheight(context);
getMyheight(BuildContext context) {
var mheight = MediaQuery.of(context).size.height;
if (mheight < 300)
return mheight * 0.80;
else if (mheight < 400)
return mheight * 0.2;
else if (mheight < 500)
return mheight * 0.2;
else if (mheight < 600)
return mheight * 0.2;
else if (mheight < 800)
return mheight * 0.3;
else
return mheight * 0.085;
}
TIP
For Discrete jump i used windows run
NB: some packages dependent on platform so may exception so for ui testing it best discrete screen.
On Windows, desktop support is enabled on Flutter 2.10 or higher. On
macOS and Linux, desktop support is disabled by default in the stable
channel. You can manually enable it with one of these commands,
depending on which platform you are running:
flutter config --enable-macos-desktop
flutter config --enable-linux-desktop
flutter config --enable-windows-desktop
This package use to test different screen sizedevicepreview
device_preview: ^1.0.0

The bottom-overflow starts around <704. BottomNavigationBarItem's is not getting enough space.
You can remove SizedBox and just start with BottomNavigationBar, it will solve the issue.
bottomNavigationBar: BottomNavigationBar(....)

Related

Pie chart issues in flutter

I'm using the fl_chart package to create an interactive Pie Chart for my application. Although the design came out fine, I'm facing the following issues with the functionality:
Tapping on a particular PieChartSectionData doesn't always select it and even tapping repeatedly doesn't help. It's always two out of the three that are tappable. Please note that the functionality works as it should for all the sections but there is no indication suggesting that the section tapped on was clicked. As defined in my code, every tap on a section should increase the radius and it's font size to make it stand out from the rest.
Every time a PieChartSectionData is clicked, it is supposed to navigate to a new page after a delay of 500 milliseconds. Although this works as expected, I cannot seem to come back to the previous page that has the Pie Chart on it using the phone's back button on the very first click. It is only after repeated clicks that it takes me back to the original page.
The chart seems to be clickable even beyond the PieChartSectionData. So like let's say if I tap an inch away from one of the sections, it tends to take me to that other page I need to navigate to. This shouldn't be the case.
Here is my code:
class ToDoListPieState extends State<ToDoListPie> {
int? index;
double? percent;
int? taskCount;
#override
Widget build(BuildContext context) {
final provider = Provider.of<TodaysTaskList>(context).getToDoList;
// TODO: implement build
return Stack(
children: [
PieChart(PieChartData(
borderData: FlBorderData(show: false),
pieTouchData: PieTouchData(
touchCallback: (FlTouchEvent event, pieTouchResponse) {
setState(() {
if (pieTouchResponse == null ||
pieTouchResponse.touchedSection == null) {
index = -1;
}
index = pieTouchResponse!.touchedSection!.touchedSectionIndex;
});
Future.delayed(const Duration(milliseconds: 500), () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => TaskList())); //This here is the event where clicking on a section should take us to the next page
});
print('Index: $index'); //This prints even if we click away from a section
},
),
sectionsSpace: 5,
centerSpaceRadius: 80,
sections: [
PieChartSectionData(
color: Colors.blue,
title: provider['upcoming'].length.toString(),
value: double.parse(provider['upcoming'].length.toString()),
radius: index == 0 ? 40 : 30,
titleStyle: TextStyle(fontSize: index == 0 ? 25 : 16)),
PieChartSectionData(
color: Colors.amber,
title: provider['today'].length.toString(),
value: double.parse(provider['today'].length.toString()),
radius: index == -1 ? 40 : 30,
titleStyle: TextStyle(fontSize: index == -1 ? 25 : 16)),
PieChartSectionData(
color: Colors.red,
title: provider['previous'].length.toString(),
value: double.parse(provider['previous'].length.toString()),
radius: index == 1 ? 40 : 30,
titleStyle: TextStyle(fontSize: index == 1 ? 25 : 16))
])),
Positioned(
left: 0,
top: SizeVariables.getHeight(context) * 0.18,
right: 0,
bottom: 0,
child: Column(
children: [
FittedBox(
fit: BoxFit.contain,
child: Text(
'${provider['upcoming'].length + provider['today'].length + provider['previous'].length}',
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(fontSize: 25),
),
),
Text(
'Tasks',
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(fontSize: 18),
)
],
),
)
],
);
}
}
Any help will be appreciated!

The named parameter 'title' isn't defined. problem in flutter

new BottomNavigationBarItem(
icon: new Icon(Icons.home, color: (_page == 0) ?Color.fromRGBO(79, 119,45,1) : Color.fromRGBO(236, 243,158,1)),
title: new Container(height: 0.0),
It will be label as title is deprecated for that.
Follow this link : https://docs.flutter.dev/release/breaking-changes/bottom-navigation-title-to-label

How to prevent not to rebuild UI inside Index Stack

I'm using index stack in home screen to show different screen at one time.
My Problem is that child widget is rebuilt again and make API call when ever I re-enter to any screen
home screen code:
final _currentPage =
context.select<MenuProvider, int>((provider) => provider.currentPage);
void _onItemTapped(int index) {
Provider.of<MenuProvider>(context, listen: false)
.updateCurrentPage(index);
}
List<MenuItem> mainMenu = [
MenuItem(
AppLocalizations.of(context)!.sd_title,
'Home',
Icons.home,
0,
),
MenuItem(
AppLocalizations.of(context)!.profile_title,
'Profile',
Icons.person,
1,
),
MenuItem(
AppLocalizations.of(context)!.sd_calculator,
'Calculator',
Icons.calculate_rounded,
2,
),
];
var screens = [
mainMenu[_currentPage].index == 0 ? const HomeFragment() : Container(),
mainMenu[_currentPage].index == 1 ? const Profile() : Container(),
mainMenu[_currentPage].index == 2
? LoanCalculatorScreen(isHome: true)
: Container(),
];
var container = Container(
alignment: Alignment.center,
color: Colors.white,
child: FadeIndexedStack(
index: mainMenu[_currentPage].index,
children: screens,
),
);
Container is used in body of Scaffold.
Bottom Navigation:
bottomNavigationBar: BottomNavigationBar(
items: mainMenu
.map(
(item) => BottomNavigationBarItem(
label: item.bottomTitle,
icon: Icon(
item.icon,
),
),
)
.toList(),
currentIndex: _currentPage,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
)
Home screen: As statefull to make a call on init state;
#override
void initState() {
var homeData = Provider.of<HomeProvider>(context, listen: false);
homeData.getOffersAndPartnersSlider();
super.initState();
}
I'm using Provider for state management and API call.
any suggestion will help me to write better code and make good performance.
I've Try Page View also same thing happen the inside child is rebuilt.
I just want to make The API call once.
To fix this I've made changes with Pages.
Declare list of pages above built method with PageStorageKey.
final List<Widget> pages = [
const HomeFragment(
key: PageStorageKey('Page1'),
),
const Profile(
key: PageStorageKey('Page2'),
),
Lo
LoanCalculatorScreen(key: const PageStorageKey('Page'), isHome: true),
];
And Call pages inside Indexed Stack Widgets Children
Container(
alignment: Alignment.center,
color: Colors.white,
child: FadeIndexedStack(
index: mainMenu[_currentPage].index,
children: pages,
),
)

flutter 1.23.0-18.1pre BottomNavigationBar deprecated 'title' use 'label'

The title part is giving an error telling me that i should use label instead.
The Error is:
info: 'title' is deprecated and shouldn't be used. Use "label" instead, as it allows for an improved text-scaling experience. This feature was deprecated after v1.19.0.. (deprecated_member_use at lib/Screens/hostHomePage.dart:49)
Hopefully someone can help me out?
BottomNavigationBarItem _buildNavigationItem(
int index, IconData iconData, String text) {
return BottomNavigationBarItem(
icon: Icon(
iconData,
color: AppConstants.nonSelectedIconColor,
),
activeIcon: Icon(
iconData,
color: AppConstants.selectedIconColor,
),
title: Text(
text,
style: TextStyle(
color: _selectedIndex == index
? AppConstants.selectedIconColor
: AppConstants.nonSelectedIconColor,
),
),
);
}
As I see in the documents the things you are mentioning are correct and to have it working you must use label and pass a string to it. And remove the title parameter wherein you pass a widget.
BottomNavigationBarItem _buildNavigationItem(
int index, IconData iconData, String text) {
return BottomNavigationBarItem(
icon: Icon(
iconData,
color: AppConstants.nonSelectedIconColor,
),
activeIcon: Icon(
iconData,
color: AppConstants.selectedIconColor,
),
label: text
);
}
This code should work out for you instead of the one you are writing right now. :-).
link to the newer documentation

Reduce top & bottom padding in BottomNavigationBar

I would like to reduce top and bottom padding of BottomNavigationBar but I want to keep the same icon height and the bar height to 50 pixels :
bottomNavigationBar: SizedBox(
height: 50,
child: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
elevation: 5.0,
currentIndex: 0,
items: buildBottomBarItems(),
),
)
the method to build bottom bar items :
List<BottomNavigationBarItem> buildBottomBarItems() {
List<BottomNavigationBarItem> _bottomBarItems = List();
List<String> _iconNames = ["home", "search", "plus", "heart"];
for (var i = 0; i < _iconNames.length; ++i) {
_bottomBarItems.add(
BottomNavigationBarItem(
icon: Container(
child: new Image.asset('assets/' + _iconNames[i] + '.png', width: 24, height: 24)
),
title: Text('')
)
);
}
}
(in the present case there is an overflow of 4.0 pixels). Thank you
To remove the default space in BottomNavigationBar set the selectedFontSize to 0.
It will remove the default space available for the text.
BottomNavigationBar(
selectedFontSize: 0.0,
)