2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.launcher3.widget;
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.os.CancellationSignal;
22 import android.util.AttributeSet;
23 import android.util.Log;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.View.OnLayoutChangeListener;
27 import android.view.ViewGroup;
28 import android.view.ViewPropertyAnimator;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
32 import com.android.launcher3.BaseActivity;
33 import com.android.launcher3.DeviceProfile;
34 import com.android.launcher3.R;
35 import com.android.launcher3.SimpleOnStylusPressListener;
36 import com.android.launcher3.StylusEventHelper;
37 import com.android.launcher3.WidgetPreviewLoader;
38 import com.android.launcher3.graphics.DrawableFactory;
39 import com.android.launcher3.model.WidgetItem;
42 * Represents the individual cell of the widget inside the widget tray. The preview is drawn
43 * horizontally centered, and scaled down if needed.
45 * This view does not support padding. Since the image is scaled down to fit the view, padding will
46 * further decrease the scaling factor. Drag-n-drop uses the view bounds for showing a smooth
47 * transition from the view to drag view, so when adding padding support, DnD would need to
48 * consider the appropriate scaling factor.
50 public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
52 private static final String TAG = "WidgetCell";
53 private static final boolean DEBUG = false;
55 private static final int FADE_IN_DURATION_MS = 90;
57 /** Widget cell width is calculated by multiplying this factor to grid cell width. */
58 private static final float WIDTH_SCALE = 2.6f;
60 /** Widget preview width is calculated by multiplying this factor to the widget cell width. */
61 private static final float PREVIEW_SCALE = 0.8f;
63 protected int mPresetPreviewSize;
64 private int mCellSize;
66 private WidgetImageView mWidgetImage;
67 private TextView mWidgetName;
68 private TextView mWidgetDims;
70 protected WidgetItem mItem;
72 private WidgetPreviewLoader mWidgetPreviewLoader;
73 private StylusEventHelper mStylusEventHelper;
75 protected CancellationSignal mActiveRequest;
76 private boolean mAnimatePreview = true;
78 protected final BaseActivity mActivity;
80 public WidgetCell(Context context) {
84 public WidgetCell(Context context, AttributeSet attrs) {
85 this(context, attrs, 0);
88 public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
89 super(context, attrs, defStyle);
91 mActivity = BaseActivity.fromContext(context);
92 mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
95 setWillNotDraw(false);
96 setClipToPadding(false);
97 setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
100 private void setContainerWidth() {
101 DeviceProfile profile = mActivity.getDeviceProfile();
102 mCellSize = (int) (profile.cellWidthPx * WIDTH_SCALE);
103 mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
107 protected void onFinishInflate() {
108 super.onFinishInflate();
110 mWidgetImage = (WidgetImageView) findViewById(R.id.widget_preview);
111 mWidgetName = ((TextView) findViewById(R.id.widget_name));
112 mWidgetDims = ((TextView) findViewById(R.id.widget_dims));
116 * Called to clear the view and free attached resources. (e.g., {@link Bitmap}
118 public void clear() {
120 Log.d(TAG, "reset called on:" + mWidgetName.getText());
122 mWidgetImage.animate().cancel();
123 mWidgetImage.setBitmap(null, null);
124 mWidgetName.setText(null);
125 mWidgetDims.setText(null);
127 if (mActiveRequest != null) {
128 mActiveRequest.cancel();
129 mActiveRequest = null;
133 public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
135 mWidgetName.setText(mItem.label);
136 mWidgetDims.setText(getContext().getString(R.string.widget_dims_format,
137 mItem.spanX, mItem.spanY));
138 mWidgetDims.setContentDescription(getContext().getString(
139 R.string.widget_accessible_dims_format, mItem.spanX, mItem.spanY));
140 mWidgetPreviewLoader = loader;
142 if (item.activityInfo != null) {
143 setTag(new PendingAddShortcutInfo(item.activityInfo));
145 setTag(new PendingAddWidgetInfo(item.widgetInfo));
149 public WidgetImageView getWidgetView() {
153 public void setAnimatePreview(boolean shouldAnimate) {
154 mAnimatePreview = shouldAnimate;
157 public void applyPreview(Bitmap bitmap) {
158 if (bitmap != null) {
159 mWidgetImage.setBitmap(bitmap,
160 DrawableFactory.get(getContext()).getBadgeForUser(mItem.user, getContext()));
161 if (mAnimatePreview) {
162 mWidgetImage.setAlpha(0f);
163 ViewPropertyAnimator anim = mWidgetImage.animate();
164 anim.alpha(1.0f).setDuration(FADE_IN_DURATION_MS);
166 mWidgetImage.setAlpha(1f);
171 public void ensurePreview() {
172 if (mActiveRequest != null) {
175 mActiveRequest = mWidgetPreviewLoader.getPreview(
176 mItem, mPresetPreviewSize, mPresetPreviewSize, this);
180 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
181 int oldTop, int oldRight, int oldBottom) {
182 removeOnLayoutChangeListener(this);
187 public boolean onTouchEvent(MotionEvent ev) {
188 boolean handled = super.onTouchEvent(ev);
189 if (mStylusEventHelper.onMotionEvent(ev)) {
196 * Helper method to get the string info of the tag.
198 private String getTagToString() {
199 if (getTag() instanceof PendingAddWidgetInfo ||
200 getTag() instanceof PendingAddShortcutInfo) {
201 return getTag().toString();
207 public void setLayoutParams(ViewGroup.LayoutParams params) {
208 params.width = params.height = mCellSize;
209 super.setLayoutParams(params);
213 public CharSequence getAccessibilityClassName() {
214 return WidgetCell.class.getName();