diff options
| author | Romain Guy <romainguy@android.com> | 2010-02-24 15:57:54 -0800 |
|---|---|---|
| committer | Romain Guy <romainguy@android.com> | 2010-02-24 17:15:40 -0800 |
| commit | a440b002aa59e1455bdfa2c5a1ca51c74bbc19ac (patch) | |
| tree | cd5dbf227fe9481a2e9d8b08bb301d3f3fb7cdd5 | |
| parent | 618c8f1ede12d81fc4fee3d6fb239940f7e2023d (diff) | |
| download | frameworks_base-a440b002aa59e1455bdfa2c5a1ca51c74bbc19ac.zip frameworks_base-a440b002aa59e1455bdfa2c5a1ca51c74bbc19ac.tar.gz frameworks_base-a440b002aa59e1455bdfa2c5a1ca51c74bbc19ac.tar.bz2 | |
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.)
| -rw-r--r-- | core/java/android/view/View.java | 40 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 26 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 8 | ||||
| -rw-r--r-- | core/java/android/widget/ListView.java | 1 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 18 |
5 files changed, 77 insertions, 16 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 2eb633f..f6f5235 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -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(); } /** @@ -4362,6 +4375,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. */ private void removeTapCallback() { @@ -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. @@ -9182,12 +9206,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. */ boolean mKeepScreenOn; diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 0663215..aac1068 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -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} diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 17d5bb7..9ddfeff 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -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) { diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 2feed03..8d688a5 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1485,7 +1485,6 @@ public class ListView extends AbsListView { } // Clear out old views - //removeAllViewsInLayout(); detachAllViewsFromParent(); switch (mLayoutMode) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index cea6d3b..cb44fa8 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -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; @@ -6372,13 +6373,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } @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 |
