如何管理两个不同的有状态小部件的状态

时间:2020-05-12 15:29:08

标签: flutter dart flutter-layout

小部件的基本轮廓如下所示。 MyListViewBuilder1 MyListViewBuilder2 这两个有状态小部件都在单独的dart文件中定义。它们都由ListViewBuilder组成。

我想要实现的是,当 MyListViewBuilder1 的项目被删除后,被删除的项目出现在 MyListViewBuilder2 中,但是问题是,只有当我重新启动屏幕时,这种情况才会发生。 那么我该如何解决呢?

当一个状态更改时,如何更改下一个状态?

Column(
children: <Widget>[
MyListViewBuilder1(),
MyListViewBuilder2()
  ]
)

1 个答案:

答案 0 :(得分:0)

您可以使用provider包来管理整个应用程序中不同小部件中的状态。在以下示例中,当在MyListViewBuilder1中删除项目时,该项目将从列表中删除,并添加到ItemChangeNotifier类中的已删除项目列表中。 MyListViewBuilder2有自己独立的项目列表,但是,在build方法中,它监视ItemChangeNofifier类中已删除项目列表的任何更改,并将这些已删除项目添加到自己的列表中独立的项目列表。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<ItemChangeNotifier>(
          create: (context) {
            return ItemChangeNotifier();
          },
        ),
      ],
      child: MyApp(),
    ),
  );
}

class Item {
  int id;
  String title;

  Item({
    this.id,
    this.title,
  });
}

class ItemChangeNotifier extends ChangeNotifier {
  final _deletedItems = <Item>[];

  List<Item> get deletedItems => List.unmodifiable(_deletedItems);

  void deleteItem(Item item) {
    _deletedItems.add(item);

    notifyListeners();
  }
}

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

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(
            child: MyListViewBuilder1(),
          ),
          Divider(
            thickness: 8,
          ),
          Expanded(
            child: MyListViewBuilder2(),
          ),
        ],
      ),
    );
  }
}

class MyListViewBuilder1 extends StatefulWidget {
  @override
  _MyListViewBuilder1State createState() => _MyListViewBuilder1State();
}

class _MyListViewBuilder1State extends State<MyListViewBuilder1> {
  List<Item> _items;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(_items[index].title),
          trailing: IconButton(
            icon: Icon(Icons.delete),
            onPressed: () {
              context.read<ItemChangeNotifier>().deleteItem(_items[index]);

              setState(() {
                _items.removeAt(index);
              });
            },
          ),
        );
      },
      itemCount: _items.length,
    );
  }

  @override
  void initState() {
    super.initState();

    _items = List.generate(
      10,
      (index) => Item(
        id: index + 1,
        title: 'Item ${index + 1}',
      ),
    );
  }
}

class MyListViewBuilder2 extends StatefulWidget {
  @override
  _MyListViewBuilder2State createState() => _MyListViewBuilder2State();
}

class _MyListViewBuilder2State extends State<MyListViewBuilder2> {
  List<Item> _items;

  @override
  Widget build(BuildContext context) {
    final items = [
      ..._items,
      ...context.select<ItemChangeNotifier, List<Item>>(
        (itemChangeNotifier) => itemChangeNotifier.deletedItems,
      ),
    ];

    return ListView.builder(
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(items[index].title),
        );
      },
      itemCount: items.length,
    );
  }

  @override
  void initState() {
    super.initState();

    _items = List.generate(
      10,
      (index) => Item(
        id: index + 101,
        title: 'Item ${index + 101}',
      ),
    );
  }
}