gpt4 book ai didi

dart - 如何从另一个页面在底部导航栏中导航?

转载 作者:IT王子 更新时间:2023-10-29 06:57:22 27 4
gpt4 key购买 nike

我正在使用一个普通的底部导航栏,其本地状态包含当前所选页面的索引。当点击其中一个导航项时,将显示点击的页面:

class _HomePageState extends State<HomePage> {
int _selectedIndex = 1;

final _widgetOptions = [
Text('Index 0'),
Overview(),
Details(),
Text('Index 3'),
];

@override
Widget build(BuildContext context) {
return Scaffold(
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
...
currentIndex: _selectedIndex,
onTap: onTap: (index) => _selectedIndex = index,
),
);
}
}

如果你想从一个页面内部导航到另一个页面并更新底部导航栏的选定索引,如何继续?

示例:第 2 页是一个概览列表,其中包含列表项的 ID。如果您点击列表中的一个项目,它应该被导航到详细信息页面(底部导航栏中的 3)显示所选项目的详细信息,因此应该传递所选项目的 ID。

Navigator.of(context)... 无法使用,因为各个页面是导航栏的项目,因此不是路线。

最佳答案

您将需要一种更好的状态管理方式。我建议您使用 BLoC 模式来管理此小部件中的导航更改。我将在此处提供一个简化示例,说明如何通过一些评论和对改进的外部引用来执行此操作。

// An enum to identify navigation index
enum Navigation { TEXT, OVERVIEW, DETAILS, OTHER_PAGE}

class NavigationBloc {
//BehaviorSubject is from rxdart package
final BehaviorSubject<Navigation> _navigationController
= BehaviorSubject.seeded(Navigation.TEXT);
// seeded with inital page value. I'am assuming PAGE_ONE value as initial page.

//exposing stream that notify us when navigation index has changed
Observable<Navigation> get currentNavigationIndex => _navigationController.stream;

// method to change your navigation index
// when we call this method it sends data to stream and his listener
// will be notified about it.
void changeNavigationIndex(final Navigation option) => _navigationController.sink.add(option);

void dispose() => _navigationController?.close();
}

这个 bloc 类公开了一个流输出 currentNavigationIndexHomeScreen 将是此输出的监听器,它提供有关必须创建和显示在 Scaffold 小部件主体上的小部件的信息。请注意,流以 Navigation.TEXT 的初始值开始。

您的主页需要进行一些更改。现在我们正在使用 StreamBuilder 小部件来创建小部件并将其提供给 body 属性。换句话说,StreamBuilder 正在监听来自 bloc 的流输出,当接收到一些数据时,这将是一个 Navigation enum 值,我们决定应该在 body 上显示什么小部件。

class _HomePageState extends State<HomePage> {
final NavigationBloc bloc = new NavigationBloc();
int _selectedIndex = 0;

@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<Navigation>(
stream: bloc.currentNavigationIndex,
builder: (context, snapshot){
_selectedIndex = snapshot.data.index;

switch(snapshot.data){
case Navigation.TEXT:
return Text('Index 0');

case Navigation.OVERVIEW:
// Here a thing... as you wanna change the page in another widget
// you pass the bloc to this new widget for it's capable to change
// navigation values as you desire.
return Overview(bloc: bloc);
//... other options bellow
case Navigation.DETAILS:
return Details(/* ... */);
}
},
),

bottomNavigationBar: BottomNavigationBar(
//...
currentIndex: _selectedIndex,
onTap: (index) => bloc.changeNavigationIndex(Navigation.values[index]),
),
);
}
@override
void dispose(){
bloc.dispose();// don't forgot this.
super.dispoe();
}
}

由于您想在单击其他小部件中的特定项目时更改主页的主体小部件,例如 Overview,那么您需要将 bloc 传递给这个新小部件,当您单击在 item 中,您将新数据放入 Stream 中,主体将被刷新。请注意,这种将 BLoC 实例发送到另一个小部件的方法并不是更好的方法。我建议您看一下 InheritedWidget 模式。我在这里以一种简单的方式进行操作,以免写出已经存在的更大的答案......

class Overview extends StatelessWidget {
final NavigationBloc bloc;

Overview({this.bloc});

@override
Widget build(BuildContext context) {
return YourWidgetsTree(
//...
// assuming that when you tap on an specific item yout go to Details page.
InSomeWidget(
onTap: () => bloc.changeNavigationIndex(Navigation.DETAILS);
),
);
}
}

我知道这么多代码,这是一种复杂的方法,但就是这样。 setState 调用不会解决您的所有需求。看看这个article它是最好的和更大的之一,它以最少的细节讨论了我在这里写的所有内容。

祝你好运!

关于dart - 如何从另一个页面在底部导航栏中导航?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55742501/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com