flutter - 在 Flutter 中更新嵌套 CupertinoPageScaffold 中的 Scaffold-Properties

标签 flutter flutter-navigation flutter-cupertino

如何更新子小部件(页面)中根脚手架的某些属性。
这是我的根脚手架中的一个片段。

CupertinoPageScaffold(
      resizeToAvoidBottomInset:
          state.resizeToAvoidBottomInsets, //update this here
      child: CupertinoTabScaffold(
          controller: _tabController,
          tabBar: CupertinoTabBar(
            onTap: onTap,
            items: widget.items,
          ),
          tabBuilder: (BuildContext context, index) {
            return StatusBarPadding(child: _tabs[index]);
          }),
    ),
docs比如说,我应该添加一个监听器来避免嵌套脚手架(例如更新 resizeToAvoidBottomInset)。
但是,这仅适用于每个选项卡的一页。当我嵌套选项卡时,我无法再直接访问它们。
我尝试了两种解决方案,我将在下面解释(+问题):
解决方案 1:提供程序
我使用 Provider 来跟踪全局导航栏状态:
class NavbarState extends ChangeNotifier {
  bool _resizeBottom;

  NavbarState(this._resizeBottom);

  get resizeBottom => _resizeBottom;

  void setResizeBottom(bool state) {
    _resizeBottom = state;
    notifyListeners();
  }
}
然后在我的页面中,我使用 BlocProvider.of<NavbarState>(context).setResizeBottom(val) 在 initState-Method 中设置状态(分别为处置)。
这有 2 问题 :
  • 调用 notifyListeners 会在消费者中触发 setState 并且您不能在 initState 方法中调用 setState。
  • 我必须在每个 initState 和 dispose 方法中声明这一点。

  • 解决方案 2:块
    我再次拥有一个全局状态,但它不必从“ChangeNotifier”继承。我使用“NavbarBloc”类跟踪状态。
    然后我可以在 onGenerateRoute 中添加一个事件方法。这比提供者方法更方便,因为我只有一个地方可以管理这种状态。
    然而,还有一个大问题 :
    当我返回时,onGenerateRoute方法没有被调用,因此状态没有得到更新。
    最简单的解决方案是什么
    至少从应用程序开发人员的角度来看,如果我可以询问位于事件导航器中的当前小部件,那就太好了。
    导航栏示例
    这是给定cupertinotabscaffold的3个导航器的插图。
    3 Navigators while the 2nd is active
    中间的“堆栈”处于事件状态,最上面的小部件显示在屏幕上。因此,目前调整大小参数应该是假的。在堆栈之间导航(点击导航图标)时,应调整调整大小参数。此外,在单个堆栈(推送、弹出)之间导航时,还应调整调整大小参数(例如,在弹出时,参数应设置为 true)。
    我找不到类似的东西。因此我需要你的帮助。

    最佳答案

    用于设置状态如何将 setter 作为回调到 onTap ?

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return CupertinoApp(
          title: 'Flutter Demo',
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      var values = [
        [true, false],
        [false, true],
      ];
    
      int stackIndex = 0;
      bool _resizeToAvoidBottomInsets = true;
      set _resizeToAvoidButtomInsets(bool value) => setState(() {
            print("set _resizeToAvoidBottomInsets = $value");
            _resizeToAvoidBottomInsets = value;
          });
    
      void handleTap(int i) {
        print("tapped: $i");
        _resizeToAvoidBottomInsets = values[stackIndex][i];
      }
    
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold(
          resizeToAvoidBottomInset: _resizeToAvoidBottomInsets,
          child: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(icon: Icon(Icons.ac_unit)),
                BottomNavigationBarItem(icon: Icon(Icons.wb_sunny)),
              ],
              onTap: handleTap,
            ),
            tabBuilder: (BuildContext context, int index) {
              return CupertinoTabView(
                builder: (BuildContext context) {
                  return CupertinoPageScaffold(
                    navigationBar: CupertinoNavigationBar(
                      middle: Text('Page 1 of tab $index'),
                    ),
                    child: Center(
                      child: CupertinoButton(
                        child: Text(
                          'resizeToAvoidBottomInsets: $_resizeToAvoidBottomInsets',
                        ),
                        onPressed: () {
                          // set state and increment stack index before push
                          stackIndex++;
                          _resizeToAvoidButtomInsets = values[stackIndex][0];
                          Navigator.of(context).push(
                            CupertinoPageRoute<void>(
                              builder: (BuildContext context) {
                                return CupertinoPageScaffold(
                                  navigationBar: CupertinoNavigationBar(
                                    middle: Text('Page 2 of tab $index'),
                                  ),
                                  child: Center(
                                    child: CupertinoButton(
                                        child: Text(
                                          'resizeToAvoidBottomInsets: $_resizeToAvoidBottomInsets',
                                        ),
                                        onPressed: () {
                                          // set state and decrement stack index before pop
                                          stackIndex--;
                                          _resizeToAvoidButtomInsets =
                                              values[stackIndex][0];
                                          Navigator.of(context).pop();
                                        }),
                                  ),
                                );
                              },
                            ),
                          );
                        },
                      ),
                    ),
                  );
                },
              );
            },
          ),
        );
      }
    }
    
    

    关于flutter - 在 Flutter 中更新嵌套 CupertinoPageScaffold 中的 Scaffold-Properties,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69427510/

    相关文章:

    node.js - 通过 Json 发送到服务器时收到空映射

    php - 在 Flutter 中获取 pHp 数组或 map 作为 JSON 数据?

    flutter 。如何使容器比屏幕更宽?

    flutter - Flutter:子 block 正在初始化,但是数据尚未存储在shared_preferences中

    flutter - 如何在flutter中将文件路由到不同页面

    flutter - 物理后退按钮在 Flutter 中不起作用,我什至无法退出应用程序

    flutter - 如何在全局范围内使用这种方法?

    flutter - 如何在 Flutter 中更改 CupertinoDatePicker 的字体大小?

    flutter - 禁用 Flutter CupertinoDatePicker 中的特定日期

    flutter - 如何在 Flutter Cupertino 底部导航栏中导航到同级项