diff options
| author | 2012-01-17 15:25:22 -0800 | |
|---|---|---|
| committer | 2012-01-17 15:25:22 -0800 | |
| commit | 792840d48a70888942df41bbf7c531b14ef14792 (patch) | |
| tree | 10cf28336df02533ad7582a308153341b7cd0e11 | |
| parent | 73d27c3d46ce9a19c0cc358d0b2788f1f51706d7 (diff) | |
| parent | b967392e0170af8cfd8053fd43fcdf8c46f703e9 (diff) | |
Merge "Hinting RemoteViewsAdapter as to which views are visible"
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 10 | ||||
| -rw-r--r-- | core/java/android/widget/AdapterViewAnimator.java | 3 | ||||
| -rw-r--r-- | core/java/android/widget/GridView.java | 2 | ||||
| -rw-r--r-- | core/java/android/widget/ListView.java | 3 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViewsAdapter.java | 39 |
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 |