summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adam Cohen <adamcohen@google.com> 2012-01-17 15:25:22 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2012-01-17 15:25:22 -0800
commit792840d48a70888942df41bbf7c531b14ef14792 (patch)
tree10cf28336df02533ad7582a308153341b7cd0e11
parent73d27c3d46ce9a19c0cc358d0b2788f1f51706d7 (diff)
parentb967392e0170af8cfd8053fd43fcdf8c46f703e9 (diff)
Merge "Hinting RemoteViewsAdapter as to which views are visible"
-rw-r--r--core/java/android/widget/AbsListView.java10
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java3
-rw-r--r--core/java/android/widget/GridView.java2
-rw-r--r--core/java/android/widget/ListView.java3
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java39
5 files changed, 47 insertions, 10 deletions
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 38bb2e1bde81..0ba4541659a0 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5572,6 +5572,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
+ * Hints the RemoteViewsAdapter, if it exists, about which views are currently
+ * being displayed by the AbsListView.
+ */
+ void setVisibleRangeHint(int start, int end) {
+ if (mRemoteAdapter != null) {
+ mRemoteAdapter.setVisibleRangeHint(start, end);
+ }
+ }
+
+ /**
* Sets the recycler listener to be notified whenever a View is set aside in
* the recycler for later reuse. This listener can be used to free resources
* associated to the View.
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index c83c78088617..9ea7b33401ba 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -555,6 +555,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
mCurrentWindowStart = newWindowStart;
mCurrentWindowEnd = newWindowEnd;
mCurrentWindowStartUnbounded = newWindowStartUnbounded;
+ if (mRemoteViewsAdapter != null) {
+ mRemoteViewsAdapter.setVisibleRangeHint(mCurrentWindowStart, mCurrentWindowEnd);
+ }
}
requestLayout();
invalidate();
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 5d406de007dc..5c1eb94fd084 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -290,6 +290,7 @@ public class GridView extends AbsListView {
pos += mNumColumns;
}
+ setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);
return selectedView;
}
@@ -382,6 +383,7 @@ public class GridView extends AbsListView {
mFirstPosition = Math.max(0, pos + 1);
}
+ setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);
return selectedView;
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 7f7a3a715a23..b6371a7073e9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -678,6 +678,7 @@ public class ListView extends AbsListView {
pos++;
}
+ setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);
return selectedView;
}
@@ -711,7 +712,7 @@ public class ListView extends AbsListView {
}
mFirstPosition = pos + 1;
-
+ setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);
return selectedView;
}
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 7b430328ef0f..586fdf4da501 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -68,6 +68,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
private RemoteViewsAdapterServiceConnection mServiceConnection;
private WeakReference<RemoteAdapterConnectionCallback> mCallback;
private FixedSizeRemoteViewsCache mCache;
+ private int mVisibleWindowLowerBound;
+ private int mVisibleWindowUpperBound;
// A flag to determine whether we should notify data set changed after we connect
private boolean mNotifyDataSetChangedAfterOnServiceConnected = false;
@@ -765,7 +767,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
if (position > -1) {
// Load the item, and notify any existing RemoteViewsFrameLayouts
- updateRemoteViews(position, isRequested);
+ updateRemoteViews(position, isRequested, true);
// Queue up for the next one to load
loadNextIndexInBackground();
@@ -827,8 +829,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
}
- private void updateRemoteViews(final int position, boolean isRequested) {
- if (!mServiceConnection.isConnected()) return;
+ private void updateRemoteViews(final int position, boolean isRequested, boolean
+ notifyWhenLoaded) {
IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
// Load the item information from the remote service
@@ -864,12 +866,14 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
// there is new data for it.
final RemoteViews rv = remoteViews;
final int typeId = mCache.getMetaDataAt(position).typeId;
- mMainQueue.post(new Runnable() {
- @Override
- public void run() {
- mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
- }
- });
+ if (notifyWhenLoaded) {
+ mMainQueue.post(new Runnable() {
+ @Override
+ public void run() {
+ mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
+ }
+ });
+ }
}
}
@@ -929,6 +933,16 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
return typeId;
}
+ /**
+ * This method allows an AdapterView using this Adapter to provide information about which
+ * views are currently being displayed. This allows for certain optimizations and preloading
+ * which wouldn't otherwise be possible.
+ */
+ public void setVisibleRangeHint(int lowerBound, int upperBound) {
+ mVisibleWindowLowerBound = lowerBound;
+ mVisibleWindowUpperBound = upperBound;
+ }
+
public View getView(int position, View convertView, ViewGroup parent) {
// "Request" an index so that we can queue it for loading, initiate subsequent
// preloading, etc.
@@ -1059,6 +1073,13 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
// Re-request the new metadata (only after the notification to the factory)
updateTemporaryMetaData();
+ // Pre-load (our best guess of) the views which are currently visible in the AdapterView.
+ // This mitigates flashing and flickering of loading views when a widget notifies that
+ // its data has changed.
+ for (int i = mVisibleWindowLowerBound; i <= mVisibleWindowUpperBound; i++) {
+ updateRemoteViews(i, false, false);
+ }
+
// Propagate the notification back to the base adapter
mMainQueue.post(new Runnable() {
@Override