2

I am using a RecyclerView inside SwipeRefreshLayout.The RecyclerView has another 2 RecyclerView (for now; it may increase). In my second RecyclerView i am trying to implement infinite scrolling. But my RecyclerView.getItemCount() and RecyclerView.getChildCount() are giving same value. Also the 2nd re has GridLayoutManager and GridlayoutManager.findFirstVisibleItemPosition() always gives 0 and GridLayoutManager.findLastVisibleItemPosition() always gives list size - 1 in OnScrolled of the RecyclerView. What is causing this and what should i do to implement the infinite scrolling.

fragment.xml

    <?xml version="1.0" encoding="utf-8"?>
 <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:paddingTop="@dimen/padding_standard"
    android:paddingBottom="@dimen/padding_standard">

</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>

parent_recyclerview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginBottom="@dimen/padding_standard"
android:orientation="vertical">

<TextView
    android:id="@+id/section_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/padding_standard"
    android:layout_marginBottom="@dimen/margin_standard"
    android:textColor="@color/label_text"
    android:textSize="@dimen/text_size_standard"
    android:textStyle="bold"
    tools:text="MOments"/>

<android.support.v7.widget.RecyclerView
    android:id="@+id/section_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipToPadding="false"/>

<ProgressBar
    android:id="@+id/events_progress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:visibility="gone"/>
</LinearLayout>

onScrollListener for child recycler view

  RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            GridLayoutManager manager = (GridLayoutManager) recyclerView.getLayoutManager();
            int itemSize = manager.getItemCount();
            int firstVisibleItem = manager.findFirstVisibleItemPosition();
            int visibleChIldCount = manager.getChildCount();
            Logger.e(TAG,"=============== START =====================");
            Logger.e(TAG, "itemSize: " + itemSize);
            Logger.e(TAG, "firstVisibleitem: " + firstVisibleItem);
            Logger.e(TAG, "visibleChIldCount: " + visibleChIldCount);
            Logger.e(TAG,"mLayoutManager.firstCOmpletely: "+ manager.findFirstCompletelyVisibleItemPosition());
            Logger.e(TAG,"mLayoutManager. lastcompletey: "+ manager.findLastCompletelyVisibleItemPosition());
                Logger.e(TAG,"mLayoutManager.findLastVisible: "+ manager.findLastVisibleItemPosition());
            Logger.e(TAG,"=================END ================");
            if (itemSize >= firstVisibleItem + visibleChIldCount){
                Logger.e("", "loading");
                    mLoadMoreListener.loadMore();

            } else {
                Logger.e(TAG, "not Loading");
            }
        }
};
umuieme
  • 729
  • 6
  • 20
  • Did you find the issue and/or solution to this? I am experiencing the same behavior. – Kevin Jan 30 '17 at 18:33
  • the recycler view was showing all the childs at same time without recycling the views ( not just the child visible in screen) I then tracked the scrolled amount of the recycler view and compared with the height of the recycler view. let me know if you solved or not otherwise i will give you some code ( when i can probably in couple hours) – umuieme Jan 31 '17 at 05:04
  • I too am facing this issue. If you can then please do add the code as an answer and accept it. It will be helpful for others. – Cognoscis Jun 02 '17 at 17:18

1 Answers1

1

Sorry for the late reply. But i will post my solution here if in case someone else is looking for them.

In the adapter of the parent recycler view i have set tag for the view

@Override
public SectionRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = mLayoutInflater.inflate(R.layout.view_section, parent, false);
    view.setTag(viewType);
    return new SectionRowHolder(view);
}

The SectionRowHolder is simple ViewHolder with a RecyclerView.OnScrollListener property with getter and setter.

public class SectionRowHolder extends RecyclerView.ViewHolder {

    protected RecyclerView recyclerView;
    RecyclerView.OnScrollListener mOnScrollListener;

    public SectionRowHolder(View view) {
        super(view);
        this.recyclerView = (RecyclerView) view.findViewById(R.id.section_list);

    }

    public RecyclerView.OnScrollListener getCustomScrollListener() {
        return mOnScrollListener;
    }

    public void setCustomScrollListener(RecyclerView.OnScrollListener mOnScrollListener) {
        this.mOnScrollListener = mOnScrollListener;
    }
}

Then in the onBindViewHolder for the child with infinite scrolling I have implemented the load more logic in scroll listener and set to the child RecyclerView.

 RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {

        boolean loadEnable = false;

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            mTotalScrolled += dy;
            if ((mTotalScrolled + LOAD_MORE_ENABLE_HEIGHT) > recyclerView.getHeight() && loadEnable) {
                loadEnable = false;
                mLoadMoreListener.loadMore();
            } else {
                loadEnable = true;
            }
        }
    };
    holder.setCustomScrollListener(scrollListener);
    holder.recyclerView.addOnScrollListener(scrollListener);

Here LOAD_MORE_ENABLE_HEIGHT is offset from bottom of the child recycler view to initialize the loadmore() logic and mLoadMoreListener is callback to the fragment or activity.

Finally for passing the scoll listener from parent recycler view to the child recycler vew, in my parent RecyclerView's onScrollListener

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            View v = mRecyclerView.findViewWithTag(CHILD_RECYCLERVIEW_TAG);
            SectionedLifeAtAdapter.SectionRowHolder viewHolder =
                    (SectionedLifeAtAdapter.SectionRowHolder) mRecyclerView
                            .findContainingViewHolder(v);
            if (viewHolder.getCustomScrollListener() != null)
                viewHolder.getCustomScrollListener().onScrolled((RecyclerView) v
                        .findViewById(R.id.section_list), dx, dy);

            Logger.e(TAG, ">>> call to on scrolled listener >>>");
        }
    });

Here CHILD_RECYCLERVIEW_TAG is the view type that you set in the onCreateViewHolder of the parent Adapter. It kind of look like messy but it did the job for me without any issues.

umuieme
  • 729
  • 6
  • 20