summaryrefslogtreecommitdiff
path: root/core/java/android/widget/RemoteViewsAdapter.java
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-02-04 15:30:48 -0800
committerSunny Goyal <sunnygoyal@google.com>2016-02-17 18:08:46 +0000
commita086f0436ad600915db1f8e0dc284d653d152e8d (patch)
treec54f735761eb29b51235f1d508974bf8c9ee5a7e /core/java/android/widget/RemoteViewsAdapter.java
parent4ea548426666c736587a7fe5ad24ab03a3466cad (diff)
Using AppWidgetHostView in RemoteViewsAdapter instead of managing the RemoteViews inflation itself
Change-Id: If6dd8a778096a07c58b543efe892bbffbe24098f (cherry picked from commit 89699a2811967fc0c3ad9e06f716d408d6949c86)
Diffstat (limited to 'core/java/android/widget/RemoteViewsAdapter.java')
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java205
1 files changed, 62 insertions, 143 deletions
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 7b6965674d06..8278c5af92cb 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import android.Manifest;
+import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
@@ -78,7 +79,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
private RemoteViewsAdapterServiceConnection mServiceConnection;
private WeakReference<RemoteAdapterConnectionCallback> mCallback;
private OnClickHandler mRemoteViewsOnClickHandler;
- private FixedSizeRemoteViewsCache mCache;
+ private final FixedSizeRemoteViewsCache mCache;
private int mVisibleWindowLowerBound;
private int mVisibleWindowUpperBound;
@@ -287,9 +288,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
* A FrameLayout which contains a loading view, and manages the re/applying of RemoteViews when
* they are loaded.
*/
- private static class RemoteViewsFrameLayout extends FrameLayout {
- public RemoteViewsFrameLayout(Context context) {
+ private static class RemoteViewsFrameLayout extends AppWidgetHostView {
+ private final FixedSizeRemoteViewsCache mCache;
+
+ public RemoteViewsFrameLayout(Context context, FixedSizeRemoteViewsCache cache) {
super(context);
+ mCache = cache;
}
/**
@@ -298,13 +302,24 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
* successfully.
*/
public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler) {
- try {
- // Remove all the children of this layout first
- removeAllViews();
- addView(view.apply(getContext(), this, handler));
- } catch (Exception e) {
- Log.e(TAG, "Failed to apply RemoteViews.");
- }
+ setOnClickHandler(handler);
+ applyRemoteViews(view);
+ }
+
+ @Override
+ protected View getDefaultView() {
+ return mCache.getMetaData().createDefaultLoadingView(this);
+ }
+
+ @Override
+ protected Context getRemoteContext() {
+ return null;
+ }
+
+ @Override
+ protected View getErrorView() {
+ // Use the default loading view as the error view.
+ return getDefaultView();
}
}
@@ -444,63 +459,33 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
return (mappedType < viewTypeCount);
}
- private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
- ViewGroup parent, Object lock, LayoutInflater layoutInflater, OnClickHandler
- handler) {
- // Create and return a new FrameLayout, and setup the references for this position
+ /**
+ * Creates a default loading view. Uses the size of the first row as a guide for the
+ * size of the loading view.
+ */
+ private synchronized View createDefaultLoadingView(ViewGroup parent) {
final Context context = parent.getContext();
- RemoteViewsFrameLayout layout = new RemoteViewsFrameLayout(context);
-
- // Create a new loading view
- synchronized (lock) {
- boolean customLoadingViewAvailable = false;
-
- if (mUserLoadingView != null) {
- // Try to inflate user-specified loading view
- try {
- View loadingView = mUserLoadingView.apply(parent.getContext(), parent,
- handler);
- loadingView.setTagInternal(com.android.internal.R.id.rowTypeId,
- new Integer(0));
- layout.addView(loadingView);
- customLoadingViewAvailable = true;
- } catch (Exception e) {
- Log.w(TAG, "Error inflating custom loading view, using default loading" +
- "view instead", e);
- }
- }
- if (!customLoadingViewAvailable) {
- // A default loading view
- // Use the size of the first row as a guide for the size of the loading view
- if (mFirstViewHeight < 0) {
- try {
- View firstView = mFirstView.apply(parent.getContext(), parent, handler);
- firstView.measure(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- mFirstViewHeight = firstView.getMeasuredHeight();
- mFirstView = null;
- } catch (Exception e) {
- float density = context.getResources().getDisplayMetrics().density;
- mFirstViewHeight = (int)
- Math.round(sDefaultLoadingViewHeight * density);
- mFirstView = null;
- Log.w(TAG, "Error inflating first RemoteViews" + e);
- }
- }
-
- // Compose the loading view text
- TextView loadingTextView = (TextView) layoutInflater.inflate(
- com.android.internal.R.layout.remote_views_adapter_default_loading_view,
- layout, false);
- loadingTextView.setHeight(mFirstViewHeight);
- loadingTextView.setTag(new Integer(0));
-
- layout.addView(loadingTextView);
+ if (mFirstViewHeight < 0) {
+ try {
+ View firstView = mFirstView.apply(parent.getContext(), parent);
+ firstView.measure(
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ mFirstViewHeight = firstView.getMeasuredHeight();
+ } catch (Exception e) {
+ float density = context.getResources().getDisplayMetrics().density;
+ mFirstViewHeight = Math.round(sDefaultLoadingViewHeight * density);
+ Log.w(TAG, "Error inflating first RemoteViews" + e);
}
+ mFirstView = null;
}
- return layout;
+ // Compose the loading view text
+ TextView loadingTextView = (TextView) LayoutInflater.from(context).inflate(
+ com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+ parent, false);
+ loadingTextView.setHeight(mFirstViewHeight);
+ return loadingTextView;
}
}
@@ -1086,21 +1071,6 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
/**
- * Returns the item type id for the specified convert view. Returns -1 if the convert view
- * is invalid.
- */
- private int getConvertViewTypeId(View convertView) {
- int typeId = -1;
- if (convertView != null) {
- Object tag = convertView.getTag(com.android.internal.R.id.rowTypeId);
- if (tag != null) {
- typeId = (Integer) tag;
- }
- }
- 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.
@@ -1114,7 +1084,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
// "Request" an index so that we can queue it for loading, initiate subsequent
// preloading, etc.
synchronized (mCache) {
- boolean isInCache = mCache.containsRemoteViewAt(position);
+ RemoteViews rv = mCache.getRemoteViewsAt(position);
+ boolean isInCache = (rv != null);
boolean isConnected = mServiceConnection.isConnected();
boolean hasNewItems = false;
@@ -1131,75 +1102,23 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
hasNewItems = mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
}
+ final RemoteViewsFrameLayout layout =
+ (convertView instanceof RemoteViewsFrameLayout)
+ ? (RemoteViewsFrameLayout) convertView
+ : new RemoteViewsFrameLayout(parent.getContext(), mCache);
if (isInCache) {
- View convertViewChild = null;
- int convertViewTypeId = 0;
- RemoteViewsFrameLayout layout = null;
-
- if (convertView instanceof RemoteViewsFrameLayout) {
- layout = (RemoteViewsFrameLayout) convertView;
- convertViewChild = layout.getChildAt(0);
- convertViewTypeId = getConvertViewTypeId(convertViewChild);
- }
-
- // Second, we try and retrieve the RemoteViews from the cache, returning a loading
- // view and queueing it to be loaded if it has not already been loaded.
- Context context = parent.getContext();
- RemoteViews rv = mCache.getRemoteViewsAt(position);
- RemoteViewsIndexMetaData indexMetaData = mCache.getMetaDataAt(position);
- int typeId = indexMetaData.typeId;
-
- try {
- // Reuse the convert view where possible
- if (layout != null) {
- if (convertViewTypeId == typeId) {
- rv.reapply(context, convertViewChild, mRemoteViewsOnClickHandler);
- return layout;
- }
- layout.removeAllViews();
- } else {
- layout = new RemoteViewsFrameLayout(context);
- }
-
- // Otherwise, create a new view to be returned
- View newView = rv.apply(context, parent, mRemoteViewsOnClickHandler);
- newView.setTagInternal(com.android.internal.R.id.rowTypeId,
- new Integer(typeId));
- layout.addView(newView);
- return layout;
-
- } catch (Exception e){
- // We have to make sure that we successfully inflated the RemoteViews, if not
- // we return the loading view instead.
- Log.w(TAG, "Error inflating RemoteViews at position: " + position + ", using" +
- "loading view instead" + e);
-
- RemoteViewsFrameLayout loadingView = null;
- final RemoteViewsMetaData metaData = mCache.getMetaData();
- synchronized (metaData) {
- loadingView = metaData.createLoadingView(position, convertView, parent,
- mCache, mLayoutInflater, mRemoteViewsOnClickHandler);
- }
- return loadingView;
- } finally {
- if (hasNewItems) loadNextIndexInBackground();
- }
+ layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler);
+ if (hasNewItems) loadNextIndexInBackground();
} else {
- // If the cache does not have the RemoteViews at this position, then create a
- // loading view and queue the actual position to be loaded in the background
- RemoteViewsFrameLayout loadingView = null;
- final RemoteViewsMetaData metaData = mCache.getMetaData();
- synchronized (metaData) {
- loadingView = metaData.createLoadingView(position, convertView, parent,
- mCache, mLayoutInflater, mRemoteViewsOnClickHandler);
- }
-
- mRequestedViews.add(position, loadingView);
+ // If the views is not loaded, apply the loading view. If the loading view doesn't
+ // exist, the layout will create a default view based on the firstView height.
+ layout.onRemoteViewsLoaded(mCache.getMetaData().mUserLoadingView,
+ mRemoteViewsOnClickHandler);
+ mRequestedViews.add(position, layout);
mCache.queueRequestedPositionToLoad(position);
loadNextIndexInBackground();
-
- return loadingView;
}
+ return layout;
}
}