1 /* 2 * Copyright (C) 2011 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 17 package com.android.launcher3.widget; 18 19 import android.content.Context; 20 import android.graphics.Canvas; 21 import android.graphics.Rect; 22 import android.graphics.RectF; 23 import android.graphics.drawable.Drawable; 24 import android.util.AttributeSet; 25 import android.view.View; 26 27 /** 28 * View that draws a bitmap horizontally centered. If the image width is greater than the view 29 * width, the image is scaled down appropriately. 30 */ 31 public class WidgetImageView extends View { 32 33 private final RectF mDstRectF = new RectF(); 34 private Drawable mDrawable; 35 WidgetImageView(Context context)36 public WidgetImageView(Context context) { 37 this(context, null); 38 } 39 WidgetImageView(Context context, AttributeSet attrs)40 public WidgetImageView(Context context, AttributeSet attrs) { 41 this(context, attrs, 0); 42 } 43 WidgetImageView(Context context, AttributeSet attrs, int defStyle)44 public WidgetImageView(Context context, AttributeSet attrs, int defStyle) { 45 super(context, attrs, defStyle); 46 } 47 48 /** Set the drawable to use for this view. */ setDrawable(Drawable drawable)49 public void setDrawable(Drawable drawable) { 50 mDrawable = drawable; 51 invalidate(); 52 } 53 getDrawable()54 public Drawable getDrawable() { 55 return mDrawable; 56 } 57 58 @Override onDraw(Canvas canvas)59 protected void onDraw(Canvas canvas) { 60 if (mDrawable != null) { 61 updateDstRectF(); 62 mDrawable.setBounds(getBitmapBounds()); 63 mDrawable.draw(canvas); 64 } 65 } 66 67 /** 68 * Prevents the inefficient alpha view rendering. 69 */ 70 @Override hasOverlappingRendering()71 public boolean hasOverlappingRendering() { 72 return false; 73 } 74 updateDstRectF()75 private void updateDstRectF() { 76 float myWidth = getWidth(); 77 float myHeight = getHeight(); 78 final float bitmapWidth = mDrawable.getIntrinsicWidth(); 79 final float bitmapHeight = mDrawable.getIntrinsicHeight(); 80 final float bitmapAspectRatio = bitmapWidth / bitmapHeight; 81 final float containerAspectRatio = myWidth / myHeight; 82 83 // Scale by width if image has larger aspect ratio than the container else by height; and 84 // avoid cropping the previews 85 final float scale = bitmapAspectRatio > containerAspectRatio ? myWidth / bitmapWidth 86 : myHeight / bitmapHeight; 87 88 final float scaledWidth = bitmapWidth * scale; 89 final float scaledHeight = bitmapHeight * scale; 90 91 // Avoid cropping by checking bounds after scaling. 92 if (scaledWidth > myWidth) { 93 mDstRectF.left = 0; 94 mDstRectF.right = scaledWidth; 95 } else { 96 mDstRectF.left = (myWidth - scaledWidth) / 2; 97 mDstRectF.right = (myWidth + scaledWidth) / 2; 98 } 99 if (scaledHeight > myHeight) { 100 mDstRectF.top = 0; 101 mDstRectF.bottom = scaledHeight; 102 } else { 103 mDstRectF.top = (myHeight - scaledHeight) / 2; 104 mDstRectF.bottom = (myHeight + scaledHeight) / 2; 105 } 106 } 107 108 /** 109 * @return the bounds where the image was drawn. 110 */ getBitmapBounds()111 public Rect getBitmapBounds() { 112 updateDstRectF(); 113 Rect rect = new Rect(); 114 mDstRectF.round(rect); 115 return rect; 116 } 117 } 118