访问在flutter中另一个有状态小部件中的一个有状态小部件中创

访问在flutter中另一个有状态小部件中的一个有状态小部件中创

本文介绍了如何访问在flutter中另一个有状态小部件中的一个有状态小部件中创建的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am stuck in my project where I have two stateful widgets created in flutter as two different dart files. Now, I have to access the instance of an object created in first widget in the second widget, but I am not so sure how I can do this in flutter when creating widgets.

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

One possible solution I thought of is to declare the two widgets in just one dart file instead of two dart files for two layouts, but I am curious if we can do it by declaring in two separate dart files.

我发布文件只是为了重现问题.

I have posted the files just to re-create the issue.

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

models.dart

class MyModel {

String name;
String emailId;
String password;

  }

secondwidget.dart

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'),),
        ),


      ],


    ),
  ),
);
}
}

推荐答案

根据您的用例,有很多方法可以做到这一点.这里有几个选项:

There are lots of ways to do this depending on your use case. Here are a few options:

  1. 您可以将创建的对象公开为您的 State 的公共成员.然后使用 GlobalKeycurrentState 属性/code> 在一个 State 中获取对另一个 State 的引用.现在您可以通过公共成员访问创建的对象.(注意:此模式限制了 State 的可测试性和封装性,因此请谨慎使用.)
  2. 两个小部件都可以有一个祖先小部件,它扩展了InheritedWidget 用于查找创建的对象.
  3. 两个小部件都可以在其构造函数中传递模型参数,例如 ValueNotifier.他们可以使用此对象来读取和写入值.
  1. You can expose the created object as public member of your State. Then use the currentState property of a GlobalKey in one State to get a reference to the other State. Now you can access the created object via the public member. (Note: This pattern limits the testability and encapsulation of your State, so use it sparingly.)
  2. Both widgets can have a ancestor widget that extends InheritedWidget that they use to look up the created object.
  3. Both widgets can be passed a model argument in their a constructor, such as a ValueNotifier. They can use this object to read and write the value.

如果您更详细地了解您的用例,我们可以帮助您选择一个有意义的模式.

If you go into more detail on your use case we can help you pick a pattern that makes sense.

这是一些实现选项 #1 的代码.

Here is some code implementing option #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;
          });
        },
      ),
    );
  }
}

这篇关于如何访问在flutter中另一个有状态小部件中的一个有状态小部件中创建的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 22:15