Inside BottomNavigation I have 2 page. 1st Page loading data from the network and showing in SliverList and In another page showing static list data.
After moving from 1st to 2nd page then 1st page all network data are gone. I have used PageStorageKey but still, it's not working. but the 2nd page never reloaded.
Why is 1st page not saving its state which has StreamBuilder?
My code:
Bottom Navigation Page:
class MainActivity extends StatefulWidget {
@override
_MainActivityState createState() => _MainActivityState();
}
class _MainActivityState extends State<MainActivity> {
final Key keyHome = PageStorageKey('pageHome');
final Key keyChat = PageStorageKey('pageChat');
int currentTab = 0;
HomePage home;
Chat chat;
List<Widget> pages;
Widget currentPage;
final PageStorageBucket bucket = PageStorageBucket();
@override
void initState(){
home = HomePage(
key: keyHome,
);
chat = Chat(
key: keyChat,
);
pages = [home, chat];
currentPage = home;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageStorage(
child: currentPage,
bucket: bucket,),
//Bottom Navigation Bar added
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentTab,
onTap: (int index){
setState(() {
currentTab = index;
currentPage = pages[index];
});
},
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.chat), title: Text('Chat')),
BottomNavigationBarItem(
icon: Icon(Icons.payment), title: Text('Pay')),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle), title: Text('Me')),
],
//currentIndex: _selectedIndex,
fixedColor: Colors.deepPurple,
),
);
}
}
Home Page:
class HomePage extends StatefulWidget { HomePage({ Key key, }) : super(key: key); @override _HomePageState createState() => _HomePageState(); }
class _HomePageState extends State<HomePage>{
@override
Widget build(BuildContext context) {
final NewsCatalogBlog newsBloc = BlocProvider.of<NewsCatalogBlog>(context);
//bloc.fetchAllNews();
return Scaffold(
appBar: PreferredSize(child: HomePageGradientAppBar(),
preferredSize: const Size.fromHeight(100.0),),
body: StreamBuilder(
stream: newsBloc.outNewsList,
builder: (context, AsyncSnapshot<List<Data>> snapshot) {
Widget newsList;
newsList = new SliverList(
delegate: new SliverChildBuilderDelegate((context,index){
print("$index");
return NewsListRow(snapshot.data, newsBloc, index);
},
childCount: (snapshot.data == null ? 0 : snapshot.data.length) + 30),
);
return new CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(child: TabPanel(),),
SliverToBoxAdapter(child: UrlButtonPanel(),),
SliverToBoxAdapter(child: ChatNowAd(),),
newsList,
],
);
},
),
);
}
}
Chat Page:
class Chat extends StatelessWidget { Chat({ Key key, }): super (key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemExtent: 250.0,
itemCount: 20,
itemBuilder: (context, index) => Container(
padding: EdgeInsets.all(10.0),
child: Material(
elevation: 4.0,
borderRadius: BorderRadius.circular(5.0),
color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,
child: Center(
child: Text('Mir{$index}'),
),
),
),
);
}
}
However, unlike iOS, when we Navigator.push to a new screen, this bottomNavigationBar disappears. In my app, I want to fulfil this requirement: Home screen has a bottomNavigationBar with 2 items ( a & b) presenting screen A & B.
By default, screen A is displayed. Inside screen A, there is a button. Tap that button, Navigator.push to screen C. Now in screen C, we can still see the bottomNavigationBar. Tap item b, I go to screen B. Now in screen B, tap item a in the bottomNavigationBar, I go back to screen C (not A, A is currently below C in the navigation hierarchy).
I definitively recommend watching @amrnt video. But for those out there who want the straight answer, you need to instantiate a PageStorageKey for each page of your bottom bar sections and then make each page to receive its PageStorageKey via constructor. Better way is to use IndexedStack instead of PageStorage or AutomaticKeepAliveClientMixin.
Better way is to use IndexedStack instead of PageStorage or AutomaticKeepAliveClientMixin.
class _MainActivityState extends State<MainActivity> {
int _selectedPage = 0;
List<Widget> pageList = List<Widget>();
@override
void initState() {
pageList.add(HomePage());
pageList.add(ChatPage());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: IndexedStack(
index: _selectedPage,
children: pageList,
),
//Bottom Navigation Bar added
bottomNavigationBar: BottomNavigationBar(
.....
**IndexedStack Widget is sub-class of Stack Widget
It shows single child from list of provided Childs. Its size as big as largest child. It keep state of all Childs.**
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With