Как перестроить только измененный элемент в списке с помощью ChangeNotifier - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь получить данные с сервера. Когда кнопка нажата, фиктивный виджет добавляется в список, и после выборки данных отображается ответ. Я позвонил notifyListeners(), когда элемент добавлен в список и когда данные загружены, но все элементы перестраиваются, даже неизмененные элементы.

Как я могу предотвратить восстановление неизменного элемента?

Вот мой код.

class Item {
  bool isLoaded;

  String request;
  String data;

  Item(this.request) : isLoaded = false;

  Future loadItemData() {
    // dummy for api request
    return Future.delayed(Duration(seconds: 3)).whenComplete(() {
      data = "item get result";
      isLoaded = true;
    });
  }
}

class ItemList extends ChangeNotifier {
  List<Item> lists = [];

  void addItem(String request) {
    var item = Item(request);
    lists.add(item);

    item.loadItemData().whenComplete(() {
      notifyListeners();
    });
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ItemList(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: MyItems(),
      ),
    );
  }
}

class MyItems extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("My Items"),
      ),
      body: Consumer<ItemList>(
        builder: (context, value, child) {
          return Column(
            children: <Widget>[
              RaisedButton(
                child: const Text("Add Item"),
                onPressed: () {
                  value.addItem("dummy request id");
                },
              ),
              Expanded(
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    var item = value.lists[index];
                    return item.isLoaded
                        ? ListTile(
                            title: Text(value.lists[index].data),
                          )
                        : ListTile(
                            leading: CircularProgressIndicator(),
                          );
                  },
                  itemCount: value.lists.length,
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}

1 Ответ

0 голосов
/ 04 мая 2020

Используйте уникальные ключи с ListTile.

ListTile(
  key: ValueKey(value.lists[index].data['id']),
  ...
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...