2

My Activity is showing a RecyclerView with a LinearLayoutManager. I want to get the first item (View) in the list. According this post's accepted answer , I can do it calling LinearLayoutManager.findViewByPosition() method, but I'm getting null instead. Why?

RecyclerView list = findViewById(R.id.list);
LinearLayoutManager llm = new LinearLayoutManager(this);
list.setLayoutManager(llm);
MyAdapter adapter = new MyAdapter();
list.setAdapter(adapter);
View firstViewItem = llm.findViewByPosition(0); // <-- null

adapter contains items, it's not empty.

Héctor
  • 19,875
  • 26
  • 98
  • 200

3 Answers3

5

A useful function is doOnPreDraw - you should call it on the RecyclerView and put your code there.

 rv.doOnPreDraw {
     // now it will work... 
     val view = llm.findViewByPosition(0)
   }
Gal Rom
  • 5,509
  • 2
  • 37
  • 30
2

It's because the population of the RecyclerView by the Adapter is asynchronous. You may launch an event when the adapter finish to populate the RecyclerView to be sure that findViewByPosition returns something to you.

Detect when RecyclerView have finished to populate all visible items is a bit difficult, because we should calculate each item size (width and height) and define how many items can enter in current device display.

But if what you need is only to access first populated item then you can fire your event in your Adapter's onBindViewHolder method, obviously inserting the needed controls to avoid to fire events for every added item.

firegloves
  • 5,187
  • 2
  • 22
  • 42
  • Thanks for your answer. How can listen to that event? – Héctor Sep 20 '17 at 16:05
  • You can use something like Otto Event Bus. It is a good event lib to use. You could find some examples on the web. I suggest you to use event approach wherever is possible, it helps to improve performance and it helps to write clear code – firegloves Sep 20 '17 at 16:07
  • But, I mean, how do I know when RecyclerView has been populated? – Héctor Sep 20 '17 at 16:09
1

try this.

new Handler().postDelayed(new Runnable() {
     @Override
     public void run() {
         View firstViewItem = llm.findViewByPosition(0);
     }
 }, 500);
Mehul Kabaria
  • 5,328
  • 4
  • 20
  • 42
  • it will work because recycler view takes some time to bind item on it. otherwise you can get it on any button click. because exact after setAdapter is never return a view. – Mehul Kabaria Sep 20 '17 at 16:09
  • 1
    This works well to debug the code but not something to place on production ! Thanks ! – Gastón Saillén Sep 11 '18 at 20:19