Прокрутка до конца анимированного списка

#dart #flutter

#dart #трепетание

Вопрос:

У меня есть прокручиваемый AnimatedList элемент, и я хочу, чтобы всякий раз, когда новый элемент добавляется в конец списка, он прокручивался до конца.

Я пытаюсь применить эту форму кода ListView , но она не работает.

 import 'package:flutter/material.dart';

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  List<String> list = ["a", "a", "a", "a", "a", "a", "a"];
  final ScrollController _listScrollController = new ScrollController();
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: AnimatedList(
          key: _listKey,
          controller: _listScrollController,
          initialItemCount: list.length,
          itemBuilder: (BuildContext context, int index, Animation animation) {
            return FadeTransition(
              opacity: animation,
              child: Container(
                width: itemSize,
                height: itemSize,
                child: Text(list[index]),
              ),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(onPressed: _addNewItem),
    );
  }

  _addNewItem() {
    list.add(list.length.toString());
    _listKey.currentState.insertItem(
      list.length - 1,
      duration: Duration(seconds: 1),
    );

    _listScrollController.animateTo(
      _listScrollController.position.maxScrollExtent, // wrong value (this value is before add new item)
      duration: const Duration(milliseconds: 250),
      curve: Curves.ease,
    );
  }
}

  

Поэтому мне нужно немного изменить код прокрутки.

 const double itemSize = 40.0;

_listScrollController.animateTo(
   _listScrollController.position.maxScrollExtent   itemSize,
   duration: const Duration(milliseconds: 250),
   curve: Curves.ease,
);
  

Но для этого нужно жестко задать itemSize (itemSize) или использовать BuildLayout, RenderBox для определения размера нового элемента. У вас, ребята, есть какие-нибудь лучшие решения?

Ответ №1:

Проблема в том, что вы анимировали материал перед добавлением элемента. Для добавления элемента потребовалось 1 сек., используйте этот таймер, который будет запускаться через 1 сек.

 Timer(
  Duration(milliseconds: 1100),
  () {
    _listScrollController.animateTo(
      _listScrollController.position.maxScrollExtent,
      duration: const Duration(milliseconds: 250),
      curve: Curves.ease,
    );
  },
);
  

Замените ваш на мой.

 _addNewItem() {
  list.add(list.length.toString());
  _listKey.currentState.insertItem(
    list.length - 1,
    duration: Duration(milliseconds: 200),
  );

  Timer(
    Duration(milliseconds: 220),
    () {
      _listScrollController.animateTo(
        _listScrollController.position.maxScrollExtent,
        duration: const Duration(milliseconds: 500),
        curve: Curves.ease,
      );
    },
  );
}
  

Вывод:

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

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

1. Этот код не работает. _listScrollController.position.maxScrollExtent это значение перед добавлением нового элемента в список. Поэтому я должен жестко закодировать новый размер элемента _listScrollController.position.maxScrollExtent itemSize . Пожалуйста, еще раз внимательно прочитайте мой вопрос.

2. Используйте таймер анимация затухания будет анимирована перед прокруткой, чтобы мы могли пропустить анимацию затухания.

3. Я видел, что вы не принимаете ответы, ваш первоначальный пост был о том, как прокрутить до конца, я дал вам решение, оно работает так, как ожидалось. Но теперь вы пытаетесь выяснить какой-то нюанс в решении, чтобы у вас была причина / оправдание не принимать и поддерживать его. Это противоречит духу Stackoverflow. В любом случае, хорошего дня!

4. Если он просто прокручивается до конца, почему я должен использовать анимированный список в первую очередь, просто реорганизуйте его в ListView, и все будет работать так, как ожидалось. Я хочу, чтобы прокрутка анимированного списка заканчивалась добавлением нового элемента, анимация которого происходит одновременно. Так что я это не принимаю. Но я поддержу ваш ответ.