0

I have to get the top visible item of the child recycler view. The child recycler view is always fully drawn within the parent item and multiple parent items are visible on screen.

I have tried the getting child layout manager and then getting the first visible item of the child recycler view but it always returns zero (I think as the child recycler view is fully drawn this is correct), also tried checking the visibility of the item but all items are always visible.

LinearLayoutManager's findFirstVisibleItemPosition(), findFirstCompletelyVisibleItemPosition() and visibility check always return 0 and true for the child recycler view even when the parent item is partially visible or the child recycler view is partially visible

sample code:

Main layout:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rcvEventList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item_design" />

</androidx.constraintlayout.widget.ConstraintLayout>

item_design:

    <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<!-- some other layout/ view -->

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rcvEventList"
        android:layout_width="20dp"
        android:layout_height="match_parent" />
    
<!-- some other layout/ view -->

</androidx.constraintlayout.widget.ConstraintLayout>

scroll listener on parent recycler:

 parentRecyclerView.addOnScrollListener(object :
        RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            val childLayoutManager: LinearLayoutManager =
                recyclerView.findViewById<RecyclerView>(R.id.childRecyclerView).layoutManager!! as LinearLayoutManager
            Timber.d("findFirstVisibleItemPosition ${childLayoutManager.findFirstVisibleItemPosition()}")
            Timber.d("findFirstCompletelyVisibleItemPosition ${childLayoutManager.findFirstCompletelyVisibleItemPosition()}")

        }
    })
anil
  • 21
  • 2

2 Answers2

0

Try this

findFirstCompletelyVisibleItemPosition()

here is full sample

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
    if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
        LinearLayoutManager llm = (LinearLayoutManager) manager;
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                    int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
                    if(visiblePosition > -1) {
                        View v = llm.findViewByPosition(visiblePosition);
                        //do something
                    }
            }
        });
    }
}
0

You can use you Set your onClickListeners on onBindViewHolder() and you can access the position from there. If you set them in your ViewHolder you won't know what position was clicked unless you also pass the position into the ViewHolder

as getPosition() is now deprecated and we should use getAdapterPosition()

override fun onBindViewHolder(holder: MyHolder, position: Int) {
    // - get element from your dataset at this position
    val item = myDataset.get(holder.absoluteAdapterPosition)
}