当前位置:网站首页>Viewpager pageradapter notifydatasetchanged invalid problem
Viewpager pageradapter notifydatasetchanged invalid problem
2022-07-05 09:36:00 【Black Mountain demon 2018】
As we all know , Whether we are using RecyclerView still ListView when , After updating the data source, it will call adapter Of notifyDataSetChanged() Method to update the view . and PagerAdapter Namely ViewPager The use of adapter, But in practice , It is found that updating the data source does not necessarily update the view .
Let's take a look at Google's right PagerAdapter This method of notifyDataSetChanged() The definition of

Personally, I don't think the definition of Google's method is a good explanation for the problems I encounter in my work , So try the source code ...
/**
* This method should be called by the application if the data backing this adapter has changed
* and associated views should update.
*/
public void notifyDataSetChanged() {
synchronized (this) {
if (mViewPagerObserver != null) {
mViewPagerObserver.onChanged();
}
}
mObservable.notifyChanged();
}
At first glance, it is the observer mode , Here we only focus on mViewPagerObserver, See where it is assigned .
void setViewPagerObserver(DataSetObserver observer) {
synchronized (this) {
mViewPagerObserver = observer;
}
}Let's see where this method is called .
/**
* Set a PagerAdapter that will supply views for this pager as needed.
*
* @param adapter Adapter to use
*/
public void setAdapter(PagerAdapter adapter) {
if (mAdapter != null) {
mAdapter.setViewPagerObserver(null);
mAdapter.startUpdate(this);
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
mAdapter.destroyItem(this, ii.position, ii.object);
}
mAdapter.finishUpdate(this);
mItems.clear();
removeNonDecorViews();
mCurItem = 0;
scrollTo(0, 0);
}
final PagerAdapter oldAdapter = mAdapter;
mAdapter = adapter;
mExpectedAdapterCount = 0;
if (mAdapter != null) {
if (mObserver == null) {
mObserver = new PagerObserver();
}
mAdapter.setViewPagerObserver(mObserver);
mPopulatePending = false;
final boolean wasFirstLayout = mFirstLayout;
mFirstLayout = true;
mExpectedAdapterCount = mAdapter.getCount();
if (mRestoredCurItem >= 0) {
mAdapter.restoreState(mRestoredAdapterState, mRestoredClassLoader);
setCurrentItemInternal(mRestoredCurItem, false, true);
mRestoredCurItem = -1;
mRestoredAdapterState = null;
mRestoredClassLoader = null;
} else if (!wasFirstLayout) {
populate();
} else {
requestLayout();
}
}
// Dispatch the change to any listeners
if (mAdapterChangeListeners != null && !mAdapterChangeListeners.isEmpty()) {
for (int i = 0, count = mAdapterChangeListeners.size(); i < count; i++) {
mAdapterChangeListeners.get(i).onAdapterChanged(this, oldAdapter, adapter);
}
}
}
In the above code, it is seen in setAdapter Assign values in this method , And see mObserver = new PagerObserver();mObserver This object is also created in this method , I want to see others PagerObserver This class , Is a private inner class .
private class PagerObserver extends DataSetObserver {
PagerObserver() {
}
@Override
public void onChanged() {
dataSetChanged();
}
@Override
public void onInvalidated() {
dataSetChanged();
}
}Now it's clear ,notifyDataSetChanged() In the method mViewPagerObserver.onChanged() Execution is dataSetChanged() Method , Let's see dataSetChanged() This method .
void dataSetChanged() {
// This method only gets called if our observer is attached, so mAdapter is non-null.
final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1
&& mItems.size() < adapterCount;
int newCurrItem = mCurItem;
boolean isUpdating = false;
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
final int newPos = mAdapter.getItemPosition(ii.object);
if (newPos == PagerAdapter.POSITION_UNCHANGED) {
continue;
}
if (newPos == PagerAdapter.POSITION_NONE) {
mItems.remove(i);
i--;
if (!isUpdating) {
mAdapter.startUpdate(this);
isUpdating = true;
}
mAdapter.destroyItem(this, ii.position, ii.object);
needPopulate = true;
if (mCurItem == ii.position) {
// Keep the current item in the valid range
newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1));
needPopulate = true;
}
continue;
}
if (ii.position != newPos) {
if (ii.position == mCurItem) {
// Our current item changed position. Follow it.
newCurrItem = newPos;
}
ii.position = newPos;
needPopulate = true;
}
}
if (isUpdating) {
mAdapter.finishUpdate(this);
}
Collections.sort(mItems, COMPARATOR);
if (needPopulate) {
// Reset our known page widths; populate will recompute them.
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.isDecor) {
lp.widthFactor = 0.f;
}
}
setCurrentItemInternal(newCurrItem, false, true);
requestLayout();
}
}See the red mark , I want to see others getItemPosition() This method ,
/**
* Called when the host view is attempting to determine if an item's position
* has changed. Returns {@link #POSITION_UNCHANGED} if the position of the given
* item has not changed or {@link #POSITION_NONE} if the item is no longer present
* in the adapter.
*
* <p>The default implementation assumes that items will never
* change position and always returns {@link #POSITION_UNCHANGED}.
*
* @param object Object representing an item, previously returned by a call to
* {@link #instantiateItem(View, int)}.
* @return object's new position index from [0, {@link #getCount()}),
* {@link #POSITION_UNCHANGED} if the object's position has not changed,
* or {@link #POSITION_NONE} if the item is no longer present.
*/
public int getItemPosition(Object object) {
return POSITION_UNCHANGED;
}
Default return POSITION_UNCHANGED, This leads to the update of the data source , But the view doesn't change .
So my solution is to rewrite getItemPosition() This method , To return to POSITION_NONE. Of course, this method costs a lot of system , Do it every time destroyItem() Method , If the amount of data is small , It will cause a lot of unnecessary expenses .
边栏推荐
- [two objects merged into one object]
- [Yugong series] go teaching course 003-ide installation and basic use in July 2022
- [reading notes] Figure comparative learning gnn+cl
- 【组队 PK 赛】本周任务已开启 | 答题挑战,夯实商品详情知识
- 高性能Spark_transformation性能
- Gradientdrawable get a single color
- [how to disable El table]
- Community group buying has triggered heated discussion. How does this model work?
- 百度智能小程序巡检调度方案演进之路
- 【sourceTree配置SSH及使用】
猜你喜欢
![[ManageEngine] how to make good use of the report function of OpManager](/img/15/dc15e638ae86d6cf1d5b989fe56611.jpg)
[ManageEngine] how to make good use of the report function of OpManager

Nips2021 | new SOTA for node classification beyond graphcl, gnn+ comparative learning

Android privacy sandbox developer preview 3: privacy, security and personalized experience

AUTOSAR from getting started to mastering 100 lectures (103) -dbc file format and creation details

Why do offline stores need cashier software?

OpenGL - Model Loading

Applet customization component

Applet global style configuration window

Kotlin introductory notes (II) a brief introduction to kotlin functions

LeetCode 556. Next bigger element III
随机推荐
【对象数组a与对象数组b取出id不同元素赋值给新的数组】
图神经网络+对比学习,下一步去哪?
Analysis of eventbus source code
Kotlin introductory notes (IV) circular statements (simple explanation of while, for)
Figure neural network + comparative learning, where to go next?
Greendao reported an error in qigsaw, could not init daoconfig
Wxml template syntax
百度交易中台之钱包系统架构浅析
Multiple solutions to one problem, asp Net core application startup initialization n schemes [Part 1]
Android 隐私沙盒开发者预览版 3: 隐私安全和个性化体验全都要
揭秘百度智能测试在测试自动执行领域实践
高性能Spark_transformation性能
C form click event did not respond
Talking about the difference between unittest and pytest
The most comprehensive promotion strategy: online and offline promotion methods of E-commerce mall
Nips2021 | new SOTA for node classification beyond graphcl, gnn+ comparative learning
What about wechat mall? 5 tips to clear your mind
一次 Keepalived 高可用的事故,让我重学了一遍它
【数组的中的某个属性的监听】
AUTOSAR from getting started to mastering 100 lectures (103) -dbc file format and creation details