Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

android - RecyclerView onScrolled method of addOnScrollListener not called except only once

Background:

I am implementing pagination logic with RecyclerView by adding addOnScrollListener function.

Problem faced:

The onScrolled method is called once when the RecyclerView adapter is loaded with dy value of 0. However when the list reaches its end when scrolled, the onScrolled method is not triggered while the onScrollStateChanged is triggered correctly.

Here is my Adapter:

HistoryAdapter(Context context, ArrayList<HistoryItem> items, RecyclerView recyclerView) {
        inflater = LayoutInflater.from(context);
        this.items = items;
        preferences = PreferenceManager.getDefaultSharedPreferences(context);
        this.context = context;
        this.recyclerView = recyclerView;

        final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                Timber.w("onScrolled.. %s", dy);

                if (dy > 0) {
                    totalItemCount = linearLayoutManager.getItemCount();
                    lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                    Timber.e("totalItemCount: %s", totalItemCount);
                    Timber.e("lastVisibleItem: %s", lastVisibleItem);

                    if (!isLoading && totalItemCount <= (lastVisibleItem + 1)) {

                        Timber.i("End reached...");
                        if (onLoadMoreListener != null) {
                            //Log.i(TAG, "Episodes Adapter: onLoadMore calling...");
                            onLoadMoreListener.onLoadMore();
                        }
                        isLoading = true;
                    }
                }
            }

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

            }
        });
    }

Recycler:

private void setupRecycler() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        historyAdapter = new HistoryAdapter(getActivity(), historyItems, recyclerView);
        recyclerView.setAdapter(historyAdapter);
        historyAdapter.setClickListener(this);
        historyAdapter.setOnLoadMoreListener(this);
        historyAdapter.setErrorClickListener(this);
    }

My Recycler xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/medium_text_color_blue"
        android:padding="12dp">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="start"
            android:text="#"
            android:textColor="@android:color/white"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="4.5"
            android:gravity="start"
            android:text="CLASS"
            android:textAllCaps="true"
            android:textColor="@android:color/white"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:gravity="center"
            android:text="Date"
            android:textAllCaps="true"
            android:textColor="@android:color/white"
            android:textStyle="bold" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:gravity="center"
            android:text="time"
            android:textAllCaps="true"
            android:textColor="@android:color/white"
            android:textStyle="bold" />
    </LinearLayout>

    <FrameLayout
        android:layout_below="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/no_reflection_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:layout_gravity="center"
            android:text="No Reflection History found!" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/history_recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </FrameLayout>
</RelativeLayout>

What I have researched:

There are many such issues already posted at StackOverflow but most of them point to a solution that is to remove the parent ScrollView of the RecyclerView which is stopping the onScrolled method to be triggered, however this seems to be not an issue I am facing.

RecyclerView.onScrolled() not getting called

RecyclerView onScrolled not called when use scrollToPosition

RecyclerView onScrolled not being fired at all

RecyclerView not calling onScrolled at the bottom

android RecyclerView onScrolled not call

https://github.com/passsy/ArrayAdapter/issues/4

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

An alternative is to check if the recycler can scroll vertically if it cannot then it means it has reached the bottom.

Try this

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)

                if (!recyclerView.canScrollVertically(1)) {
                    // Load more
                }
            }
}

`

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...