Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if item is visible on RecyclerView

I have built a basic interface consisting of a list of CardView’s inside a RecyclerView. When a card is added I need to know if it is visible on screen or not.

I am trying to obtain this by using the layout manager’s findLastVisibleItemPosition() method, however it seems to return a result one item less than expected. For example if I have 1 card which is visible findLastVisibleItemPosition() returns -1 (where I would expect the index of the visible card would be 0).

My simplified core methods are as follows:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    items = new ArrayList<>();

    RecyclerView recycList = (RecyclerView) findViewById(R.id.rv);
    recycList.setHasFixedSize(true);
    llm = new LinearLayoutManager(this);
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    recycList.setLayoutManager(llm);
    recycList.addOnChildAttachStateChangeListener(new ChildAttachListener(llm));
    adapter = new RecycAdapter(items);
    recycList.setAdapter(adapter);
}

private void addItem(){
    items.add(new Item());
    adapter.notifyDataSetChanged();
}

private class ChildAttachListener implements OnChildAttachStateChangeListener{
    LinearLayoutManager llm;

    public ChildAttachListener(LinearLayoutManager llm){
        super();
        this.llm = llm;
    }

    @Override
    public void onChildViewAttachedToWindow(View view) {

        System.out.println("Items size = "+items.size() + ", Last Visible Item = "+llm.findLastVisibleItemPosition());
    }

    @Override
    public void onChildViewDetachedFromWindow(View view) {

    }
}

Return when first item is added:

Items size = 1, Last Visible Item = -1

Return when second item is added:

Items size = 2, Last Visible Item = 0
Items size = 2, Last Visible Item = 0

Return when third item is added:

Items size = 3, Last Visible Item = 0
Items size = 3, Last Visible Item = 1
Items size = 3, Last Visible Item = 1

In all cases all items are visible (I can have 7 visible items on screen).

Could someone please help me understand the return of findLastVisibleItemPosition() and suggest how I can determine if a card is visible on screen when adding it?

EDIT: I should clarify that my real objective is to know if an item is visible when I add it (using my addItem() method). If there is a simple way of doing that inside the addItem() method even better.

like image 386
Ratty Avatar asked Nov 04 '15 12:11

Ratty


People also ask

What is Item view in RecyclerView?

A RecyclerView. ViewHolder class which caches views associated with the default Preference layouts. A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive findViewById results.


1 Answers

For those interested I have solved the problem by calling findLastVisibleItemPosition inside a Handler:

@Override
public void onChildViewAttachedToWindow(View view) {

    Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {

                System.out.println(llm.findLastVisibleItemPosition());
            }
        });
}
like image 148
Ratty Avatar answered Oct 03 '22 10:10

Ratty