如何在flutter

时间:2017-10-03 10:46:25

标签: dart flutter

我被困在我的项目中,我有两个状态小部件在颤动中创建为两个不同的dart文件。现在,我必须访问第二个小部件中第一个小部件中创建的对象的实例,但我不确定在创建小部件时如何在颤动时执行此操作。

我想到的一个可能的解决方案是在一个dart文件中声明两个小部件而不是两个布局的两个dart文件,但我很好奇我们是否可以通过在两个单独的dart文件中声明来实现它。

我发布文件只是为了重新创建问题。

main.dart

 import 'package:flutter/material.dart';
 import 'package:untitled2/models.dart';
 import 'package:untitled2/secondwidget.dart';

void main() {
 runApp(new MaterialApp(
     home: new MyApp(),
 ),);
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
  }

      class _MyAppState extends State<MyApp> {
 final TextEditingController _nameController = new TextEditingController();
 final TextEditingController _emailIdController = new 
 TextEditingController();
 final TextEditingController _passwordController = new 
 TextEditingController();
 final TextEditingController _confirmPasswordController = new 
 TextEditingController();

 MyModel myModel = new MyModel();

 @override
 Widget build(BuildContext context) {
  return new MaterialApp(
  home: new Scaffold(
    body: new ListView(

      children: <Widget>[
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
              labelText: 'Enter your Name'
            ),
            controller: _nameController,
            onSaved: (String value){myModel.name = value;} ,
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'EmailId'
            ),
              controller: _emailIdController,
              onSaved: (String value){myModel.emailId = value;}
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Password'
            ),
              controller: _passwordController,
              onSaved: (String value){myModel.password = value;}
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Confirm Password'
            ),
            controller: _confirmPasswordController,

          ),
        ),
        new Container(
          child: new FlatButton(
            onPressed: ((){

              Navigator.push(context, new MaterialPageRoute(builder: (_) => 
         new SecondScreen(),),);

            }),
            child: new Text('Save'),),
        ),



      ],


      ),
     ),
    );
   }
  }

models.dart

class MyModel {

String name;
String emailId;
String password;

  }

secondwidget.dart

 import 'package:flutter/material.dart';


 class SecondScreen extends StatefulWidget {
 @override
 _SecondScreenState createState() => new _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
  home: new Scaffold(
    body: new ListView(

      children: <Widget>[
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Enter address'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Address Line 2'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Address Line 3'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'POST CODE'
            ),
          ),
        ),

        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Mobile Number'
            ),
          ),
        ),
        new Container(
          child: new FlatButton(
              onPressed: ((){


                //I want to push the data captured from main.dart and from 
                            //secondwidget.dart into database
     // I want to use the instance of MyModel from main.dart here to save 
      // the data captured from the first screen and this one into database

              }),
              child: new Text('Save'),),
        ),


      ],


    ),
  ),
);
}
}

3 个答案:

答案 0 :(得分:26)

根据您的使用情况,有很多方法可以做到这一点。以下是一些选项:

  1. 您可以将创建的对象公开为State的公共成员。然后在一个currentState中使用GlobalKeyState属性来获取对其他State的引用。现在,您可以通过公共成员访问创建的对象。 (注意:此模式限制了State的可测试性和封装,因此请谨慎使用。)
  2. 两个窗口小部件都可以有一个扩展InheritedWidget的祖先窗口小部件,用于查找创建的对象。
  3. 两个小部件都可以在构造函数中传递模型参数,例如ValueNotifier。他们可以使用此对象来读取和写入值。
  4. 如果您详细了解您的用例,我们可以帮助您选择一个有意义的模式。

    以下是一些实现选项#1的代码。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MyApp());
    }
    
    final key = new GlobalKey<MyStatefulWidget1State>();
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new Scaffold(
            body: new Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                new MyStatefulWidget1(key: key),
                new MyStatefulWidget2(),
              ],
            ),
          ),
        );
      }
    }
    
    class MyStatefulWidget1 extends StatefulWidget {
      MyStatefulWidget1({ Key key }) : super(key: key);
      State createState() => new MyStatefulWidget1State();
    }
    
    class MyStatefulWidget1State extends State<MyStatefulWidget1> {
      String _createdObject = "Hello world!";
      String get createdObject => _createdObject;
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Text(_createdObject),
        );
      }
    }
    
    class MyStatefulWidget2 extends StatefulWidget {
      State createState() => new MyStatefulWidget2State();
    }
    
    class MyStatefulWidget2State extends State<MyStatefulWidget2> {
      String _text = 'PRESS ME';
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new RaisedButton(
            child: new Text(_text),
            onPressed: () {
              setState(() {
                _text = key.currentState.createdObject;
              });
            },
          ),
        );
      }
    }
    

答案 1 :(得分:8)

您可以在构造SecondScreen小部件时传递模型。

  1. 将模型添加到SecondScreen构造函数:

    class SecondScreen extends StatefulWidget {
      final MyModel myModel;
    
      SecondScreen(MyModel myModel, {Key key}):
          super(key: key);
    ...
    }
    
  2. 在main.dart

    中构建SecondScreen时传递模型
    Navigator.push(context, new MaterialPageRoute(builder: (_) => 
      new SecondScreen(model)));
    
  3. 现在,您可以通过_SecondScreenState

  4. 访问widget.myModel中的模型

答案 2 :(得分:2)

这是我将参数传递给子窗口小部件的方式。

第一个Widget飞镖文件

class FirstWidget extends StatefulWidget {
    _FirstWidgetState createState() => _FirstWidgetState() 
}

class _FirstWidgetState extends State<FirstWidget> {
    String param = "My parameter";
    @override
    Widget build(BuildContext context) {
        return Container(
                    child: 
                        SecondWidget(param), //pass parmater here
                );
    }
}

第二个小部件的飞镖文件

class SecondWidget extends StatefulWidget {
    final String param; 
    SecondWidget(this.param); //passed paramter
    _SecondWidgetState createState() => _SecondWidgetState() 
}

class _SecondWidgetState extends State<SecondWidget> {
    @override
    Widget build(BuildContext context) {
        return Container(
                    child: 
                        Text(widget.param), //output paramter
                );
    }
}