【问题标题】:With flutter/Dart how can I use the BuildContext in an inherited class使用颤振/飞镖如何在继承的类中使用 BuildContext
【发布时间】:2020-02-29 06:33:40
【问题描述】:

我正在经历一些重构,以寻找适合我感受的 Flutter 架构/编码风格。我喜欢许多小的独立代码块。因此,例如,我正在尝试对 AppBar 小部件进行子类化。我遇到的问题是,在我的子类中,我无法访问最终顶级小部件的 BuildContext。在下面的 sn-p 中,我找不到用于切换页面的“导航器”,因为我没有要传递给“of(context)”的上下文。

那么,问题是:当我的后代类需要访问构建上下文时,我应该使用什么惯用模式来对有状态小部件(例如 AppBar)进行子类化?

感谢您的帮助。

import 'package:flutter/material.dart';

class MyBaseAppBar  extends AppBar {
  MyBaseAppBar( { actions, title }) : super( actions: actions, title: title);
}

class MyPageAppBar  extends MyBaseAppBar {
  static var myPageActions = <Widget>[
      IconButton( 
        icon: Icon(Icons.view_agenda), 
        onPressed: () =>Navigator.of( context ). pushNamed("agenda"))
  ];


  MyPageAppBar() : super( 
    title : Text("My App Bar"),
    actions : myPageActions
  );
}

class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyPageAppBar(),
      body: Container() // for example
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    在您的情况下,为什么不在 AppBar 构造函数中传递上下文?您还可以在无状态类中创建一个方法(调用 AppBar 并将其传递给扩展 AppBar 的构造函数的类。dart 中的函数是第一类对象,因此您可以将它们存储在变量中。记住要避免右括号作为参数传递时。

     class MyBaseAppBar  extends AppBar {  
        MyBaseAppBar( { actions, title, @required navigateTo}) : super( actions: actions, title: title);
      }
    
    class MyPageAppBar  extends MyBaseAppBar {
       final var NavigateTo; //you could use the Navigator Object instead for the Datatype
    
       static var myPageActions = <Widget>[
         IconButton( 
        icon: Icon(Icons.view_agenda), 
        onPressed: () =>Navigator.of( context ). pushNamed("agenda"))
       ];
    
    
      MyPageAppBar({@required this.navigateTo}) : super( 
       title : Text("My App Bar"),
       actions : myPageActions
        );
     }
    
    
    class MyStatelessWidget extends StatelessWidget {
      const MyStatelessWidget({Key key}) : super(key: key);
    
    NavigateToFunc( Build context context)
    { 
       // Code to route
     }
    
      @override
      Widget build(BuildContext context) {
         return Scaffold
         /// You should be able to access the context in the 
          MyPageAppBar as it has its own build method
         appBar: MyPageAppBar(navigateTo: NavigateToFunc),
         body: Container() // for example
    );
    

    } } 关于模式,有很多建议的技术来解决您的挑战。

    看看这个 https://flutter.dev/docs/development/data-and-backend/state-mgmt/options

    我倾向于使用 Provider 插件。您可以将父小部件包装在 ChangeNotifierProvider 中,而将在 Consumer 中更改的小部件(子部件)或使用 Provider.of.context 在小部件之间传递值。此外,您可能不需要将有状态小部件与提供程序一起使用。用 Consumer 包装改变状态的小部件

    【讨论】:

    • 谢谢,我对状态选项非常熟悉。这种事情是可能的(medium.com/flutter-community/…)。但是,在这种情况下,提供者等似乎有点矫枉过正/不优雅。使用上下文调用“AppBar”基类 BuildContext()。我觉得必须有一个惯用的继承机制来解决这个问题。
    【解决方案2】:

    我最终这样做了。 https://medium.com/flutter-community/navigate-without-context-in-flutter-with-a-navigation-service-e6d76e880c1c

    我仍然觉得为了更改页面而必须添加提供程序和服务是很蹩脚的,但可惜这似乎是唯一的方法。

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 2020-01-28
      • 2020-11-28
      • 2022-11-12
      • 2018-09-10
      • 2019-02-05
      • 2021-01-28
      • 1970-01-01
      • 2019-06-03
      相关资源
      最近更新 更多