将数据传递给StatefulWidget并在Flutter中以其状态访问它

moo*_*der 58 dart flutter

我的Flutter应用程序中有2个屏幕:记录列表和用于创建和编辑记录的屏幕.

如果我将对象传递给第二个屏幕,这意味着我将编辑它,如果我传递null,则意味着我正在创建新项目.编辑屏幕是有状态的小部件,我不知道如何使用这种方法https://flutter.io/cookbook/navigation/passing-data/为我的情况.

class RecordPage extends StatefulWidget {
  final Record recordObject;

  RecordPage({Key key, @required this.recordObject}) : super(key: key);

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

class _RecordPageState extends State<RecordPage> {
  @override
  Widget build(BuildContext context) {
   //.....
  }
}
Run Code Online (Sandbox Code Playgroud)

如何访问recordObject里面_RecordPageState

dhu*_*981 113

要在_RecordPageState中使用recordObject,您必须像下面一样编写widget.objectname

class _RecordPageState extends State<RecordPage> {
  @override
  Widget build(BuildContext context) {
   .....
   widget.recordObject
   .....
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @hhk为什么有必要? (11认同)
  • 那些不熟悉Flutter的人,不要忘记定义像'@override RecordPage get widget => super.widget;'的小部件. (7认同)
  • `recordObject` 不应该是 `State` 类的一部分吗?从逻辑上讲,将其放在“StatefulWidget”中是不正确的(就内聚性而言)。此外,“StatefulWidget”的所有字段都应该是不可变的 - 如果您想更改“recordObject”引用怎么办? (4认同)
  • 似乎不再需要像 @hhk 的评论中那样定义小部件了。 (2认同)

San*_*inh 50

完整示例

您不需要使用它的构造函数将参数传递给 State。您可以使用widget.myField轻松访问这些。

class MyRecord extends StatefulWidget {
  final String recordName;
  const MyRecord(this.recordName);

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

class MyRecordState extends State<MyRecord> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.recordName); // Here you direct access using widget
  }
}
Run Code Online (Sandbox Code Playgroud)

当您导航屏幕时传递您的数据:

 Navigator.of(context).push(MaterialPageRoute(builder: (context) => MyRecord("WonderWorld")));
Run Code Online (Sandbox Code Playgroud)

  • 如果我需要改变它的值怎么办? (9认同)
  • 多年前[此处](/sf/answers/3520232271/)已经提到过这一点。在写你的答案之前,请先阅读其他答案。 (3认同)

小智 14

示例如下:

class nhaphangle extends StatefulWidget {
  final String username;
  final List<String> dshangle;// = ["1","2"];
  const nhaphangle({ Key key, @required this.username,@required this.dshangle }) : super(key: key);


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

class _nhaphangleState extends State<nhaphangle> {
  TextEditingController mspController = TextEditingController();
  TextEditingController soluongController = TextEditingController();
  final scrollDirection = Axis.vertical;
  DateTime Ngaysx  = DateTime.now();
  ScrollController _scrollController = new ScrollController();

  ApiService _apiService;
  List<String> titles = [];

  @override
  void initState() {
    super.initState();
    _apiService = ApiService();
    titles = widget.dshangle;  //here var is call and set to 
  }

    
Run Code Online (Sandbox Code Playgroud)


Joh*_*dge 12

class RecordPage extends StatefulWidget {
  final Record recordObject;

  RecordPage({Key key, @required this.recordObject}) : super(key: key);

  @override
  _RecordPageState createState() => new _RecordPageState(recordObject);
}

class _RecordPageState extends State<RecordPage> {
  Record  recordObject
 _RecordPageState(this. recordObject);  //constructor
  @override
  Widget build(BuildContext context) {.    //closure has access
   //.....
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不认为在“State”和“StatefulWidget”类中同时拥有“recordObject”字段是一个好主意(尽管我看到教程正是这样做的)。使用“State”类的“widget”字段访问“StatefulWidget”字段的方法似乎是更正确的方法(尽管它有自己的问题) (4认同)

小智 9

因此,您不必在状态类中创建任何新的对象或变量,您只需在有状态类中为您的对象定义一个最终且可为空的变量。你可以通过widget.类似的方式访问这个变量widget.recordObject

class RecordPage extends StatefulWidget {
   final Record? recordObject;
   RecordPage({required this.recordObject});
   @override
   _RecordPageState createState() => new _RecordPageState();
}

class _RecordPageState extends State<RecordPage> {
   @override
   Widget build(BuildContext context) {
      return Text(
         widget.recordObject == null? "the object is null" : "the object isn't null",
   );
 }
}
Run Code Online (Sandbox Code Playgroud)


Par*_*iya 5

通常,您不仅要导航到新屏幕,还要将数据传递到屏幕。例如,您可能希望传递有关已点击的项目的信息。

在本例中,创建一个待办事项列表。点击待办事项后,导航到显示有关记录的信息的新屏幕(小部件)。此配方使用以下步骤:

  • 定义一个 RecordObject 类。
  • 创建一个StatefulWidget. 我们称之为 RecordsScreen(用于:显示记录列表)。
  • 创建可以显示有关记录的信息的详细信息屏幕。
  • 导航并将数据传递到详细信息屏幕。

定义一个 RecordObject 类

class RecordsScreen extends StatefulWidget {
  List<RecordObject> records;
  RecordsScreen({Key key, @required this.records}) : super(key: key);
  @override
  _RecordsScreenState createState() => _RecordsScreenState();
}

class _RecordsScreenState extends State<RecordsScreen> {
  
  @override
  Widget build(BuildContext context) {
    widget.records = List<RecordObject>.generate(20,
          (i) => RecordObject(
        'Record $i',
        'A description of what needs to be done for Record $i',
      ),
    );
    return Scaffold(
      appBar: AppBar(
        title: Text('Records'),
      ),
      body: ListView.builder(
        itemCount:  widget.records.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text( widget.records[index].title),
            // When a user taps the ListTile, navigate to the DetailScreen.
            // Notice that you're not only creating a DetailScreen, you're
            // also passing the current todo through to it.
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailScreen(recordObject:  widget.records[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
    
Run Code Online (Sandbox Code Playgroud)

创建详细信息屏幕- 屏幕标题包含记录的标题,屏幕主体显示描述。

class DetailScreen extends StatefulWidget {
  // Declare a field that holds the RecordObject.
  final RecordObject recordObject;

  // In the constructor, require a RecordObject.
  DetailScreen({Key key, @required this.recordObject}) : super(key: key);

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

class _DetailScreenState extends State<DetailScreen> {
  @override
  Widget build(BuildContext context) {
    // Use the RecordObject to create the UI.
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.recordObject.title),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text(widget.recordObject.description),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明