#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, и все будет работать так, как ожидалось. Я хочу, чтобы прокрутка анимированного списка заканчивалась добавлением нового элемента, анимация которого происходит одновременно. Так что я это не принимаю. Но я поддержу ваш ответ.