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

@@ -3650,14 +3650,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
/**
* This is called when a container is going to temporarily detach a child
* that currently has focus, with
* @hide
*/
public void dispatchStartTemporaryDetach() {
onStartTemporaryDetach();
}
/**
* This is called when a container is going to temporarily detach a child, with
* {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}.
* It will either be followed by {@link #onFinishTemporaryDetach()} or
* {@link #onDetachedFromWindow()} when the container is done. Generally
* this is currently only done ListView for a view with focus.
* {@link #onDetachedFromWindow()} when the container is done.
*/
public void onStartTemporaryDetach() {
removeUnsetPressCallback();
}
/**
* @hide
*/
public void dispatchFinishTemporaryDetach() {
onFinishTemporaryDetach();
}
/**
@@ -4361,6 +4374,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
}
/**
* Remove the prepress detection timer.
*/
private void removeUnsetPressCallback() {
if ((mPrivateFlags & PRESSED) != 0 && mUnsetPressedState != null) {
setPressed(false);
removeCallbacks(mUnsetPressedState);
}
}
/**
* Remove the tap detection timer.
*/
@@ -5886,6 +5909,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @see #onAttachedToWindow()
*/
protected void onDetachedFromWindow() {
removeUnsetPressCallback();
removeLongPressCallback();
destroyDrawingCache();
}
@@ -8731,7 +8755,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
boolean clampedX, boolean clampedY) {
// Intentionally empty.
}
/**
* A MeasureSpec encapsulates the layout requirements passed from parent to child.
* Each MeasureSpec represents a requirement for either the width or the height.
@@ -9181,12 +9205,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
*/
boolean mRecomputeGlobalAttributes;
/**
* Set to true when attributes (like mKeepScreenOn) need to be
* recomputed.
*/
boolean mAttributesChanged;
/**
* Set during a traveral if any views want to keep the screen on.
*/

View File

@@ -1065,6 +1065,32 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void dispatchStartTemporaryDetach() {
super.dispatchStartTemporaryDetach();
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
children[i].dispatchStartTemporaryDetach();
}
}
/**
* {@inheritDoc}
*/
@Override
public void dispatchFinishTemporaryDetach() {
super.dispatchFinishTemporaryDetach();
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
children[i].dispatchFinishTemporaryDetach();
}
}
/**
* {@inheritDoc}