如何将继承的小部件传递到整个Material App [英] How to Pass Inherited Widgets to Entire Material App

查看:77
本文介绍了如何将继承的小部件传递到整个Material App的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So i have an inherited widget that looks like :

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:

And a main.dart like this:

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 App及其所有路线,但似乎并没有将继承的小部件传递通过脚手架.从脚手架本身看来,我可以执行以下操作:

From what i've gotten from some guides this is how i should pass Inherited Widgets to my Material App and all its routes but it doesn't seem to be passing the Inherited Widget Past the Scaffold. From the Scaffold itself it seems like i'm able to do something like :

InheritedStateWidget.of(上下文)

InheritedStateWidget.of(context)

它将成功地带回我的Inherited Widget,但在currentPage Widget中,即HomePage(Stateful Widget).我似乎无法访问它,但我得到了

And it would successfully bring back my Inherited widget but while in the currentPage Widget i.e HomePage(Stateful Widget). I can't seem to access it and i get

未处理的异常:NoSuchMethodError:类"HomePageState"具有 没有实例getter'InheritedStateWidget'.接收方:的实例 "HomePageState"

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

我要去哪里错了?

推荐答案

我对您的前几类进行了稍微的重构:

I restructured your top few classes slightly:

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之间的接口,但这只是一个建议...

I prefer to strengthen the interface between the State and the InheritedWidget like this, but just a suggestion...

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的孩子都具有对状态(someString)的读取权限,并且必须通过调用方法(someFunction)对其进行修改.还有更多样板.

Any child now using the InheritedWidget just has read access to the state (someString) and has to modify it by calling methods (someFunction). There's a bit more boilerplate involved.

这篇关于如何将继承的小部件传递到整个Material App的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆