Prevents ListView items children to modify properties of other children.

Bug #2464502

This fix introduce a new dispatch mechanism to tell views when they are temporary
detached/reattached from/to a ListView. This is very important to remove pending
callbacks or cleanup temporary states.

This change also modifies TextView which was relying on that callback in a very
particular case: a focused EditText in a ListView. The modified code acts only
when in that case, not if onStart/FinishTemporaryDetach() is called via
dispatch*() (== recycled views in ListView.)
This commit is contained in:
Romain Guy
2010-02-24 15:57:54 -08:00
parent 618c8f1ede
commit a440b002aa
5 changed files with 77 additions and 16 deletions

View File

@@ -1314,7 +1314,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
position, -1);
}
} else {
isScrap[0] = true;
isScrap[0] = true;
child.dispatchFinishTemporaryDetach();
}
} else {
child = mAdapter.getView(position, null, this);
@@ -4145,8 +4146,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
if (mViewTypeCount == 1) {
scrap.dispatchStartTemporaryDetach();
mCurrentScrap.add(scrap);
} else {
scrap.dispatchStartTemporaryDetach();
mScrapViews[viewType].add(scrap);
}
@@ -4165,7 +4168,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
ArrayList<View> scrapViews = mCurrentScrap;
final int count = activeViews.length;
for (int i = 0; i < count; ++i) {
for (int i = count - 1; i >= 0; i--) {
final View victim = activeViews[i];
if (victim != null) {
int whichScrap = ((AbsListView.LayoutParams) victim.getLayoutParams()).viewType;
@@ -4181,6 +4184,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (multipleScraps) {
scrapViews = mScrapViews[whichScrap];
}
victim.dispatchStartTemporaryDetach();
scrapViews.add(victim);
if (hasListener) {

View File

@@ -1485,7 +1485,6 @@ public class ListView extends AbsListView {
}
// Clear out old views
//removeAllViewsInLayout();
detachAllViewsFromParent();
switch (mLayoutMode) {

View File

@@ -198,6 +198,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private boolean mFreezesText;
private boolean mFrozenWithFocus;
private boolean mTemporaryDetach;
private boolean mDispatchTemporaryDetach;
private boolean mEatTouchRelease = false;
private boolean mScrolled = false;
@@ -6371,14 +6372,27 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mBlink.postAtTime(mBlink, mShowCursor + BLINK);
}
@Override
public void dispatchFinishTemporaryDetach() {
mDispatchTemporaryDetach = true;
super.dispatchFinishTemporaryDetach();
mDispatchTemporaryDetach = false;
}
@Override
public void onStartTemporaryDetach() {
mTemporaryDetach = true;
super.onStartTemporaryDetach();
// Only track when onStartTemporaryDetach() is called directly,
// usually because this instance is an editable field in a list
if (!mDispatchTemporaryDetach) mTemporaryDetach = true;
}
@Override
public void onFinishTemporaryDetach() {
mTemporaryDetach = false;
super.onFinishTemporaryDetach();
// Only track when onStartTemporaryDetach() is called directly,
// usually because this instance is an editable field in a list
if (!mDispatchTemporaryDetach) mTemporaryDetach = false;
}
@Override