blob: a7728a11b7272081d12fec048fa6e7279917e9d5 [file] [log] [blame]
Hyunyoung Song3f471442015-04-08 19:01:34 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.launcher3.widget;
17
18import android.content.Context;
19import android.content.pm.ResolveInfo;
20import android.support.v7.widget.RecyclerView.Adapter;
21import android.util.Log;
22import android.view.LayoutInflater;
23import android.view.View;
24import android.view.ViewGroup;
25import android.widget.ImageView;
26import android.widget.TextView;
27
28import com.android.launcher3.IconCache;
29import com.android.launcher3.Launcher;
30import com.android.launcher3.LauncherAppState;
31import com.android.launcher3.LauncherAppWidgetProviderInfo;
32import com.android.launcher3.R;
33import com.android.launcher3.WidgetPreviewLoader;
34import com.android.launcher3.compat.UserHandleCompat;
35
36import java.util.List;
37
38/**
39 * List view adapter for the widget tray.
40 *
41 * <p>Memory vs. Performance:
42 * The less number of types of views are inserted into a {@link RecyclerView}, the more recycling
43 * happens and less memory is consumed. {@link #getItemViewType} was not overridden as there is
44 * only a single type of view.
45 */
46public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> {
47
48 private static final String TAG = "WidgetsListAdapter";
49 private static final boolean DEBUG = false;
50
51 private Context mContext;
52 private Launcher mLauncher;
53 private LayoutInflater mLayoutInflater;
54 private IconCache mIconCache;
55
56 private WidgetsModel mWidgetsModel;
57 private WidgetPreviewLoader mWidgetPreviewLoader;
58
Hyunyoung Song3f471442015-04-08 19:01:34 -070059 private View.OnClickListener mIconClickListener;
60 private View.OnLongClickListener mIconLongClickListener;
61
Hyunyoung Song3f471442015-04-08 19:01:34 -070062 public WidgetsListAdapter(Context context,
Hyunyoung Song3f471442015-04-08 19:01:34 -070063 View.OnClickListener iconClickListener,
64 View.OnLongClickListener iconLongClickListener,
65 Launcher launcher) {
66 mLayoutInflater = LayoutInflater.from(context);
67 mContext = context;
68
Hyunyoung Song3f471442015-04-08 19:01:34 -070069 mIconClickListener = iconClickListener;
70 mIconLongClickListener = iconLongClickListener;
71
72 mLauncher = launcher;
73 mIconCache = LauncherAppState.getInstance().getIconCache();
74 }
75
76 public void setWidgetsModel(WidgetsModel w) {
77 mWidgetsModel = w;
78 }
79
80 @Override
81 public int getItemCount() {
82 return mWidgetsModel.getPackageSize();
83 }
84
85 @Override
86 public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) {
Hyunyoung Song4e8fb912015-04-11 15:44:32 -070087 List<Object> infoList = mWidgetsModel.getSortedWidgets(pos);
Hyunyoung Song3f471442015-04-08 19:01:34 -070088
89 ViewGroup row = ((ViewGroup) holder.getContent().findViewById(R.id.widgets_cell_list));
90 if (DEBUG) {
91 Log.d(TAG, String.format(
Hyunyoung Song4e8fb912015-04-11 15:44:32 -070092 "onBindViewHolder [pos=%d, widget#=%d, row.getChildCount=%d]",
93 pos, infoList.size(), row.getChildCount()));
Hyunyoung Song3f471442015-04-08 19:01:34 -070094 }
95
96 // Add more views.
97 // if there are too many, hide them.
98 int diff = infoList.size() - row.getChildCount();
99 if (diff > 0) {
100 for (int i = 0; i < diff; i++) {
101 WidgetCell widget = new WidgetCell(mContext);
102 widget = (WidgetCell) mLayoutInflater.inflate(
103 R.layout.widget_cell, row, false);
104
105 // set up touch.
106 widget.setOnClickListener(mIconClickListener);
107 widget.setOnLongClickListener(mIconLongClickListener);
Hyunyoung Song3f471442015-04-08 19:01:34 -0700108 row.addView(widget);
109 }
110 } else if (diff < 0) {
111 for (int i=infoList.size() ; i < row.getChildCount(); i++) {
112 row.getChildAt(i).setVisibility(View.GONE);
113 }
114 }
115
116 // Bind the views in the application info section.
Hyunyoung Song4e8fb912015-04-11 15:44:32 -0700117 PackageItemInfo infoOut = mWidgetsModel.getPackageItemInfo(pos);
Hyunyoung Song3f471442015-04-08 19:01:34 -0700118 if (infoOut.usingLowResIcon) {
Hyunyoung Song4e8fb912015-04-11 15:44:32 -0700119 // TODO(hyunyoungs): call this in none UI thread in the same way as BubbleTextView.
120 mIconCache.getTitleAndIconForApp(infoOut.packageName,
121 UserHandleCompat.myUserHandle(), false /* useLowResIcon */, infoOut);
Hyunyoung Song3f471442015-04-08 19:01:34 -0700122 }
Hyunyoung Song559d90d2015-04-28 15:06:45 -0700123
124 TextView tv = ((TextView) holder.getContent().findViewById(R.id.section));
125 tv.setText(infoOut.title);
Hyunyoung Song3f471442015-04-08 19:01:34 -0700126 ImageView iv = (ImageView) holder.getContent().findViewById(R.id.section_image);
127 iv.setImageBitmap(infoOut.iconBitmap);
128
129 // Bind the view in the widget horizontal tray region.
130 for (int i=0; i < infoList.size(); i++) {
131 WidgetCell widget = (WidgetCell) row.getChildAt(i);
Hyunyoung Song4e8fb912015-04-11 15:44:32 -0700132 if (getWidgetPreviewLoader() == null) {
Hyunyoung Song3f471442015-04-08 19:01:34 -0700133 return;
134 }
135 if (infoList.get(i) instanceof LauncherAppWidgetProviderInfo) {
136 LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) infoList.get(i);
137 PendingAddWidgetInfo pawi = new PendingAddWidgetInfo(info, null);
138 widget.setTag(pawi);
139 widget.applyFromAppWidgetProviderInfo(info, -1, mWidgetPreviewLoader);
140 } else if (infoList.get(i) instanceof ResolveInfo) {
141 ResolveInfo info = (ResolveInfo) infoList.get(i);
142 PendingAddShortcutInfo pasi = new PendingAddShortcutInfo(info.activityInfo);
143 widget.setTag(pasi);
144 widget.applyFromResolveInfo(mLauncher.getPackageManager(), info, mWidgetPreviewLoader);
145 }
146 widget.setVisibility(View.VISIBLE);
147 widget.ensurePreview();
148 }
Hyunyoung Song3f471442015-04-08 19:01:34 -0700149 }
150
151 @Override
152 public WidgetsRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
153 if (DEBUG) {
Hyunyoung Song559d90d2015-04-28 15:06:45 -0700154 Log.v(TAG, "\nonCreateViewHolder");
Hyunyoung Song3f471442015-04-08 19:01:34 -0700155 }
156
157 ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
158 R.layout.widgets_list_row_view, parent, false);
159 return new WidgetsRowViewHolder(container);
160 }
161
162 @Override
Hyunyoung Songf17a1c92015-04-27 17:01:32 -0700163 public void onViewRecycled(WidgetsRowViewHolder holder) {
164 ViewGroup row = ((ViewGroup) holder.getContent().findViewById(R.id.widgets_cell_list));
165
166 for (int i = 0; i < row.getChildCount(); i++) {
167 WidgetCell widget = (WidgetCell) row.getChildAt(i);
Hyunyoung Song559d90d2015-04-28 15:06:45 -0700168 widget.clear();
Hyunyoung Songf17a1c92015-04-27 17:01:32 -0700169 }
170 }
171
172 @Override
Hyunyoung Song3f471442015-04-08 19:01:34 -0700173 public long getItemId(int pos) {
174 return pos;
175 }
176
177 private WidgetPreviewLoader getWidgetPreviewLoader() {
178 if (mWidgetPreviewLoader == null) {
179 mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
180 }
181 return mWidgetPreviewLoader;
182 }
Hyunyoung Song3f471442015-04-08 19:01:34 -0700183}