更新时间:2023-11-29 10:17:22
经过一番调查,结果发现notifyItemChanged
仅在连接了RecyclerView
且实际上已完成onLayout
时起作用,而onLayout
After a bit of investigation it turns out that notifyItemChanged
only works when RecyclerView
is attached and actually has completed onLayout
which happens after onCreate
.
中,调用processAdapterUpdatesAndSetAnimationFlags()
来检查要更新的项目是否具有可用的ViewHolder
(在这种情况下为null
),因为在onCreate()
,RecyclerView
未附加到窗口,因此未对RecyclerView
internally during RecyclerView.onLayout()
which is called by notifyItemChanged -> requestLayout()
, processAdapterUpdatesAndSetAnimationFlags()
is called which checks if the item that is to be updated has an available ViewHolder
which in this case is null
because during onCreate()
, RecyclerView
is not attached to the window, thus no measurement and layout has done to RecyclerView
RecyclerView
的完整绘制发生在onCreate()
和OnResume()
Apparently complete drawing of RecyclerView
happens sometime after onCreate()
and OnResume()
@Override
protected void onResume() {
super.onResume();
boolean a = list.isAttachedToWindow();//this is false!
}
所以要使notifyItemChanged
在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 will update the item
}
});
new Thread((new Runnable() {
@Override
public void run() {
try {
Thread.sleep(28);//small amount of delay,below 20 doesn't seem to work
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyItemChanged(1, new Object());//also works
}
});
}
})).start();
我猜这是因为ViewRootImpl.performTraversal()
是由系统控制的,并且发生在DecorView
附加到onCreate
I guess the reason for this is ViewRootImpl.performTraversal()
is controlled by the system and it happens sometime after DecorView
is attached to the window which is during onCreate
我假设这只能在onCreate
和onResume
期间发生,如果以后再调用可能不会发生.
I'm assuming this can only happen during onCreate
and onResume
, it may not happen if called later.