summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@android.com>2010-02-24 15:57:54 -0800
committerRomain Guy <romainguy@android.com>2010-02-24 17:15:40 -0800
commita440b002aa59e1455bdfa2c5a1ca51c74bbc19ac (patch)
treecd5dbf227fe9481a2e9d8b08bb301d3f3fb7cdd5
parent618c8f1ede12d81fc4fee3d6fb239940f7e2023d (diff)
downloadframeworks_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.java40
-rw-r--r--core/java/android/view/ViewGroup.java26
-rw-r--r--core/java/android/widget/AbsListView.java8
-rw-r--r--core/java/android/widget/ListView.java1
-rw-r--r--core/java/android/widget/TextView.java18
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