Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinitive RecyclerView doesn't work for me

Tags:

android

I know that this question was asked many times before, but i'm confused why sometimes the data is loaded and sometimes data isn't loaded once i get to the end of list. Also when i go fast scrolling through the list, and the new data has been loaded, but immediately it returns me to the first item in list and remove all new loaded items from the next page from server. So that is the second problem and the third problem is that when i load items using SwipeRefreshLayout, i'm also not getting new items when i reach the end of the list.

I have implemented this in my project: https://gist.github.com/ssinss/e06f12ef66c51252563e

list.setLayoutManager(manager);
    list.setEmptyView(emptyView);
    list.setItemAnimator(new DefaultItemAnimator());
    list.setAdapter(mAdapter);

    loadJokes(1);

    list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
        @Override
        public void onLoadMore(final int current_page) {
            loadMoreJokes(current_page);
        }
    });

Here is the method where i'm loading more items from server:

private void loadMoreJokes(int current_page) {
    StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + current_page,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    hideDialog();
                    try {
                        JSONObject object = new JSONObject(response);
                        boolean error = object.getBoolean("error");
                        JSONArray jokes = object.getJSONArray("jokes");
                        if (!error) {
                            for (int i = 0; i < jokes.length(); i++) {
                                JSONObject object1 = jokes.getJSONObject(i);
                                Joke joke = new Joke();
                                joke.setId(object1.optInt("id"));
                                joke.setLikes(object1.optInt("likes"));
                                joke.setComments(object1.optInt("comments"));
                                joke.setJoke(object1.optString("joke"));
                                joke.setCreatedAt(object1.optString("created_at"));
                                joke.setName(object1.optString("user_name"));
                                joke.setImagePath(object1.optString("image_path"));
                                joke.setFacebookUserId(object1.optString("facebook_user_id"));
                                joke.setCategory(object1.optString("category"));
                                mJokes.add(joke);
                            }
                            menu.showMenu(true);
                        }

                        // Notify adapter that data has changed
                        mAdapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            hideDialog();
            Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });

    AppController.getInstance().addToRequestQueue(request);
}

And here is the method where i'm loading first visible items when someone launch the app:

private void loadJokes(int page) {
    pDialog.setMessage("Loading..");
    showDialog();

    StringRequest request = new StringRequest(Request.Method.GET, AppConfig.URL_GET_ALL_JOKES + page,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    mJokes.clear();
                    hideDialog();
                    try {
                        JSONObject object = new JSONObject(response);
                        boolean error = object.getBoolean("error");
                        JSONArray jokes = object.getJSONArray("jokes");
                        if (!error) {
                            for (int i = 0; i < jokes.length(); i++) {
                                JSONObject object1 = jokes.getJSONObject(i);

                                Joke joke = new Joke();
                                joke.setId(object1.optInt("id"));
                                joke.setLikes(object1.optInt("likes"));
                                joke.setComments(object1.optInt("comments"));
                                joke.setJoke(object1.optString("joke"));
                                joke.setCreatedAt(object1.optString("created_at"));
                                joke.setName(object1.optString("user_name"));
                                joke.setImagePath(object1.optString("image_path"));
                                joke.setFacebookUserId(object1.optString("facebook_user_id"));
                                joke.setCategory(object1.optString("category"));
                                mJokes.add(joke);
                            }
                            menu.showMenu(true);
                        }

                        // Notify adapter that data has changed
                        mAdapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            hideDialog();
            menu.showMenu(true);
            Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });

    AppController.getInstance().addToRequestQueue(request);
}

And this is onRefresh() method:

@Override
public void onRefresh() {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            refreshItems();
        }
    }, 5000);
}

private void refreshItems() {
    loadJokes(1);

    mSwipeRefreshLayout.setRefreshing(false);
}

If i need to post more code, let me know. I really need to solve this problem as soon as i can. So again, the problems are the following:

  • When fast scrolling through the list, new items are being loaded, but immediately after that it returns me to the beginning of the list and when i go to the end of list again, load more doesn't respond.

  • After refreshing the list with SwipRefreshLayout, also scrolling doesn't respond at the end.

Note: The scrolling and loading new items is working only if i go slowly through the list and if i didn't swipe to refresh list.

EDIT:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_jokes, container, false);

    mContext = getActivity();
    mView = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout);

    TextView tvEmptyText = (TextView) view.findViewById(R.id.tv_empty);
    ImageView ivSignal = (ImageView) view.findViewById(R.id.iv_signal);

    if (!ConnectionDetector.getInstance(getActivity()).isOnline() && mAdapter == null) {
        tvEmptyText.setVisibility(View.VISIBLE);
        ivSignal.setVisibility(View.VISIBLE);
        showNoInternetSnackbar();
    }

    // INITIALIZE RECYCLER VIEW
    EmptyRecyclerView list = (EmptyRecyclerView) view.findViewById(R.id.list);
    mJokes = new ArrayList<>();
    mAdapter = new RecyclerJokesAdapter(getActivity(), mJokes, JokesFragment.this, null);

    // Progress dialog
    pDialog = new ProgressDialog(getActivity());
    pDialog.setMessage("Please wait");
    pDialog.setIndeterminate(true);
    pDialog.setCancelable(false);

    showDialog();

    View emptyView = inflater.inflate(R.layout.layout_empty_view, container, false);

    FloatingActionButton fab1 = (FloatingActionButton) view.findViewById(R.id.fab_funny);
    FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.fab_good_morning);
    FloatingActionButton fab3 = (FloatingActionButton) view.findViewById(R.id.fab_good_night);
    FloatingActionButton fab4 = (FloatingActionButton) view.findViewById(R.id.fab_all);
    menu = (FloatingActionMenu) view.findViewById(R.id.menu_sort_jokes);

    fab1.setOnClickListener(this);
    fab2.setOnClickListener(this);
    fab3.setOnClickListener(this);
    fab4.setOnClickListener(this);

    mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
    mSwipeRefreshLayout.setOnRefreshListener(this);
    mSwipeRefreshLayout.setColorSchemeResources(
            R.color.refresh_progress_1,
            R.color.refresh_progress_2,
            R.color.refresh_progress_3);

    LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);

    list.setLayoutManager(manager);
    list.setEmptyView(emptyView);
    list.setItemAnimator(new DefaultItemAnimator());
    list.setAdapter(mAdapter);

    if (ConnectionDetector.getInstance(mContext).isOnline()) {
        loadJokes(1);
    } else {
        showNoInternetSnackbar();
        hideDialog();
    }

    list.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
        @Override
        public void onLoadMore(final int current_page) {
            loadMoreJokes(current_page);
        }
    });

    return view;
}
like image 734
Dusan Dimitrijevic Avatar asked Nov 09 '22 15:11

Dusan Dimitrijevic


1 Answers

In onCreate method initialize your adapter, recyclerView and List

List<MyObject> myList = new ArrayList<>();
recyclerViewAdapter = new RecyclerViewAdapter(context, myList)
myRecyclerView.setAdapter(recyclerViewAdapter);

Now, whenever you load data. add the data to your myList and call notifyDataSetChange on your adpater

myList.add(data);
recyclerViewAdapter.notifyDataSetChange();
like image 106
Arshad Avatar answered Nov 15 '22 07:11

Arshad