#flutter
#flutter
Вопрос:
Я новичок в Flutter, и я столкнулся с проблемой.
Что у меня есть до сих пор, так это то, что я получаю данные из веб-службы асинхронно (Json). Итак, в методе сборки я использую FutureBuilder
виджет для аргумента тела Scaffold. И его аргумент ‘builder’ ( FutureBuilder
виджета) возвращает a ListView.builder
для отображения данных. Также я использую ScrollController
для прокрутки.
Когда я достигаю максимальной точки прокрутки, я снова вызываю службу, чтобы получить следующую страницу данных и так далее…
Проблема в том, что когда я «меняю страницу» с помощью прокрутки, данные отображаются правильно, но они начинаются с самой первой строки данных, а не с точки, в которой я достиг maxScrollExtent
точки.
Итак, если первый «снимок» содержит 25 строк, а второй — 15, когда я перехожу ко второму, он начинается со строки 1, а не со строки 26, хотя общее количество строк данных правильно равно 40.
В результате у меня нет плавной прокрутки. Я застрял на достаточно долгое время до этого момента, и я не знаю, чего мне не хватает. Должен ли я использовать ключи хранения страниц (я видел видео от команды flutter, но я не нашел решения своей проблемы). Какие-либо подсказки? Далее следует пример кода.
class _MyAppState extends State<MyApp> {
final ScrollController _controller = ScrollController();
@override
void initState() {
super.initState();
_controller.addListener(_scrollListener);
}
void _scrollListener() {
if (_controller.offset >= _controller.position.maxScrollExtent amp;amp;
!_controller.position.outOfRange) {
if (nextDataSet != null) {
print('nextDataSet = ' nextDataSet);
setState(() {
inDataSet = nextDataSet;
});
} else {
print('nextDataSet = NULL');
}
}
Future<Post> fetchPost([String dataSet]) async {
...
return Post.fromJson(json.decode(utf8.decode(response.bodyBytes)));
}
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Scaffold(
...
body: FutureBuilder<Post>(
future: fetchPost(inDataSet),
builder: _buildList,
),
),
),
);
}
Widget _buildList(BuildContext context, AsyncSnapshot snapshot) {
... /*code that eventually fills the lists of strings
progressivePartyListSec, progressivePartyListThird*/
...
return ListData(controller: _controller, listEidosPerigr:
progressivePartyListSec, listPerigr: progressivePartyListThird );
}
}
class ListData extends StatelessWidget {
final ScrollController controller;
final List<String> listEidosPerigr;
final List<String> listPerigr;
ListData({this.controller,
this.listEidosPerigr,
this.listPerigr});
@override
Widget build(BuildContext context) {
return ListView.builder(
controller: controller,
itemCount: rowsSelected,
itemBuilder: (context, i) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
removeAllHtmlTags(listEidosPerigr[i]),
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.blue),
),
new RichText(
text: new TextSpan(
text: listPerigr[i].replaceAllMapped('<BR>', (Match m) => '').replaceAllMapped('<b>', (Match m) => '').replaceAllMapped('</b>', (Match m) => ''),
style: DefaultTextStyle.of(context).style,
),
),
]);
});
}
}
Комментарии:
1. Не могли бы вы добавить больше кода
2. Да, конечно, я добавил соответствующий код…
Ответ №1:
после некоторых исследований я нашел решение по следующей ссылке: Flutter: создание ListView, которое загружает по одной странице за раз
Большое спасибо Абдулрахману Альхамали.
В принципе, в приведенном выше коде, который я опубликовал, я использовал другой аргумент для ListView.builder, и это следующий ключ: PageStorageKey(‘offset’),
Наконец, как пишет Абдулрахман в своей статье, я использовал KeepAliveFutureBuilder в качестве оболочки FutureBuilder в других мирах в моем методе сборки, который я сделал…
body: KeepAliveFutureBuilder(
//child: FutureBuilder<Post>(
future: fetchPost(inDataSet),
builder: _buildList,
//),
),