Home | History | Annotate | Download | only in mediapicker
      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 {
     47         void onItemClicked(View view, GalleryGridItemData data, boolean longClick);
     48         boolean isItemSelected(GalleryGridItemData data);
     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 
     64     public GalleryGridItemView(final Context context, final AttributeSet attrs) {
     65         super(context, attrs);
     66         mData = DataModel.get().createGalleryGridItemData();
     67     }
     68 
     69     @Override
     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
    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 
    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 
    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 
    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