diff options
author | Alan Viverette <alanv@google.com> | 2013-08-07 15:47:04 -0700 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2013-08-07 15:47:04 -0700 |
commit | 39bed695cecdbefc9fae785692fe468cd9007c35 (patch) | |
tree | 49e270ed2bcd3f99e2d70f01ef33a1c3f55de8a1 /core | |
parent | 18ec40c44c936fd5146133ccc7446a4cd860b527 (diff) | |
download | frameworks_base-39bed695cecdbefc9fae785692fe468cd9007c35.zip frameworks_base-39bed695cecdbefc9fae785692fe468cd9007c35.tar.gz frameworks_base-39bed695cecdbefc9fae785692fe468cd9007c35.tar.bz2 |
Fix FastScroller regression for non-UI threads
Previously it was safe to call setFastScrollEnabled() and
setFastScrollAlwaysVisible() off the UI thread. After switching
FastScroller to use an Overlay, these methods stopped working.
This change ensures that all direct interaction with FastScroller
happens on the thread that created the host AbsListView.
BUG: 10210504
Change-Id: Ib6d9bd9212965420c0de39546652e3bc2d32ff8b
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/widget/AbsListView.java | 70 | ||||
-rw-r--r-- | core/java/android/widget/FastScroller.java | 3 |
2 files changed, 61 insertions, 12 deletions
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 2d7637c..e7227e3 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -223,6 +223,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public static final int CHOICE_MODE_MULTIPLE_MODAL = 3; /** + * The thread that created this view. + */ + private final Thread mOwnerThread; + + /** * Controls if/how the user may choose/check items in the list */ int mChoiceMode = CHOICE_MODE_NONE; @@ -438,6 +443,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te boolean mFastScrollEnabled; /** + * Whether or not to always show the fast scroll feature on this list + */ + boolean mFastScrollAlwaysVisible; + + /** * Optional callback to notify client when scroll position has changed */ private OnScrollListener mOnScrollListener; @@ -756,6 +766,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te super(context); initAbsListView(); + mOwnerThread = Thread.currentThread(); + setVerticalScrollBarEnabled(true); TypedArray a = context.obtainStyledAttributes(R.styleable.View); initializeScrollbars(a); @@ -770,6 +782,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te super(context, attrs, defStyle); initAbsListView(); + mOwnerThread = Thread.currentThread(); + TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AbsListView, defStyle, 0); @@ -1205,15 +1219,28 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @see #isFastScrollEnabled() * @param enabled whether or not to enable fast scrolling */ - public void setFastScrollEnabled(boolean enabled) { - mFastScrollEnabled = enabled; + public void setFastScrollEnabled(final boolean enabled) { + if (mFastScrollEnabled != enabled) { + mFastScrollEnabled = enabled; - if (enabled && mFastScroller == null) { - mFastScroller = new FastScroller(getContext(), this); + if (isOwnerThread()) { + setFastScrollerEnabledUiThread(enabled); + } else { + post(new Runnable() { + @Override + public void run() { + setFastScrollerEnabledUiThread(enabled); + } + }); + } } + } + private void setFastScrollerEnabledUiThread(boolean enabled) { if (mFastScroller != null) { mFastScroller.setEnabled(enabled); + } else if (enabled) { + mFastScroller = new FastScroller(this); } } @@ -1228,17 +1255,38 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @see #setScrollBarStyle(int) * @see #setFastScrollEnabled(boolean) */ - public void setFastScrollAlwaysVisible(boolean alwaysShow) { - if (alwaysShow && !mFastScrollEnabled) { - setFastScrollEnabled(true); + public void setFastScrollAlwaysVisible(final boolean alwaysShow) { + if (mFastScrollAlwaysVisible != alwaysShow) { + if (alwaysShow && !mFastScrollEnabled) { + setFastScrollEnabled(true); + } + + mFastScrollAlwaysVisible = alwaysShow; + + if (isOwnerThread()) { + setFastScrollerAlwaysVisibleUiThread(alwaysShow); + } else { + post(new Runnable() { + @Override + public void run() { + setFastScrollerAlwaysVisibleUiThread(alwaysShow); + } + }); + } } + } + private void setFastScrollerAlwaysVisibleUiThread(boolean alwaysShow) { if (mFastScroller != null) { mFastScroller.setAlwaysShow(alwaysShow); } + } - computeOpaqueFlags(); - recomputePadding(); + /** + * @return whether the current thread is the one that created the view + */ + private boolean isOwnerThread() { + return mOwnerThread == Thread.currentThread(); } /** @@ -1249,12 +1297,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @see #setFastScrollAlwaysVisible(boolean) */ public boolean isFastScrollAlwaysVisible() { - return mFastScrollEnabled && mFastScroller.isAlwaysShowEnabled(); + return mFastScrollEnabled && mFastScrollAlwaysVisible; } @Override public int getVerticalScrollbarWidth() { - if (isFastScrollAlwaysVisible()) { + if (isFastScrollAlwaysVisible() && mFastScroller != null) { return Math.max(super.getVerticalScrollbarWidth(), mFastScroller.getWidth()); } return super.getVerticalScrollbarWidth(); diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index d08e38e..b3b00b1 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -231,10 +231,11 @@ class FastScroller { } }; - public FastScroller(Context context, AbsListView listView) { + public FastScroller(AbsListView listView) { mList = listView; mOverlay = listView.getOverlay(); + final Context context = listView.getContext(); mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); final Resources res = context.getResources(); |