Флаттер отклонить элемент в анимированном списке не работает правильно

#flutter #dart #listview #animation #flutter-animatedlist

Вопрос:

Я использую AnimatedList в своем приложении Flutter. Он работает, но dismiss поведение-не является плавным, потому что отклоненный элемент изменяется на указанный выше элемент при переходе.

Вот видео с экрана для лучшего понимания. Сосредоточьтесь на тексте, он всегда меняется в середине перехода к тексту первого пункта («Hallo Das ist 1»).

Я следовал этому руководству, где вы также можете протестировать его на кодовом контроллере, где вы можете увидеть точно такое же поведение. Это не та желаемая анимация… Кто-нибудь знает, как я могу это исправить?

Вот как я отклоняю эти пункты:

  _removeMemoryAtIndex(int index, Month currentMonth) {
    listKey.currentState!.removeItem(
      index,
      (_, animation) => slideIt(
        context,
        currentMonth,
        0,
        CurvedAnimation(
            parent: animation,
            curve: Curves.easeIn,
            reverseCurve: Curves.easeOut),
      ),
      duration: Duration(
        milliseconds: 500,
      ),
    );

    Provider.of<MemoryImageProvider>(context, listen: false)
        .removeMemoryAt(index: index);
  }
 

и моя slideIt — функция для анимации:

 Widget slideIt(
    BuildContext context,
    Month currentMonth,
    int index,
    animation,
  ) {
    Memory memory = currentMonth.memories[index];
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(-1, 0),
        end: Offset(0, 0),
      ).animate(
        CurvedAnimation(
          parent: animation,
          curve: Curves.easeIn,
          reverseCurve: Curves.easeOut,
        ),
      ),
      child: Column(
        children: [
          MemoryTile(
            memory: memory,
            monthName: currentMonth.name,
            onTapped: () {
              _removeMemoryAtIndex(index, currentMonth);
              print('tap on ${memory.description}');
            },
          ),
          SizedBox(
            height: scaleWidth(20),
          ),
        ],
      ),
    );
  }
 

Если вам нужна дополнительная информация, просто дайте знать! Любая помощь приветствуется. Я надеюсь, что это можно как-то исправить…

Комментарии:

1. может быть, мы можем попробовать сделать его асинхронным, как _removeMemoryAtIndex(индекс int, текущий месяц месяца) асинхронным{ ключ списка ожидания.Текущее состояние! .Удалите элемент( ….

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

3. @YeasinSheikh removeItem -это не asnyc..

Ответ №1:

для этого мы можем создать временную модель данных, вот как это будет работать.

 
import 'package:flutter/material.dart';

class MemoryTile {
  int index;
  String name;
  MemoryTile({
    required this.index,
    required this.name,
  });
}

final items = List.generate(
  10,
  (index) => MemoryTile(
    index: index,
    name: "name $index",
  ),
);

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

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

class _AnimLtestState extends State<AnimLtest> {
  final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();

  // Remove the selected item from the list model.

  _removeMemoryAtIndex(int index, MemoryTile currentMonth) {
    var tempMOnth = currentMonth;

    listKey.currentState!.removeItem(
      index,
      (_, animation) => slideIt(
        context,
        tempMOnth,
        CurvedAnimation(
            parent: animation,
            curve: Curves.easeIn,
            reverseCurve: Curves.easeOut),
      ),
      duration: Duration(
        milliseconds: 500,
      ),
    );

    items.removeAt(index);
    // setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedList(
      key: listKey,
      initialItemCount: items.length,
      itemBuilder: (context, index, animation) => Container(
        child: InkWell(
          onTap: () {
            _removeMemoryAtIndex(index, items[index]);
          },
          child: slideIt(
            context,
            items[index],
            animation,
          ),
        ),
      ),
    );
  }

  Widget slideIt(
    BuildContext context,
    MemoryTile memory,
    animation,
  ) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(-1, 0),
        end: Offset(0, 0),
      ).animate(
        CurvedAnimation(
          parent: animation,
          curve: Curves.easeIn,
          reverseCurve: Curves.easeOut,
        ),
      ),
      child: Row(
        children: [
          CircleAvatar(
            child: Text(memory.index.toString()),
          ),
          Text("Name > ${memory.name}")
        ],
      ),
    );
  }
}

 

Ответ №2:

глупая ошибка… Если вы посмотрите на _removeMemoryAtIndex метод, который я всегда передавал 0 как индекс…