summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/widget/WidgetsListAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/widget/WidgetsListAdapter.java')
-rw-r--r--src/com/android/launcher3/widget/WidgetsListAdapter.java218
1 files changed, 218 insertions, 0 deletions
diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java
new file mode 100644
index 000000000..f1cde299d
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.os.Build;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.LinearLayout;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.WidgetPreviewLoader;
+import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.model.WidgetsModel;
+
+import java.util.List;
+
+/**
+ * List view adapter for the widget tray.
+ *
+ * <p>Memory vs. Performance:
+ * The less number of types of views are inserted into a {@link RecyclerView}, the more recycling
+ * happens and less memory is consumed. {@link #getItemViewType} was not overridden as there is
+ * only a single type of view.
+ */
+public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> {
+
+ private static final String TAG = "WidgetsListAdapter";
+ private static final boolean DEBUG = false;
+
+ private Launcher mLauncher;
+ private LayoutInflater mLayoutInflater;
+
+ private WidgetsModel mWidgetsModel;
+ private WidgetPreviewLoader mWidgetPreviewLoader;
+
+ private View.OnClickListener mIconClickListener;
+ private View.OnLongClickListener mIconLongClickListener;
+
+ private static final int PRESET_INDENT_SIZE_TABLET = 56;
+ private int mIndent = 0;
+
+ public WidgetsListAdapter(Context context,
+ View.OnClickListener iconClickListener,
+ View.OnLongClickListener iconLongClickListener,
+ Launcher launcher) {
+ mLayoutInflater = LayoutInflater.from(context);
+
+ mIconClickListener = iconClickListener;
+ mIconLongClickListener = iconLongClickListener;
+ mLauncher = launcher;
+
+ setContainerHeight();
+ }
+
+ public void setWidgetsModel(WidgetsModel w) {
+ mWidgetsModel = w;
+ }
+
+ @Override
+ public int getItemCount() {
+ if (mWidgetsModel == null) {
+ return 0;
+ }
+ return mWidgetsModel.getPackageSize();
+ }
+
+ @Override
+ public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) {
+ List<Object> infoList = mWidgetsModel.getSortedWidgets(pos);
+
+ ViewGroup row = ((ViewGroup) holder.getContent().findViewById(R.id.widgets_cell_list));
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "onBindViewHolder [pos=%d, widget#=%d, row.getChildCount=%d]",
+ pos, infoList.size(), row.getChildCount()));
+ }
+
+ // Add more views.
+ // if there are too many, hide them.
+ int diff = infoList.size() - row.getChildCount();
+
+ if (diff > 0) {
+ for (int i = 0; i < diff; i++) {
+ WidgetCell widget = (WidgetCell) mLayoutInflater.inflate(
+ R.layout.widget_cell, row, false);
+
+ // set up touch.
+ widget.setOnClickListener(mIconClickListener);
+ widget.setOnLongClickListener(mIconLongClickListener);
+ LayoutParams lp = widget.getLayoutParams();
+ lp.height = widget.cellSize;
+ lp.width = widget.cellSize;
+ widget.setLayoutParams(lp);
+
+ row.addView(widget);
+ }
+ } else if (diff < 0) {
+ for (int i=infoList.size() ; i < row.getChildCount(); i++) {
+ row.getChildAt(i).setVisibility(View.GONE);
+ }
+ }
+
+ // Bind the views in the application info section.
+ PackageItemInfo infoOut = mWidgetsModel.getPackageItemInfo(pos);
+ BubbleTextView tv = ((BubbleTextView) holder.getContent().findViewById(R.id.section));
+ tv.applyFromPackageItemInfo(infoOut);
+
+ // Bind the view in the widget horizontal tray region.
+ if (getWidgetPreviewLoader() == null) {
+ return;
+ }
+ for (int i=0; i < infoList.size(); i++) {
+ WidgetCell widget = (WidgetCell) row.getChildAt(i);
+ if (infoList.get(i) instanceof LauncherAppWidgetProviderInfo) {
+ LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) infoList.get(i);
+ PendingAddWidgetInfo pawi = new PendingAddWidgetInfo(mLauncher, info, null);
+ widget.setTag(pawi);
+ widget.applyFromAppWidgetProviderInfo(info, mWidgetPreviewLoader);
+ } else if (infoList.get(i) instanceof ResolveInfo) {
+ ResolveInfo info = (ResolveInfo) infoList.get(i);
+ PendingAddShortcutInfo pasi = new PendingAddShortcutInfo(info.activityInfo);
+ widget.setTag(pasi);
+ widget.applyFromResolveInfo(mLauncher.getPackageManager(), info, mWidgetPreviewLoader);
+ }
+ widget.ensurePreview();
+ widget.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ @Override
+ public WidgetsRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ if (DEBUG) {
+ Log.v(TAG, "\nonCreateViewHolder");
+ }
+
+ ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
+ R.layout.widgets_list_row_view, parent, false);
+ LinearLayout cellList = (LinearLayout) container.findViewById(R.id.widgets_cell_list);
+
+ // if the end padding is 0, then container view (horizontal scroll view) doesn't respect
+ // the end of the linear layout width + the start padding and doesn't allow scrolling.
+ if (Utilities.ATLEAST_JB_MR1) {
+ cellList.setPaddingRelative(mIndent, 0, 1, 0);
+ } else {
+ cellList.setPadding(mIndent, 0, 1, 0);
+ }
+
+ return new WidgetsRowViewHolder(container);
+ }
+
+ @Override
+ public void onViewRecycled(WidgetsRowViewHolder holder) {
+ ViewGroup row = ((ViewGroup) holder.getContent().findViewById(R.id.widgets_cell_list));
+
+ for (int i = 0; i < row.getChildCount(); i++) {
+ WidgetCell widget = (WidgetCell) row.getChildAt(i);
+ widget.clear();
+ }
+ }
+
+ public boolean onFailedToRecycleView(WidgetsRowViewHolder holder) {
+ // If child views are animating, then the RecyclerView may choose not to recycle the view,
+ // causing extraneous onCreateViewHolder() calls. It is safe in this case to continue
+ // recycling this view, and take care in onViewRecycled() to cancel any existing
+ // animations.
+ return true;
+ }
+
+ @Override
+ public long getItemId(int pos) {
+ return pos;
+ }
+
+ private WidgetPreviewLoader getWidgetPreviewLoader() {
+ if (mWidgetPreviewLoader == null) {
+ mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+ }
+ return mWidgetPreviewLoader;
+ }
+
+ private void setContainerHeight() {
+ Resources r = mLauncher.getResources();
+ DeviceProfile profile = mLauncher.getDeviceProfile();
+ if (profile.isLargeTablet || profile.isTablet) {
+ mIndent = Utilities.pxFromDp(PRESET_INDENT_SIZE_TABLET, r.getDisplayMetrics());
+ }
+ }
+}