Как обновить данные в AnimatedList во Flutter

Как вы обновляете данные (добавляете, удаляете строки) в AnimatedList во Flutter? Я могу сделать это в ListView, просто обновив данные резервного копирования и позвонив setState. Например,

setState(() {
  _data.insert(2, 'pig');
});

Однако в AnimatedList это кажется более сложным.


person Suragch    schedule 26.01.2019    source источник


Ответы (1)


Ниже показаны различные способы обновления AnimatedList. Каждый раз процесс состоит из двух основных этапов:

  1. Обновите набор данных
  2. Уведомить глобальный ключ AnimatedList об изменении

Вставить один элемент

Добавьте «Свинья» в индекс 2.

введите описание изображения здесь

String item = "Pig";
int insertIndex = 2;
_data.insert(insertIndex, item);
_listKey.currentState.insertItem(insertIndex);

Вставить несколько элементов

Вставьте трех животных в индекс 2.

введите описание изображения здесь

final items = ['Pig', 'Chichen', 'Dog'];
int insertIndex = 2;
_data.insertAll(insertIndex, items);
// This is a bit of a hack because currentState doesn't have
// an insertAll() method.
for (int offset = 0; offset < items.length; offset++) {
  _listKey.currentState.insertItem(insertIndex + offset);
}

Удалить один элемент

Убрать «Свинью» из списка.

введите описание изображения здесь

int removeIndex = 2;
String removedItem = _data.removeAt(removeIndex);
// This builder is just so that the animation has something
// to work with before it disappears from view since the original
// has already been deleted.
AnimatedListRemovedItemBuilder builder = (context, animation) {
  // A method to build the Card widget.
  return _buildItem(removedItem, animation);
};
_listKey.currentState.removeItem(removeIndex, builder);

Удалить несколько элементов

Убрать из списка «Верблюд» и «Овца».

введите описание изображения здесь

int removeIndex = 2;
int count = 2;
for (int i = 0; i < count; i++) {
  String removedItem = _data.removeAt(removeIndex);
  AnimatedListRemovedItemBuilder builder = (context, animation) {
    return _buildItem(removedItem, animation);
  };
  _listKey.currentState.removeItem(removeIndex, builder);
}

Дополнительный код

main.dart

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('Update AnimatedList data')),
        body: BodyWidget(),
      ),
    );
  }
}

class BodyWidget extends StatefulWidget {
  @override
  BodyWidgetState createState() {
    return new BodyWidgetState();
  }
}

class BodyWidgetState extends State<BodyWidget> {

  // the GlobalKey is needed to animate the list
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();

  // backing data
  List<String> _data = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        SizedBox(
          height: 400,
          child: AnimatedList(
            key: _listKey,
            initialItemCount: _data.length,
            itemBuilder: (context, index, animation) {
              return _buildItem(_data[index], animation);
            },
          ),
        ),
        RaisedButton(
          child: Text(
            'Insert single item',
            style: TextStyle(fontSize: 20),
          ),
          onPressed: () {
            _onButtonPress();
          },
        )
      ],
    );
  }

  Widget _buildItem(String item, Animation animation) {
    return SizeTransition(
      sizeFactor: animation,
      child: Card(
        child: ListTile(
          title: Text(
            item,
            style: TextStyle(fontSize: 20),
          ),
        ),
      ),
    );
  }

  void _onButtonPress() {
    // replace this with method choice below
    _insertSingleItem();
  }

  void _insertSingleItem() {
    String item = "Pig";
    int insertIndex = 2;
    _data.insert(insertIndex, item);
    _listKey.currentState.insertItem(insertIndex);
  }

  void _insertMultipleItems() {
    final items = ['Pig', 'Chichen', 'Dog'];
    int insertIndex = 2;
    _data.insertAll(insertIndex, items);
    // This is a bit of a hack because currentState doesn't have
    // an insertAll() method.
    for (int offset = 0; offset < items.length; offset++) {
      _listKey.currentState.insertItem(insertIndex + offset);
    }
  }

  void _removeSingleItems() {
    int removeIndex = 2;
    String removedItem = _data.removeAt(removeIndex);
    // This builder is just so that the animation has something
    // to work with before it disappears from view since the original
    // has already been deleted.
    AnimatedListRemovedItemBuilder builder = (context, animation) {
      // A method to build the Card widget.
      return _buildItem(removedItem, animation);
    };
    _listKey.currentState.removeItem(removeIndex, builder);
  }

  void _removeMultipleItems() {
    int removeIndex = 2;
    int count = 2;
    for (int i = 0; i < count; i++) {
      String removedItem = _data.removeAt(removeIndex);
      AnimatedListRemovedItemBuilder builder = (context, animation) {
        return _buildItem(removedItem, animation);
      };
      _listKey.currentState.removeItem(removeIndex, builder);
    }
  }
}

Примечание

  • Если элементы вашего списка включают какие-либо виджеты с отслеживанием состояния, вам нужно будет предоставить им ключи, чтобы система могла их отслеживать.
  • Хотя я написал этот ответ до того, как написал статью о Medium, сейчас я поддерживаю мой ответ на Medium. Проверьте там последние обновления.
person Suragch    schedule 26.01.2019
comment
Можно ли обновить существующие данные в индексе, а не удалять и добавлять их снова? Например, у меня есть текст по индексу, и я хочу изменить текстовое значение. Как мне это сделать? - person Rakesh; 12.06.2020
comment
@Rakesh Вы можете использовать setState и просто обновить список данных. Я расширил свой ответ здесь, чтобы описать что. - person Suragch; 13.06.2020