summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2013-08-07 15:47:04 -0700
committerAlan Viverette <alanv@google.com>2013-08-07 15:47:04 -0700
commit39bed695cecdbefc9fae785692fe468cd9007c35 (patch)
tree49e270ed2bcd3f99e2d70f01ef33a1c3f55de8a1 /core
parent18ec40c44c936fd5146133ccc7446a4cd860b527 (diff)
downloadframeworks_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.java70
-rw-r--r--core/java/android/widget/FastScroller.java3
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();