Как реализовать разбивку на страницы в делегате Flutter Search?

#flutter #dart #pagination

#flutter #dart #разбивка на страницы

Вопрос:

Я пытаюсь реализовать разбивку на страницы в своем приложении, когда пользователь что-то ищет.
Я смог получить и отобразить свои данные (ограничено примерно 12 результатами), но я не смог получить больше результатов из-за того, что делегат поиска не является классом с сохранением состояния.
Есть ли способ эффективно использовать setState для загрузки большего количества данных путем добавления в мой уже выбранный ListView?

Код

 import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:official_coolkicks/models/shoe.dart';
import 'package:official_coolkicks/providers/search-provider.dart';
import 'package:official_coolkicks/providers/shoe-provider.dart';
import 'package:official_coolkicks/themes/adjust_settings_icons.dart';
import 'package:official_coolkicks/views/widgets/category/shoeCard.dart';
import 'package:official_coolkicks/views/widgets/filtering/filter_chip.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;

import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

class CategorySearch extends SearchDelegate<Shoe> {
  @override
  ThemeData appBarTheme(BuildContext context) {
    assert(context != null);
    final ThemeData theme = Theme.of(context);
    assert(theme != null);
    return theme;
  }

  ScrollController _sc = new ScrollController();

  List<Shoe> shoes;
  int page = 1;
  bool isLoading = false;

  @override
  String get searchFieldLabel => 'Search in Men's Shoes';

  var random = new Random();

 

  Future _saveList() async {
    SharedPreferences.getInstance().then((prefs) {
      prefs.setStringList("searchHistory", searchHistory);
    });
  }

  Widget content;

 

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () {
          query = "";
        },
      )
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
        icon: AnimatedIcon(
          icon: AnimatedIcons.menu_arrow,
          progress: transitionAnimation,
        ),
        onPressed: () {
          close(context, null);
        });
  }

  @override
  Widget buildResults(BuildContext context) {
    final double height = MediaQuery.of(context).size.height;
   

    return StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
      void loadMore()  {
        setState(() {
          page  ;
          isLoading = true;
          print('ISLOADING IS EQUALS TO $isLoading');
        });

      }

      setState(() {
        if (page > 1) {
          page  ;
          print('PAGE IS NOW $page');
        }
      });
      return FutureBuilder(
        future: _search(page),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              print(snapshot.error);
              return Center(
                child: Text('Check your Internet connection and try again'),
              );
            } else if (snapshot.data.length == 0) {
              return Center(
                child: Text('No search results found'),
              );
            }

            return Container(
                height: height,
                child: Stack(
                  children: [
                    Column(
                      children: <Widget>[
                        Expanded(
                            child: NotificationListener<ScrollNotification>(
                          child: GridView.count(
                            padding: EdgeInsets.all(15),
                            controller:
                                new ScrollController(keepScrollOffset: false),
                            shrinkWrap: true,
                            childAspectRatio:
                                MediaQuery.of(context).size.width /
                                    (MediaQuery.of(context).size.height / 1.3),
                            scrollDirection: Axis.vertical,
                            crossAxisCount: 2,
                            crossAxisSpacing: 15,
                            mainAxisSpacing: 15,
                            children: List.generate(
                              snapshot.data.length,
                              (index) {
                                return ShoeCard(
                                    index: random.nextInt(1000000),
                                    shoe: snapshot.data[index]);
                              },
                            ),
                          ),
                          onNotification: (ScrollNotification scrollInfo) {
                            if (scrollInfo.metrics.pixels ==
                                scrollInfo.metrics.maxScrollExtent) {
                              // loadMore();
                            }
                            return false;
                          },
                        )),
                     
                       
                      ],
                    ),
                     Align(
                      alignment: FractionalOffset.bottomCenter,
                      child: Container(
                            height: isLoading ? 50 : 0,
                            child: Center(
                              child: CircularProgressIndicator(),
                            ))),
                    Align(
                      alignment: FractionalOffset.bottomRight,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: FloatingActionButton(
                          child: Icon(AdjustSettings.adjust),
                          backgroundColor: Colors.deepPurple,
                          onPressed: () {
                            Navigator.push(
                                context,
                                CupertinoPageRoute(
                                    builder: (context) => FilterChipDisplay()));
                          },
                        ),
                      ),
                    ),
                  ],
                ));
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      );
    });
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    // List<Product> shoeList = products;
    return Container();
  }

  Future<List<Shoe>> _search(int page) async {
    String baseurl = "https://coolke.herokuapp.com";
    String formatter(String url) {
      return baseurl   url;
    }

    String url = formatter('/coolke/getCategorySearch/Men/$query?$page');
    final result = await http.get(url);
    final nlist = json.decode(result.body);
    final list = nlist['shoes'] as List;

    return list.map((e) => Shoe.fromJson(e)).toList();
  }

  
}