• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package com.android.messaging.ui.mediapicker;
17 
18 import android.content.Context;
19 import android.database.Cursor;
20 import android.graphics.Rect;
21 import android.util.AttributeSet;
22 import android.view.MotionEvent;
23 import android.view.TouchDelegate;
24 import android.view.View;
25 import android.widget.CheckBox;
26 import android.widget.FrameLayout;
27 import android.widget.ImageView.ScaleType;
28 
29 import com.android.messaging.R;
30 import com.android.messaging.datamodel.DataModel;
31 import com.android.messaging.datamodel.data.GalleryGridItemData;
32 import com.android.messaging.ui.AsyncImageView;
33 import com.android.messaging.ui.ConversationDrawables;
34 import com.google.common.annotations.VisibleForTesting;
35 
36 import java.util.concurrent.TimeUnit;
37 
38 /**
39  * Shows an item in the gallery picker grid view. Hosts an FileImageView with a checkbox.
40  */
41 public class GalleryGridItemView extends FrameLayout {
42     /**
43      * Implemented by the owner of this GalleryGridItemView instance to communicate on media
44      * picking and selection events.
45      */
46     public interface HostInterface {
onItemClicked(View view, GalleryGridItemData data, boolean longClick)47         void onItemClicked(View view, GalleryGridItemData data, boolean longClick);
isItemSelected(GalleryGridItemData data)48         boolean isItemSelected(GalleryGridItemData data);
isMultiSelectEnabled()49         boolean isMultiSelectEnabled();
50     }
51 
52     @VisibleForTesting
53     GalleryGridItemData mData;
54     private AsyncImageView mImageView;
55     private CheckBox mCheckBox;
56     private HostInterface mHostInterface;
57     private final OnClickListener mOnClickListener = new OnClickListener() {
58         @Override
59         public void onClick(final View v) {
60             mHostInterface.onItemClicked(GalleryGridItemView.this, mData, false /*longClick*/);
61         }
62     };
63 
GalleryGridItemView(final Context context, final AttributeSet attrs)64     public GalleryGridItemView(final Context context, final AttributeSet attrs) {
65         super(context, attrs);
66         mData = DataModel.get().createGalleryGridItemData();
67     }
68 
69     @Override
onFinishInflate()70     protected void onFinishInflate() {
71         super.onFinishInflate();
72         mImageView = (AsyncImageView) findViewById(R.id.image);
73         mCheckBox = (CheckBox) findViewById(R.id.checkbox);
74         mCheckBox.setOnClickListener(mOnClickListener);
75         setOnClickListener(mOnClickListener);
76         final OnLongClickListener longClickListener = new OnLongClickListener() {
77             @Override
78             public boolean onLongClick(final View v) {
79                 mHostInterface.onItemClicked(v, mData, true /* longClick */);
80                 return true;
81             }
82         };
83         setOnLongClickListener(longClickListener);
84         mCheckBox.setOnLongClickListener(longClickListener);
85         addOnLayoutChangeListener(new OnLayoutChangeListener() {
86             @Override
87             public void onLayoutChange(View v, int left, int top, int right, int bottom,
88                     int oldLeft, int oldTop, int oldRight, int oldBottom) {
89                 // Enlarge the clickable region for the checkbox to fill the entire view.
90                 final Rect region = new Rect(0, 0, getWidth(), getHeight());
91                 setTouchDelegate(new TouchDelegate(region, mCheckBox) {
92                     @Override
93                     public boolean onTouchEvent(MotionEvent event) {
94                         switch (event.getAction()) {
95                             case MotionEvent.ACTION_DOWN:
96                                 setPressed(true);
97                                 break;
98                             case MotionEvent.ACTION_UP:
99                             case MotionEvent.ACTION_CANCEL:
100                                 setPressed(false);
101                                 break;
102                         }
103                         return super.onTouchEvent(event);
104                     }
105                 });
106             }
107         });
108     }
109 
110     @Override
onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)111     protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
112         // The grid view auto-fit the columns, so we want to let the height match the width
113         // to make the image square.
114         super.onMeasure(widthMeasureSpec, widthMeasureSpec);
115     }
116 
bind(final Cursor cursor, final HostInterface hostInterface)117     public void bind(final Cursor cursor, final HostInterface hostInterface) {
118         final int desiredSize = getResources()
119                 .getDimensionPixelSize(R.dimen.gallery_image_cell_size);
120         mData.bind(cursor, desiredSize, desiredSize);
121         mHostInterface = hostInterface;
122         updateViewState();
123     }
124 
updateViewState()125     private void updateViewState() {
126         updateImageView();
127         if (mHostInterface.isMultiSelectEnabled() && !mData.isDocumentPickerItem()) {
128             mCheckBox.setVisibility(VISIBLE);
129             mCheckBox.setClickable(true);
130             mCheckBox.setChecked(mHostInterface.isItemSelected(mData));
131         } else {
132             mCheckBox.setVisibility(GONE);
133             mCheckBox.setClickable(false);
134         }
135     }
136 
updateImageView()137     private void updateImageView() {
138         if (mData.isDocumentPickerItem()) {
139             mImageView.setScaleType(ScaleType.CENTER);
140             setBackgroundColor(ConversationDrawables.get().getConversationThemeColor());
141             mImageView.setImageResourceId(null);
142             mImageView.setImageResource(R.drawable.ic_photo_library_light);
143             mImageView.setContentDescription(getResources().getString(
144                     R.string.pick_image_from_document_library_content_description));
145         } else {
146             mImageView.setScaleType(ScaleType.CENTER_CROP);
147             setBackgroundColor(getResources().getColor(R.color.gallery_image_default_background));
148             mImageView.setImageResourceId(mData.getImageRequestDescriptor());
149             final long dateSeconds = mData.getDateSeconds();
150             final boolean isValidDate = (dateSeconds > 0);
151             final int templateId = isValidDate ?
152                     R.string.mediapicker_gallery_image_item_description :
153                     R.string.mediapicker_gallery_image_item_description_no_date;
154             String contentDescription = String.format(getResources().getString(templateId),
155                     dateSeconds * TimeUnit.SECONDS.toMillis(1));
156             mImageView.setContentDescription(contentDescription);
157         }
158     }
159 }
160