Я хочу реализовать разбиение на страницы в GridView. Я использую GridView.builder. Я хочу загружать элементы 10 на 10, когда пользователь достигает последней строки.
не так уж много я использовал Grid и привязывал к нему данные только тогда, когда мне нужен способ разбиения на страницы со столбцами строк данных
Из документации вы должны использовать IndexedWidgetBuilder
для создания дочерних элементов по запросу: api.flutter.dev/flutter/widgets/ListView-class.html
хорошо, я попробую
Вы можете использовать этот плагин здесь: Пейджинг. Оберните свой GridView внутри него и скажите мне, работает ли это!
Вы можете сделать это с помощью NotificationListener
. В качестве простой демонстрации он будет увеличивать длину вашего GridView
всякий раз, когда он достигает конца страницы:
var items_number = 10 ;
return NotificationListener<ScrollNotification>(
onNotification: (scrollNotification){
if (scrollNotification.metrics.pixels == scrollNotification.metrics.maxScrollExtent){
setState(() {
items_number += 10 ;
});
}
},
child: GridView.builder(
itemCount: items_number,
itemBuilder: (context, index) {
//.... the reminder of your code
}
),
);
отлично сработало для меня, но я хочу сделать это с данными из API, как сделать загрузчик и дождаться данных, если это возможно
Затем оберните NotificationListener
StreamBuilder
и дайте потоку измениться из функции onNotification()
.
Мне это тоже нужно, но я не смог найти виджет для gridview
pagination
, поэтому я попытался создать компонент на основе ответа @Mazin Ibrahim ниже. Кажется, это работает, но не уверен, что это правильный способ сделать это.
typedef Future<bool> OnNextPage(int nextPage);
class GridViewPagination extends StatefulWidget {
final int itemCount;
final double childAspectRatio;
final OnNextPage onNextPage;
final Function(BuildContext context, int position) itemBuilder;
final Widget Function(BuildContext context) progressBuilder;
GridViewPagination({
this.itemCount,
this.childAspectRatio,
this.itemBuilder,
this.onNextPage,
this.progressBuilder,
});
@override
_GridViewPaginationState createState() => _GridViewPaginationState();
}
class _GridViewPaginationState extends State<GridViewPagination> {
int currentPage = 1;
bool isLoading = false;
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification sn) {
if (!isLoading && sn is ScrollUpdateNotification && sn.metrics.pixels == sn.metrics.maxScrollExtent) {
setState(() {
this.isLoading = true;
});
widget.onNextPage?.call(currentPage++)?.then((bool isLoaded) {
setState(() {
this.isLoading = false;
});
});
}
return true;
},
child: CustomScrollView(
slivers: <Widget>[
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 1,
mainAxisSpacing: 1,
crossAxisCount: 2,
childAspectRatio: widget.childAspectRatio,
),
delegate: SliverChildBuilderDelegate(
widget.itemBuilder,
childCount: widget.itemCount,
addAutomaticKeepAlives: true,
addRepaintBoundaries: true,
addSemanticIndexes: true,
),
),
if (isLoading)
SliverToBoxAdapter(
child: widget.progressBuilder?.call(context) ?? _defaultLoading(),
),
],
),
);
}
Widget _defaultLoading() {
return Container(
padding: EdgeInsets.all(15),
alignment: Alignment.center,
child: CircularProgressIndicator(),
);
}
}
Пример -
GridViewPagination(
itemCount: 10,
childAspectRatio: 1,
itemBuilder: _buildGridItem,
onNextPage: (int nextPage) {
return fetchData();
},
)
Я использовал это в своем проекте, но столкнулся с одной проблемой: всякий раз, когда я дохожу до конца, он перезагружается и снова прокручивается до вершины сетки, есть ли у вас какое-либо решение для этого?
создать контроллер прокрутки
ScrollController _scrollController = new ScrollController();
добавить прослушиватель событий прокрутки
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
// Bottom poistion
}
});
}
Теперь просто нужно установить контроллер в вашем GridView
, ListView
и ...
GridView.builder(
controller: _scrollController,
));
Можете ли вы поделиться, что вы пробовали до сих пор?