• 1000 * Использование предоставленной BottomNavigationBar там, где это необходимо (в данном случае ProductScreen)
Но проблема в том, что когда я перехожу со страницы Page1 -> ProductScreen (щелкните контейнер «Go to Products» из PageOne) и обратно в ProductScreen -> Page2 (щелкните второй элемент в BottomNavigationBar), BottomNavigationBar не обновляется. Однако представление стека обновляется (отображает PageTwo). Не могли бы вы помочь мне понять, почему панель навигации не обновляется. Заранее спасибо.
Для этого я сохранил все классы в main.dart, как показано ниже.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => NavBar(),
),
],
child: MyApp(),
));
}
// navigation bar
class NavBar extends StatefulWidget with ChangeNotifier {
Function callBack;
int selectedIndex = 0;
NavBar({
this.callBack,
});
void setCallBack(Function callBack) {
this.callBack = callBack;
}
void setIndex(index) {
selectedIndex = index;
notifyListeners();
}
@override
_NavBarState createState() => _NavBarState();
}
class _NavBarState extends State<NavBar> {
void _onNavItemClicked(index) {
Navigator.of(context).popUntil(ModalRoute.withName('/'));
print("${widget.selectedIndex} => $index");
setState(() {
widget.setIndex(index);
});
widget.callBack(index);
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: widget.selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onNavItemClicked,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
title: Text("One"),
),
BottomNavigationBarItem(
icon: Icon(Icons.border_color),
title: Text("Two"),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text("Three"),
),
],
);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(),
routes: {
ProductScreen.routeName: (context) => ProductScreen(),
},
);
}
}
class HomeScreen extends StatefulWidget {
HomeScreen();
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _stackIndex = 0;
NavBar navBar;
@override
void initState() {
super.initState();
}
void _changeStackIndex(int index) {
setState(() {
_stackIndex = index;
});
}
@override
Widget build(BuildContext context) {
print("Homescreen rebuilding...");
navBar = Provider.of<NavBar>(context);
navBar.setCallBack(_changeStackIndex);
return Scaffold(
appBar: AppBar(
title: Text("Project Title"),
centerTitle: true,
),
bottomNavigationBar: navBar,
body: Center(
child: IndexedStack(
index: _stackIndex,
children: <Widget>[
PageOne(),
PageTwo(),
PageThree(),
],
),
),
);
}
}
class PageOne extends StatefulWidget {
@override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
List<int> intList = List.generate(20, (index) => index);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
GotoProductsLink(),
ListView.builder(
physics: ScrollPhysics(),
itemCount: 20,
shrinkWrap: true,
itemBuilder: (context, index) =>
SingleContainer("One: " + intList[index].toString()),
),
],
),
);
}
}
class PageTwo extends StatefulWidget {
@override
_PageTwoState createState() => _PageTwoState();
}
class _PageTwoState extends State<PageTwo> {
List<int> intList = List.generate(20, (index) => index);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
GotoProductsLink(),
ListView.builder(
physics: ScrollPhysics(),
itemCount: 20,
shrinkWrap: true,
itemBuilder: (context, index) =>
SingleContainer("Two: " + intList[index].toString()),
),
],
),
);
}
}
class PageThree extends StatefulWidget {
@override
_PageThreeState createState() => _PageThreeState();
}
class _PageThreeState extends State<PageThree> {
List<int> intList = List.generate(20, (index) => index);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 20,
shrinkWrap: true,
itemBuilder: (context, index) =>
SingleContainer("Three: " + intList[index].toString()),
);
}
}
class GotoProductsLink extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).pushNamed(ProductScreen.routeName);
},
child: Container(
alignment: Alignment.center,
color: Colors.blue,
width: double.infinity,
padding: EdgeInsets.all(20),
child: Text(
"Go to Products",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
class SingleContainer extends StatelessWidget {
String text;
SingleContainer(this.text);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey.withOpacity(0.1),
height: 100,
padding: EdgeInsets.all(30),
margin: EdgeInsets.only(bottom: 10),
child: Center(
child: Text(text),
),
);
}
}
////////////////////////////////////////
// this screen can be invoked from multiple pages
class ProductScreen extends StatefulWidget {
static String routeName = "/products";
@override
_ProductScreenState createState() => _ProductScreenState();
}
class _ProductScreenState extends State<ProductScreen> {
List<int> gridItems = List.generate(20, (index) => index);
@override
Widget build(BuildContext context) {
NavBar navBar = Provider.of<NavBar>(context);
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: navBar,
body: GridView.builder(
itemCount: 20,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
itemBuilder: (context, index) => Container(
color: Colors.blue.withOpacity(0.1),
child: Center(
child: Text("Single Product"),
),
),
),
);
}
}