0

I'm having a hard time to wrap my head around infinite scrolling in flutter. I'm trying to load 10 recipes first, then with the help of ScrollController show the new recipes. and when there is no more recipes left, I want to show a message that shows there is no more posts.

here's my project's code.

import 'package:flutter/material.dart';
import 'package:test/model/recipe.dart';
import 'package:test/pages/recipe_details.dart';
import 'package:test/widgets/recipe_card.dart';
import 'package:http/http.dart' as http;

class SingleCategory extends StatefulWidget {
  final Recipe recipe;
  final int recipeCourseid;
  final String recipeCourseName;

  SingleCategory({
    this.recipe,
    @required this.recipeCourseid,
    @required this.recipeCourseName,
  });

  @override
  _SingleCategoryState createState() => _SingleCategoryState();
}

class _SingleCategoryState extends State<SingleCategory> {
  ScrollController _scrollController = ScrollController();
  int pageNumber = 1;

  var myRecipe;

  Future<List<Recipe>> getRecipeList({int pageNumber}) async {
    // pageNum = 1;
    var response = await http.get(
        'https://test.com/wp-json/wp/v2/wprm_recipe?wprm_course=${widget.recipeCourseid}&per_page=10&$pageNumber');
    var body = response.body;
    final recipes = recipeFromJson(body)

    return recipes;
  }

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        pageNumber++;
        print(pageNumber);
        getRecipeList();
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.recipeCourseName),
          centerTitle: true,
          elevation: 5,
        ),
        body: Padding(
          padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 12.0),
          child: FutureBuilder(
            future: getRecipeList(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return GridView.builder(
                  controller: _scrollController,
                  itemCount: snapshot.data.length,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                    crossAxisSpacing: 12.0,
                    mainAxisSpacing: 12.0,
                  ),
                  itemBuilder: (BuildContext context, int index) {
                    myRecipe = snapshot.data[index].recipe;
                    return InkWell(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => RecipeDetails(
                              recipe: snapshot.data[index],
                            ),
                          ),
                        );
                      },
                      child: RecipeCard(myRecipe: myRecipe),
                    );
                  },
                );
              } else if (snapshot.hasError) {
                return Center(
                  child: Text('There was an error, Please try again'),
                );
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          ),
        ),
      ),
    );
  }
}

I would apprecite it if you could point me to the right direction.

3 Answers 3

1

Everything looks good but you have to make a small change.

Your Code:

_scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        pageNumber++;
        print(pageNumber);
        getRecipeList();
      }
    });

Should be:

_scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        pageNumber++;
        setState(() {}); // if add this, Reload your futurebuilder and load more data
 //        getRecipeList(); // It's not necessary because, FutureBuilder call automatically getRecipeList when you call setState 
      }
    });
Sign up to request clarification or add additional context in comments.

1 Comment

Actually you were correct. there was another mistake on my end that I found it and fixed the issue. Thank you
1

Try to add in your GridView

physics: const AlwaysScrollableScrollPhysics(),

1 Comment

thank you for your time, but my problem is not with scrolling and I think the problem is with me not being able to add new posts to those that are already showing
0

Declare a new variable in your class

 List<Recipe> recipesList;

And inside the getRecipeList() method change as like below

Future<List<Recipe>> getRecipeList({int pageNumber}) async {
    // pageNum = 1;
If(page number ==1)
  recipesList.clear;

    var response = await http.get(
        'https://test.com/wp-json/wp/v2/wprm_recipe?wprm_course=${widget.recipeCourseid}&per_page=10&$pageNumber');
    var body = response.body;
    final recipes = recipeFromJson(body)
    recipesList.addAll(recipes);
    return recipesList;
  }

And in the scrollListener try to pass pageNumber. Since you have declare the same name for pageNumber both inside and outside getRecipesList method.

_scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        pageNumber++;
        print(pageNumber);
        getRecipeList(pageNumber:pageNumber).then((){
            setState((){});
        });
      }
    });

1 Comment

Thank you this part of your code with some editing worked but first answer needed less modification _scrollController.addListener( () { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { pageNumber++; setState(() { getRecipeList(); }); } }, );

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.