Flutter - 从 parent 更新 child 状态

Flutter - Update child state from parent

我想在 parent 中单击按钮时更新 child 的状态,例如:

class Parent extends StatelessWidget{
    Widget build(context){
    return Scaffold(
            appBar: AppBar(
                actions: <Widget>[
                    IconButton(
                            onPressed: () => //somehow increment the child's counter,
                            icon: const Icon(Icons.add),
                        ),
                    
                ],
            ),
            body: const Child(),
        );
    }
}

class Child extends StatefulWidget {
    const Child({Key? key}) : super(key: key);

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

class _ChildState extends State<Child> {
...
   int counter = 0; //to be incremented when parent's button is clicked on.
...
}

有没有通用的实现方法?从我读过的其他帖子中,人们通常使用 child 通过回调更新 parent 的状态,因此如果有一种方法可以重构我的代码以达到相同的效果,那将也帮忙。

您可以在父级中创建字段计数器并将其传递给子小部件并从父级更新子小部件。

你可以在这里查看我制作的演示.. DartPad Demo Link

状态管理方法

  1. 您可以使用 provider,bloc,cubit,getx... 包来更新子值和父值
  2. setstate回调(这里我提到)

像这样更改您的小部件。您的父小部件为有状态的。

int counter = 0;
class Parent extends StatefulWidget {
  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            onPressed: () {
              setState(() {
                counter++;
              });
            },
            icon: const Icon(Icons.add),
          ),
        ],
      ),
      body:  Child(),
    );
  }
}



class Child extends StatefulWidget {
   Child({Key? key}) : super(key: key);

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

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("$counter",style: TextStyle(fontSize: 30),));
  } //to be incremented when parent's button is clicked on.

SampleCod Dartpad live code check here

import 'package:flutter/material.dart';


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Parent(),
    );
  }
}

class Parent extends StatefulWidget {
  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            onPressed: () {
              setState(() {
                counter++;
              });
            },
            icon: const Icon(Icons.add),
          ),
        ],
      ),
      body:  Child(),
    );
  }
}

int counter = 0;

class Child extends StatefulWidget {
   Child({Key? key}) : super(key: key);

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

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("$counter",style: TextStyle(fontSize: 30),));
  } //to be incremented when parent's button is clicked on.

}

试试这个:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Parent(),
    );
  }
}

class Parent extends StatefulWidget {
  const Parent({Key? key}) : super(key: key);

  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  int counter = 0;

  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            tooltip: "Increment counter",
            onPressed: incrementCounter,
            icon: const Icon(
              Icons.add,
            ),
          ),
        ],
      ),
      body: Child(
        counter: counter,
      ),
    );
  }
}

class Child extends StatefulWidget {
  const Child({
    Key? key,
    required this.counter,
  }) : super(key: key);

  final int counter;

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

class _ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        widget.counter.toString(),
        style: const TextStyle(
          fontSize: 30,
        ),
      ),
    );
  }
}