I was trying to stack widgets and display in bottom navigation bar. I tried placing the widgets within Column
which passed to bottomNavigationBar
. The result was the items of Column
or bottomNavigationBar blocking/covering the entire body
.
Then I wrapped the column within a Container
, the problem still persisted. I then tried giving the container a height, and the result was positive. The stacked bottom navigation bar was there at the bottom as I wanted. The only problem was bottom overflow as the height I passed was smaller to accommodate both the widgets in the column.
To fix this I decided to pass GlobalKeys
to each of the widgets in the column widget of used in the bottom navigation bar "stack". I am supposed to use the height
information that can be retrieved from the GlobalKeys
.
For this I created the function _heightOfStackedBNB
which takes GlobalKeys
as its parameters. Initially I used the function directly in the widget tree to check if its return value is greater than -1, but this was erratic of me. So, I instead decided to call the function in the initState
method as shown in the code below. The error is gone but now the stacked BottomNavigationBar is not displayed.
What am I doing wrong? Please help.
Code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(home: const MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<BottomNavigationBarItem>? _items = [];
String _value = "";
int _index = 0;
bool _showStackedBottomNavBar = false;
final GlobalKey keyStackedBNBContainer = GlobalKey();
final GlobalKey keyStackedBNB_BNB = GlobalKey();
List<int> _listHeightOfStackedBNB = [];
double _varForHeightOfStackedBNB = 0.0;
@override
void initState() {
super.initState();
if (_items != null) {
_items?.add(
BottomNavigationBarItem(icon: Icon(Icons.people), label: "People"),
);
_items?.add(
BottomNavigationBarItem(icon: Icon(Icons.weekend), label: "Weekend"),
);
_items?.add(
BottomNavigationBarItem(icon: Icon(Icons.message), label: "Message"),
);
}
_varForHeightOfStackedBNB = _heightOfStackedBNB(
keyStackedBNBContainer,
keyStackedBNB_BNB,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: const Text("Bottom sheet and navigation bar"),
),
body: Column(
children: [
Text("########## $_value"),
ElevatedButton(
onPressed: () {
if (_showStackedBottomNavBar) {
_showStackedBottomNavBar = false;
} else {
_showStackedBottomNavBar = true;
}
setState(() {});
},
child: Text("Click Me!"),
),
],
),
bottomNavigationBar:
(_showStackedBottomNavBar && _varForHeightOfStackedBNB > -1.0)
? Container(
height: _varForHeightOfStackedBNB,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
key: keyStackedBNBContainer,
padding: EdgeInsets.all(15.0),
height: 60.0,
width: double.infinity,
decoration: BoxDecoration(color: Colors.amberAccent),
child: const Text("Bottom Navigation Bar"),
),
BottomNavigationBar(
key: keyStackedBNB_BNB,
items: _items!,
currentIndex: _index,
onTap: (int newIndex) {
setState(() {
_index = newIndex;
_value = "Current value is: ${_index.toString()}";
});
},
),
],
),
)
: Container(height: 60.0, color: Colors.red),
);
}
double _heightOfStackedBNB(GlobalKey gk01, GlobalKey gk02) {
double totalHeight = 0.0;
bool isAnyHeightNull = false;
double height01 = 0.0;
if (gk01.currentContext?.size?.height == null) {
isAnyHeightNull = true;
height01 = gk01.currentContext?.size?.height ?? 0.0;
}
double height02 = 0.0;
if (gk02.currentContext?.size?.height == null) {
isAnyHeightNull = true;
height02 = gk02.currentContext?.size?.height ?? 0.0;
}
totalHeight = height01 + height02;
return isAnyHeightNull ? -1.0 : totalHeight;
}
}
Update: I tried using the following in the initState
but I'm still unable to get things working:
WidgetsBinding.instance.addPostFrameCallback((timestamp) {
setState(() {
_varForHeightOfStackedBNB = _heightOfStackedBNB(
keyStackedBNBContainer,
keyStackedBNB_BNB,
);
});
});
I assume since the stacked bottom navigation bar widget is not rendered (but would only if the condition is met), the value is being given as null. But I'm not sure.