在 Flutter 的 child 中访问 parent class 变量?

Access a parent class variable in its child in Flutter?

我正在尝试使用自定义的有状态 PageWrapper 小部件来包装我的所有页面。想法是把它return做成一个脚手架并使用相同的菜单抽屉和底部导航栏,并调用适当的页面作为页面参数。

我的 bottomNavigationBar 运行良好,我正在设置正确的 selectedIndex,但我无法在 child 页面(在另一个文件中)中找到访问它的方法,因为我没有知道如何访问 parent 的 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 中用 ChangeNotifierProvider 包裹 MaterialApp

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

创建一个模型来保存您的索引值: 此外,您必须覆盖索引的 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
      }
     },
   );
  }
 )
}

额外说明。以下是如何在 UI:

中访问 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.

中访问它时,这是必需的