在Flutter中访问其子级中的父类变量?

问题描述

我正在尝试使用自定义的全状态PageWrapper小部件来包装我的所有页面。这样做的目的是使其返回一个脚手架,并使用相同的菜单抽屉和底部导航栏,并将适当的页面作为页面参数调用

我的bottomNavigationBar运行良好,并且我设置了正确的selectedindex,但是由于我不知道如何访问父级的子页面,所以找不到在子页面(即另一个文件)中访问它的方法。 selectedindex并从我的页面列表中显示适当的小部件。

import 'package:Flutter/material.dart';

class PageWrapper extends StatefulWidget {

  final Widget page;
  final AppBar appBar;
  final BottomNavigationBar bottomNav;
  final Color bckColor;

  PageWrapper({@required this.page,this.appBar,this.bckColor,this.bottomNav});

  @override
  _PageWrapperState createState() => _PageWrapperState();
}

class _PageWrapperState extends State<PageWrapper> {

  int _selectedindex;

  void _onItemTapped(int index) {
    setState(() {
      _selectedindex = index;
    });
  }

  @override
  void initState() {
    super.initState();
    _selectedindex = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: widget.appBar,backgroundColor: widget.bckColor,bottomNavigationBar: CustomBottomNavigation(selectedindex: _selectedindex,onItemTapped: _onItemTapped),body: widget.page,drawer: Drawer(...),);
  }
}

命名根源于我的main.dart中

home: PageWrapper(page: HomeScreen()),routes: {
  'form': (context) => PageWrapper(page: RoomService()),},

我想以某种方式在HomeScreen和RoomService屏幕中访问该底部导航栏的当前索引。有办法吗?

解决方法

您可以使用ProviderBloc之类的状态管理工具来解决此问题。为简单起见,请使用Provider进行操作。

在main.dart中用MaterialApp包装ChangeNotifierProvider

return MultiProvider(
  providers: [
    ChangeNotifierProvider<IndexModel>(
        create: (context) => IndexModel()),],child: MaterialApp(...)
);

创建一个将保存您的索引值的模型: 另外,您必须重写index的getter和setter才能在设置其值后调用notifyListeners。这是一个示例:

class IndexModel extends ChangeNotifier {
  int _index;
  get index => _index;
  set index(int index) {
    _index = index;
    notifyListeners(); //Notifies its listeners that the value has changed
  }
}

这里是根据数据索引显示数据的方式(理想情况下,您应该使用Selector而不是Consumer,以便只有在其监听的值发生更改时才重新构建窗口小部件):

@override
Widget build(BuildContext context) {
 //other widgets
 Selector<IndexModel,String>(
  selector: (_,model) => model.index,builder: (_,i,__) {
   switch(i){
     //do your returning here based on the index
      }
     },);
  }
 )
}

额外笔记。您可以通过以下方法在用户界面中访问ImageModel的值:

final model=Provider.of<IndexModel>(context,listen:false);
int index =model.index; //get index value
model.index=index; //set your index value

不听更改时,您必须通过listen:false。在initStateonPressed中访问它时,这是必需的。