Flutter 颤振继承的小部件-缺少一些侦听器

Flutter 颤振继承的小部件-缺少一些侦听器,flutter,state,inherited-widget,Flutter,State,Inherited Widget,我正在努力让下面的内容发挥作用。未通过继承的小部件“AppStateProvider”获取对应用程序模型状态的更改。我已经设法让它与汇/流一起工作,但希望建立一个更简单的结构 这只是一个在各种应用模式之间切换的测试应用程序 少了什么 import 'package:flutter/material.dart'; void main() { runApp(AppStateProvider( child: RootPage(), appState: new AppState()

我正在努力让下面的内容发挥作用。未通过继承的小部件“AppStateProvider”获取对应用程序模型状态的更改。我已经设法让它与汇/流一起工作,但希望建立一个更简单的结构

这只是一个在各种应用模式之间切换的测试应用程序

少了什么

import 'package:flutter/material.dart';

void main() {
  runApp(AppStateProvider(
    child: RootPage(),
    appState: new AppState(),
  ));
}

enum AppMode { introduction, login, home }

class AppState {
  AppMode appMode;
  AppState({
    this.appMode = AppMode.introduction,
  });
}

class AppStateProvider extends InheritedWidget {
  final AppState appState;

  AppStateProvider({Key key, Widget child, this.appState})
      : super(key: key, child: child);

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

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

class RootPage extends StatelessWidget {
  AppMode _mode;

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Inherited Widget Test',
      theme: new ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: _body(context),
    );
  }

  Widget _body(BuildContext context) {
    final provider = AppStateProvider.of(context); //Registers as a listener
    final state = provider.appState;
    _mode = state.appMode;

    return new Stack(
      children: <Widget>[
        new Offstage(
          offstage: _mode != AppMode.introduction,
          child: new MaterialApp(
            home: ColorsListPage(
              color: Colors.red,
              targetAppMode: AppMode.login,
              title: "Intro",
            ),
          ),
        ),
        new Offstage(
          offstage: _mode != AppMode.login,
          child: new MaterialApp(
            home: ColorsListPage(
              color: Colors.blue,
              targetAppMode: AppMode.home,
              title: "Login",
            ),
          ),
        ),
        new Offstage(
          offstage: _mode != AppMode.home,
          child: new MaterialApp(
            home: ColorsListPage(
              color: Colors.green,
              targetAppMode: AppMode.introduction,
              title: "Home",
            ),
          ),
        ),
      ],
    );
  }
}

class ColorDetailPage extends StatefulWidget {
  final String title;
  final MaterialColor color;
  final int materialIndex;
  final AppMode targetAppMode;

  ColorDetailPage(
      {this.color, this.title, this.targetAppMode, this.materialIndex: 500});

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

class _ColorDetailPageState extends State<ColorDetailPage> {
  @override
  Widget build(BuildContext context) {
    final provider = AppStateProvider.of(context);

    return Scaffold(
      appBar: AppBar(
        backgroundColor: widget.color,
        title: Text(
          '$widget.title[$widget.materialIndex]',
        ),
      ),
      body: Container(
        color: widget.color[widget.materialIndex],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            provider.appState.appMode = widget.targetAppMode;
          });
        },
        heroTag: null,
      ),
    );
  }
}

class ColorsListPage extends StatefulWidget {
  final MaterialColor color;
  final String title;
  final ValueChanged<int> onPush;
  final AppMode targetAppMode;
  final List<int> materialIndices = [
    100,
    200,
    300,
    400,
    500,
    600,
    700,
    800,
    900,
  ];

  ColorsListPage({this.color, this.targetAppMode, this.title, this.onPush});

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

class _ColorsListPageState extends State<ColorsListPage> {
  @override
  Widget build(BuildContext context) {
    final provider = AppStateProvider.of(context);

    return new Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          backgroundColor: widget.color,
        ),
        body: Container(
          color: Colors.white,
          child: _buildList(context),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              provider.appState.appMode = widget.targetAppMode;
            });
          },
          heroTag: null,
        ));
  }

  Widget _buildList(BuildContext context) {
    return ListView.builder(
      itemCount: widget.materialIndices.length,
      itemBuilder: (BuildContext content, int index) {
        int materialIndex = widget.materialIndices[index];
        return Container(
            color: widget.color[materialIndex],
            child: ListTile(
                title: Text(
                  "$materialIndex",
                  style: TextStyle(fontSize: 24.0),
                ),
                trailing: Icon(Icons.chevron_right),
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => ColorDetailPage(
                              color: widget.color,
                              title: widget.title,
                              targetAppMode: widget.targetAppMode,
                              materialIndex: materialIndex,
                            )),
                  );
                }
                //onTap: () => onPush(materialIndex),
                ));
      },
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(AppStateProvider(
子项:RootPage(),
appState:新的appState(),
));
}
枚举应用模式{介绍,登录,主页}
类AppState{
AppMode-AppMode;
AppState({
this.appMode=appMode.introduction,
});
}
类AppStateProvider扩展了InheritedWidget{
最终AppState AppState;
AppStateProvider({Key,Widget子项,this.appState})
:super(key:key,child:child);
@凌驾
bool updateShouldNotify(InheritedWidget oldWidget)=>true;
的静态AppStateProvider(BuildContext上下文){
返回(context.inheritFromWidgetOfExactType(AppStateProvider)
作为AppStateProvider);
}
}
类RootPage扩展了无状态小部件{
应用模式(AppMode);;
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“继承的小部件测试”,
主题:新主题数据(
原始样本:颜色。蓝灰色,
),
主页:_body(上下文),
);
}
Widget_body(构建上下文){
final provider=AppStateProvider.of(context);//注册为侦听器
最终状态=provider.appState;
_mode=state.appMode;
返回新堆栈(
儿童:[
新后台(
后台:_mode!=AppMode.introduction,
孩子:新材料pp(
主页:彩色插页(
颜色:颜色,红色,
targetAppMode:AppMode.login,
标题:“简介”,
),
),
),
新后台(
后台:_mode!=AppMode.login,
孩子:新材料pp(
主页:彩色插页(
颜色:颜色,蓝色,
targetAppMode:AppMode.home,
标题:“登录”,
),
),
),
新后台(
后台:_mode!=AppMode.home,
孩子:新材料pp(
主页:彩色插页(
颜色:颜色。绿色,
targetAppMode:AppMode.introduction,
标题:“家”,
),
),
),
],
);
}
}
类ColorDetailPage扩展StatefulWidget{
最后的字符串标题;
最终材料颜色;
最终材料指数;
最终应用模式targetAppMode;
ColorDetailPage(
{this.color、this.title、this.targetAppMode、this.materialIndex:500});
@凌驾
_ColorDetailPageState createState()=>new_ColorDetailPageState();
}
类\u ColorDetailPageState扩展状态{
@凌驾
小部件构建(构建上下文){
最终提供者=AppStateProvider.of(上下文);
返回脚手架(
appBar:appBar(
backgroundColor:widget.color,
标题:正文(
“$widget.title[$widget.materialIndex]”,
),
),
主体:容器(
颜色:widget.color[widget.materialIndex],
),
浮动操作按钮:浮动操作按钮(
已按下:(){
设置状态(){
provider.appState.appMode=widget.targetAppMode;
});
},
heroTag:null,
),
);
}
}
类ColorsListPage扩展StatefulWidget{
最终材料颜色;
最后的字符串标题;
最终值在推送时更改;
最终应用模式targetAppMode;
最终清单重要性=[
100,
200,
300,
400,
500,
600,
700,
800,
900,
];
ColorsListPage({this.color,this.targetAppMode,this.title,this.onPush});
@凌驾
_ColorsListPageState createState()=>new_ColorsListPageState();
}
类_ColorsListPageState扩展状态{
@凌驾
小部件构建(构建上下文){
最终提供者=AppStateProvider.of(上下文);
归还新脚手架(
appBar:appBar(
标题:文本(widget.title),
backgroundColor:widget.color,
),
主体:容器(
颜色:颜色,白色,
子项:_构建列表(上下文),
),
浮动操作按钮:浮动操作按钮(
已按下:(){
设置状态(){
provider.appState.appMode=widget.targetAppMode;
});
},
heroTag:null,
));
}
小部件构建列表(构建上下文){
返回ListView.builder(
itemCount:widget.materialIndices.length,
itemBuilder:(构建上下文内容,int索引){
int materialIndex=widget.materialIndices[index];
返回容器(
颜色:widget.color[materialIndex],
孩子:ListTile(
标题:正文(
“$materialIndex”,
样式:TextStyle(fontSize:24.0),
),
尾随:图标(图标。右V形),
onTap:(){
导航器。推(
上下文
材料路线(
生成器:(上下文)=>ColorDetailPage(
颜色:widget.color,
标题:widget.title,
targetAppMode:widget.targetAppMode,
唯物指数:唯物指数,
)),
);
}
//onTap:()=>onPush(materialIndex),
));
},
);
}
}

您需要将您的
继承小部件
包装在
状态小部件

class _AppStateProvider extends InheritedWidget {
  final AppStateProviderState data;

  _AppStateProvider({Key key, @required Widget child, @required this.data})
      : super(key: key, child: child);

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

class AppStateProvider extends StatefulWidget {
  final Widget child;
  final AppState appState;

  AppStateProvider({
    @required this.child,
    @required this.appState,
  });

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

  @override
  AppStateProviderState createState() => AppStateProviderState(
        appState,
      );
}

class AppStateProviderState extends State<AppStateProvider> {
  AppState appState;

  AppStateProviderState(this.appState);

  void updateAppMode(AppMode appMode) {
    setState(() {
      appState.appMode = appMode;
    });
  }

  @override
  Widget build(BuildContext context) {
    return _AppStateProvider(
      data: this,
      child: widget.child,
    );
  }
}
您可以这样使用它:

  floatingActionButton: FloatingActionButton(
    onPressed: () {
      provider.updateAppMode(widget.targetAppMode);
    },
    heroTag: null,
  ),

谢谢。我确实得到了类似的工作。使用继承的小部件并不总是需要包装在有状态的小部件中。所以我很想知道为什么这里需要它。我希望有一个更简单的解决办法。那是很多锅炉板
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      provider.updateAppMode(widget.targetAppMode);
    },
    heroTag: null,
  ),