Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用提供程序重写嵌套的Navigator 2.0示例_Flutter_Dart_Flutter Web - Fatal编程技术网

Flutter 使用提供程序重写嵌套的Navigator 2.0示例

Flutter 使用提供程序重写嵌套的Navigator 2.0示例,flutter,dart,flutter-web,Flutter,Dart,Flutter Web,我想重写一下。具体地说,我想使用provider编写另一个实现来提升状态,而不是像这里使用ˋhandleBookTappedˋ那样将回调传递到页面 Q:如何使用提供程序将BookAppState传递到页面,同时正确更新外部和内部导航器,而不丢失选项卡的状态。 class InnerRouterDelegate extends RouterDelegate<BookRoutePath> with ChangeNotifier, PopNavigatorRouterDelegat

我想重写一下。具体地说,我想使用provider编写另一个实现来提升状态,而不是像这里使用ˋhandleBookTappedˋ那样将回调传递到页面

Q:如何使用提供程序将BookAppState传递到页面,同时正确更新外部和内部导航器,而不丢失选项卡的状态。

class InnerRouterDelegate extends RouterDelegate<BookRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<BookRoutePath> {
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  BooksAppState get appState => _appState;
  BooksAppState _appState;
  set appState(BooksAppState value) {
    if (value == _appState) {
      return;
    }
    _appState = value;
    notifyListeners();
  }

  InnerRouterDelegate(this._appState);

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: [
        if (appState.selectedIndex == 0) ...[
          FadeAnimationPage(
            child: BooksListScreen(
              books: appState.books,
              onTapped: _handleBookTapped,
            ),
            key: ValueKey('BooksListPage'),
          ),
          if (appState.selectedBook != null)
            MaterialPage(
              key: ValueKey(appState.selectedBook),
              child: BookDetailsScreen(book: appState.selectedBook),
            ),
        ] else
          FadeAnimationPage(
            child: SettingsScreen(),
            key: ValueKey('SettingsPage'),
          ),
      ],
      onPopPage: (route, result) {
        appState.selectedBook = null;
        notifyListeners();
        return route.didPop(result);
      },
    );
  }

  @override
  Future<void> setNewRoutePath(BookRoutePath path) async {
    // This is not required for inner router delegate because it does not
    // parse route
    assert(false);
  }

  void _handleBookTapped(Book book) {
    appState.selectedBook = book;
    notifyListeners();
  }
}

类InnerRouterDelegate扩展了RouterDelegate
使用ChangeNotifier、PopNavigatorRouterDelegateMixin{
最终GlobalKey navigatorKey=GlobalKey();
BooksAppState获取appState=>\u appState;
BooksAppState appState;
设置appState(BooksAppState值){
如果(值==\u应用状态){
返回;
}
_appState=值;
notifyListeners();
}
InnerRouterDelegate(此应用状态);
@凌驾
小部件构建(构建上下文){
返回导航器(
关键:导航工作,
页码:[
如果(appState.selectedIndex==0)[
FadeAnimationPage(
孩子:书单屏幕(
books:appState.books,
上装:上装把手,
),
key:ValueKey('BooksListPage'),
),
if(appState.selectedBook!=null)
材料页(
key:ValueKey(appState.selectedBook),
子项:BookDetailsScreen(书籍:appState.selectedBook),
),
]否则
FadeAnimationPage(
子项:设置屏幕(),
key:ValueKey('SettingsPage'),
),
],
onPopPage:(路线、结果){
appState.selectedBook=null;
notifyListeners();
返回路线.didPop(结果);
},
);
}
@凌驾
Future setNewRoutePath(BookRoutePath路径)异步{
//内部路由器委托不需要这样做,因为它不需要
//解析路由
断言(假);
}
空的(书本){
appState.selectedBook=book;
notifyListeners();
}
}
  • 在您的应用程序上添加
    MultiProvider
    (因为您可能会使用多个)
  • bottomNavigationBar上
    replace
    appState.
    by
    context.watch()。
    (注意,我使用enum作为索引,与官方示例略有不同)
  • bottomNavigationBar:
    底部导航栏(
    类型:BottomNavigationBarType.fixed,
    items:BottomNavigationBarItems.items(),
    currentIndex:context.watch()。已选择底部Navindex.index,
    //currentIndex:appState.selectedBottomNavIndex.index,//替换
    onTap:(新索引){
    context.read().selectedBottomNavIndex=NavItem.values[newIndex];
    //appState.selectedBottomNavIndex=NavItem.values[newIndex];//替换
    },
    ),
    

    这将使它与移动设备一起工作。还有很多web内容也需要更新,代码需要清理/删除
    appState
    变量已过时。

    @damian-k-bast您找到如何更新外部和内部委托了吗?我也有同样的问题。
        Future<void> main() async {
          WidgetsFlutterBinding.ensureInitialized();
        
          runApp(
            /// Providers are above [MyApp] instead of inside it, so that tests
            /// can use [MyApp] while mocking the providers
            MultiProvider(
              providers: [
                ChangeNotifierProvider(create: (_) => MyAppState()),
                //ChangeNotifierProvider(create: (_) => Counter()),
              ],
              child: RootRouter(),
            ),
          );
        
        }
    
    @override
      Widget build(BuildContext context) {
        var idx = context.watch<MyAppState>().selectedBottomNavIndex;
        return Navigator(
    ...
    
    bottomNavigationBar:
            BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              items: BottomNavigationBarItems.items(),
              currentIndex: context.watch<MyAppState>().selectedBottomNavIndex.index,
              //currentIndex: appState.selectedBottomNavIndex.index, //replace
              onTap: (newIndex) {
                context.read<MyAppState>().selectedBottomNavIndex= NavItem.values[newIndex];
                //appState.selectedBottomNavIndex = NavItem.values[newIndex]; //replace
              },
            ),