flutter - 如何将继承的小部件传递给整个 Material 应用程序

标签 flutter

所以我有一个继承的小部件,看起来像:

class InheritedStateWidget extends StatefulWidget {
  final Widget child;

  InheritedStateWidget({
    @required this.child
  });

  @override
  InheritedStateWidgetState createState() => new InheritedStateWidgetState();

  static of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_MyInheritedWidget) as _MyInheritedWidget).data;
  }
}

class InheritedStateWidgetState extends State<InheritedStateWidget> {
  String _userName;

  // Getter methods
  String get tasks => _userName;

  void changeUserName(String name) {
    setState(() {
      _userName = name;      
    });
  }
  @override
  Widget build(BuildContext context) {
    return new _MyInheritedWidget(
      data: this,
      child: widget.child,
    );
  }

}

class _MyInheritedWidget extends InheritedWidget {
  final InheritedStateWidgetState data;

  _MyInheritedWidget({
    Key key,
    this.data,
    Widget child}): super(key: key, child: child);

    @override
    bool updateShouldNotify(_MyInheritedWidget old) {
      return true;
    }
}

还有一个像这样的 main.dart:

void main() => runApp(InheritedStateWidget(
  child: new Builder ( builder: (context) => new MyApp()))
  );

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'App One',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final PageStorageBucket bucket = PageStorageBucket();

  int currentTab;
  Widget currentPage;
  List<Widget> pages;
  HomePage one;
  ProfilePage two;

  @override
  void initState() {
    super.initState();
    one = HomePage(
      key: exploreKey,
    );
    two = Profile(
      key: myTasksKey,
    );

    pages = [one, two];

    currentPage = one;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("Testing"),),
      body: new PageStorage(
        bucket: bucket,
        child: currentPage,
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentTab,
        onTap: (int index) {
          setState(() {
            currentTab = index;
            currentPage = pages[index];
          });
        },
        type: BottomNavigationBarType.fixed,
        items: <BottomNavigationBarItem> [
          BottomNavigationBarItem(
            title: Text("Home"),
            icon: null
          ),
          BottomNavigationBarItem(
            title: Text("Profile"),
            icon: null
          )
        ],
      )
    );
  }
}

根据我从一些指南中得到的信息,这就是我应该如何将继承的小部件传递到我的 Material 应用程序及其所有路由,但它似乎并没有将继承的小部件传递给脚手架。从脚手架本身来看,我似乎可以做类似的事情:

InheritedStateWidget.of(context)

它会成功带回我的继承小部件,但在当前页面小部件中,即主页(有状态小部件)。我似乎无法访问它,但我得到了

Unhandled exception: NoSuchMethodError: Class 'HomePageState' has no instance getter 'InheritedStateWidget'. Receiver: Instance of 'HomePageState'

我哪里错了?

最佳答案

我稍微重组了你的前几个类:

import 'package:flutter/material.dart';

void main() => runApp(InheritedStateWidget());

class InheritedStateWidget extends StatefulWidget {
  @override
  InheritedStateWidgetState createState() => InheritedStateWidgetState();
}

class InheritedStateWidgetState extends State<InheritedStateWidget> {
  String _userName;

  // Getter methods
  String get tasks => _userName;

  void changeUserName(String name) {
    setState(() {
      _userName = name;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new MyInheritedWidget(
      data: this,
      child: MyApp(),
    );
  }
}

class MyInheritedWidget extends InheritedWidget {
  final InheritedStateWidgetState data;

  MyInheritedWidget({Key key, this.data, Widget child})
      : super(key: key, child: child);

  static MyInheritedWidget of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(MyInheritedWidget);

  @override
  bool updateShouldNotify(MyInheritedWidget old) => true;
}

class MyApp extends StatelessWidget {
  // in MyApp and below you can refer to MyInheritedWidget.of(context).data
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'App One',
      home: new MyHomePage(),
    );
  }
}

我更喜欢像这样加强State和InheritedWidget之间的接口(interface),但只是一个建议...

void main() => runApp(new Controller());

class Controller extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => ControllerState();
}

typedef void VoidIntFunction(int i);

class ControllerState extends State<Controller> {
  String someString = '';

  void someFunction(int v) {
    print('function called with $v');
  }

  @override
  Widget build(BuildContext context) {
    return StateContainer(
      someString: someString,
      someFunction: someFunction,
      child: new ExampleApp(),
    );
  }
}

class StateContainer extends InheritedWidget {
  final String someString;
  final VoidIntFunction someFunction;

  const StateContainer({
    this.someString,
    this.someFunction,
    Widget child,
  }) : super(child: child);

  static StateContainer of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(StateContainer);

  @override
  bool updateShouldNotify(StateContainer oldWidget) => true;
}

现在使用 InheritedWidget 的任何 child 都只能读取状态 (someString) 并且必须通过调用方法 (someFunction) 来修改它。涉及更多样板文件。

关于flutter - 如何将继承的小部件传递给整个 Material 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51441536/

相关文章:

Flutter 插件未安装错误;运行时 'flutter doctor'

flutter - 有什么解决方法可以使“喇叭形按钮”正常工作? flutter

Flutter ListView.Builder() 在可滚动列中与其他小部件

flutter - 如何修复工具栏中的 CircularProgressIndicator() 大小

flutter - flutter 选项卡是否可以具有不同的宽度并将剩余空间均匀分布为左右填充?

flutter - 如何将 onTap 添加到图像类别

flutter - 我是否需要删除存储在 path_provider.getTemporaryDirectory() 中的图像,因为我将其用作临时占位符?

android - 找不到资源样式/LaunchTheme

dart - 在不注销 Flutter/Dart 的情况下关闭应用程序

dart - 如何在 Cloud Firestore 中为将要更改的文档路径创建复合键