从其他小部件获取变量值

时间:2020-07-20 14:24:35

标签: flutter dart

我想要的是,当我单击切换按钮时,Option1Content小部件中的文本应更改为true或false(取决于切换的当前值)。当您单击磁贴,从抽屉中选择一个不同的选项,然后返回到选项1时,该值是正确的。我的要求是,当我按下切换磁贴时,Option1Content的值应立即更改。有关功能参考:https://dartpad.dev/c9cabc35a0bda57758b1d1cf07f8a823。任何帮助将不胜感激。谢谢。

import 'package:flutter/material.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatefulWidget{
  MyWidgetState createState()=> MyWidgetState();
}
class MyWidgetState extends State<MyWidget> {
  bool status;
  Widget myBody;
  GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  
   void closeDrawer() {
    if (_scaffoldKey.currentState.isDrawerOpen) {
      _scaffoldKey.currentState.openEndDrawer();
    }
  }
  
  @override
  void initState(){
    super.initState();
    status = false;
    myBody = Option1Content(status:status);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key:_scaffoldKey,
    appBar:AppBar(
      iconTheme: IconThemeData(color: Colors.black),
      elevation:0,
      backgroundColor:Colors.transparent,
    actions:[
      Switch(
        inactiveThumbColor: Colors.black,
        activeColor: Colors.green,
        value:status,
        onChanged:(value){
          setState((){
            status=value;
          });
        })
    ]
    ),
      drawer: Drawer(
        child:Center(child:ListView(children:[
          DrawerHeader(
                      child: Column(
                        children: <Widget>[
                          CircleAvatar(
                            radius: 50,
                            backgroundColor: Colors.grey,
                          ),
                          Padding(
                            padding: const EdgeInsets.only(
                                left: 8.0, right: 8.0, top: 12.0),
                            child: Text(
                              'Account',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                              ),
                              textScaleFactor: 1.3,
                            ),
                          ),
                        ],
                      ),
                    ),
          ListTile(title:Center(child:Text('Option 1')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Option1Content(status:status);
            });
          }),
          ListTile(title:Center(child:Text('Option 2')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Center(child:Text('Option 2 Content'));
            });
          }),
          ListTile(title:Center(child:Text('Option 3')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Center(child:Text('Option 3 Content'));
            });
          }),
        ]))
      ),
      body: myBody
    );
  }
}



class Option1Content extends StatefulWidget {
  final bool status;
  Option1Content({@required this.status});

  @override
  _Option1ContentState createState() => _Option1ContentState();
}

class _Option1ContentState extends State<Option1Content> {

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('${widget.status}'),
    );
  }
}

1 个答案:

答案 0 :(得分:2)

问题在于,仅更改status的值并不会更新myBody中实际显示的内容。即使将status更改为setStatemyBody仍包含具有旧值status的窗口小部件。这就是为什么当您转到另一个myBody并对其进行更新的原因,因为myBody现在具有带有更新的status值的新窗口小部件。

要解决此问题,您需要一种方法来更新myBody中包含的内容,因为这是唯一要构建的部分。进行以下操作是最简单的更改。

只是改变

setState((){
  status = value;
});

setState((){
  status = value;
  myBody = Option1Content(status:status);
});

和完整代码:

import 'package:flutter/material.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyWidget(),
    );
  }
}

class MyWidget extends StatefulWidget{
  MyWidgetState createState()=> MyWidgetState();
}
class MyWidgetState extends State<MyWidget> {
  bool status;
  Widget myBody;
  GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  
   void closeDrawer() {
    if (_scaffoldKey.currentState.isDrawerOpen) {
      _scaffoldKey.currentState.openEndDrawer();
    }
  }
  
  @override
  void initState(){
    super.initState();
    status = false;
    myBody = Option1Content(status:status);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key:_scaffoldKey,
    appBar:AppBar(
      iconTheme: IconThemeData(color: Colors.black),
      elevation:0,
      backgroundColor:Colors.transparent,
    actions:[
      Switch(
        inactiveThumbColor: Colors.black,
        activeColor: Colors.green,
        value:status,
        onChanged:(value){
          setState((){
            status = value;
            myBody = Option1Content(status:status);
          });
        })
    ]
    ),
      drawer: Drawer(
        child:Center(child:ListView(children:[
          DrawerHeader(
                      child: Column(
                        children: <Widget>[
                          CircleAvatar(
                            radius: 50,
                            backgroundColor: Colors.grey,
                          ),
                          Padding(
                            padding: const EdgeInsets.only(
                                left: 8.0, right: 8.0, top: 12.0),
                            child: Text(
                              'Account',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                              ),
                              textScaleFactor: 1.3,
                            ),
                          ),
                        ],
                      ),
                    ),
          ListTile(title:Center(child:Text('Option 1')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Option1Content(status:status);
            });
          }),
          ListTile(title:Center(child:Text('Option 2')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Center(child:Text('Option 2 Content'));
            });
          }),
          ListTile(title:Center(child:Text('Option 3')),onTap:(){
            closeDrawer();
            setState((){
              myBody = Center(child:Text('Option 3 Content'));
            });
          }),
        ]))
      ),
      body: myBody
    );
  }
}



class Option1Content extends StatefulWidget {
  final bool status;
  Option1Content({@required this.status});

  @override
  _Option1ContentState createState() => _Option1ContentState();
}

class _Option1ContentState extends State<Option1Content> {

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('${widget.status}'),
    );
  }
}