Как добавить индикатор выполнения в конец GridView, когда я получаю следующие данные - PullRequest
0 голосов
/ 20 марта 2020

Моя цель - добавить индикатор выполнения в конец GridView, когда я получаю следующую страницу. Я пытался сделать индикатор прогресса видимым, когда достигну конца экрана, затем отключить его при загрузке с помощью isLoading bool, но это не помогло. ничего не показывать, и я пытался показать индикатор выполнения на основе количества элементов в Gridview. Вот код без моей попытки:

class _PopularGalleryGridState extends State<PopularGalleryGrid> {
      List<Photo> data = new List<Photo>();

      ScrollController _scrollController = new ScrollController();
      StreamController<List<Photo>> _photosStreamController =
          StreamController<List<Photo>>.broadcast();

      Future<List<Photo>> _fetchPhotos() async {
        developer.log('fetch photos');
        try {
          final response =
              await http.get(galleryUrl + page.toString() + "&limit=10");
          Map<String, dynamic> decodedJson = json.decode(response.body);
          List photos = decodedJson['data'] as List;
          List<Photo> result =
              (photos.map((photo) => Photo.fromJson(photo))).toList();
          data.addAll(result);
          _photosStreamController.sink.add(data);
        } catch (e) {
          _photosStreamController.sink.addError(e);
        }
      }

      @override
      void initState() {
        data.clear();
        _scrollController.addListener(() {
          if (_scrollController.position.pixels ==
              _scrollController.position.maxScrollExtent) {
            developer.log('scroll controller');
            page++;
            _fetchPhotos();
          }
        });
        _photosStreamController.onListen = _fetchPhotos;
        super.initState();
      }

      @override
      void dispose() {
        super.dispose();
        _scrollController.dispose();
        _photosStreamController?.close();
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: StreamBuilder<List<Photo>>(
          stream: _photosStreamController.stream,
          builder: (context, snapshot) {
            developer.log('builder');
            if (snapshot.hasData || data.isNotEmpty) {
              return _photoGridView(snapshot.data ?? data);
            } else if (snapshot.hasError) {
              return Text("${snapshot.hasError}");
            }
            return CircularProgressIndicator();
          },
        ));
      }

      GridView _photoGridView(data) {
        return GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            childAspectRatio: 1.0,
            mainAxisSpacing: 4.0,
            crossAxisSpacing: 4.0,
          ),
          itemCount: data.length,
          itemBuilder: (context, index) {
            return Card(
              elevation: 4,
              child: GestureDetector(
                onTap: () => _navigateToImage(context, data[index].id),
                child: Image.network(
                    ('http://gallery.dev.webant.ru/media/' + data[index].image)),
              ),
            );
          },
          controller: _scrollController,
        );
      }

      void _navigateToImage(BuildContext context, int id) {
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) => SingleImage(imageId: id),
          ),
        );
      }
    }

1 Ответ

0 голосов
/ 21 марта 2020

Возможно, вам придется поиграть с count и itemBuilder. Я надеюсь, что вы получили суть.

itemCount: data.length+1,
          itemBuilder: (context, index) {
          if(index==data.length) return CircularProgressIndicator();

Или вы можете сохранить флаг состояния загрузки, который находится ниже ListView и который вызывает состояние загрузки, являющееся истинным.

...