android - Why notifyItemChanged only works in post Runnable after setAdapter? -


public class mainactivity extends appcompatactivity {  @override protected void oncreate(bundle savedinstancestate) {     super.oncreate(savedinstancestate);     setcontentview(r.layout.main);      recyclerview list = (recyclerview) findviewbyid(r.id.list);     list.setlayoutmanager(new linearlayoutmanager(this));     final recyclerview.adapter adapter = getadapter();     list.setadapter(adapter);      adapter.notifyitemchanged(1, new object());//this doesn't work     list.post(new runnable() {         @override         public void run() {             adapter.notifyitemchanged(1, new object());//this works         }     });   }  @nonnull private recyclerview.adapter getadapter() {     return new recyclerview.adapter() {         @override         public recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) {             return new itemviewholder( layoutinflater.from(parent.getcontext())                     .inflate(r.layout.list_view_item, parent, false));         }          @override         public void onbindviewholder(recyclerview.viewholder holder, int position) {             itemviewholder item = (itemviewholder) holder;             item.tv.settext("test");         }          @override         public void onbindviewholder(recyclerview.viewholder holder, int position, list payloads) {             if(payloads.isempty())                 onbindviewholder(holder, position);             else{                 itemviewholder item = (itemviewholder) holder;                 item.tv.settext("changed!!!!!! ");             }         }          @override         public int getitemcount() {             return 40;         }          class itemviewholder extends recyclerview.viewholder{             textview tv;             itemviewholder(view itemview) {                 super(itemview);                 tv = (textview) itemview.findviewbyid(r.id.tv);             }         }     }; }} 

very simple example here test notifyitemchanged, works when post message queue, not invoking directly after setadapter. setadapter triggers call requestlayout(), mean notifyitemchanged can't happen if in middle of laying out items?

after bit of investigation turns out notifyitemchanged works when recyclerview attached , has completed onlayout happens after oncreate.

internally during recyclerview.onlayout() called notifyitemchanged -> requestlayout(), processadapterupdatesandsetanimationflags() called checks if item updated has available viewholder in case null because during oncreate(), recyclerview not attached window, no measurement , layout has done recyclerview

apparently complete drawing of recyclerview happens sometime after oncreate() , onresume()

@override protected void onresume() {     super.onresume();     boolean = list.isattachedtowindow();//this false! } 

so make notifyitemchanged work on oncreate

list.addonlayoutchangelistener(new view.onlayoutchangelistener() {         @override         public void onlayoutchange(view v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldright, int oldbottom) {             adapter.notifyitemchanged(1, new object());//this update item         }     });    new thread((new runnable() {         @override         public void run() {             try {                 thread.sleep(28);//small amount of delay,below 20 doesn't seem work             } catch (interruptedexception e) {                 e.printstacktrace();             }             runonuithread(new runnable() {                 @override                 public void run() {                     adapter.notifyitemchanged(1, new object());//also works                 }             });         }     })).start(); 

i guess reason viewrootimpl.performtraversal() controlled system , happens sometime after decorview attached window during oncreate

i'm assuming can happen during oncreate , onresume, may not happen if called later.


Comments

Popular posts from this blog

python - How to insert QWidgets in the middle of a Layout? -

python - serve multiple gunicorn django instances under nginx ubuntu -

module - Prestashop displayPaymentReturn hook url -