1 /* 2 * Copyright (C) 2019 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.car.apps.common; 17 18 import android.content.Context; 19 import android.content.res.TypedArray; 20 import android.graphics.Bitmap; 21 import android.graphics.drawable.BitmapDrawable; 22 import android.graphics.drawable.Drawable; 23 import android.util.AttributeSet; 24 import android.util.Size; 25 import android.view.View; 26 27 import androidx.annotation.Nullable; 28 import androidx.constraintlayout.widget.ConstraintLayout; 29 30 /** 31 * A View to place a large, blurred image in the background. 32 * Intended for Car's Dialer and Media apps. 33 */ 34 public class BackgroundImageView extends ConstraintLayout { 35 36 private CrossfadeImageView mImageView; 37 38 /** Configuration (controlled from resources) */ 39 private Size mBitmapTargetSize; 40 private float mBitmapBlurPercent; 41 42 private View mDarkeningScrim; 43 BackgroundImageView(Context context)44 public BackgroundImageView(Context context) { 45 this(context, null); 46 } 47 BackgroundImageView(Context context, AttributeSet attrs)48 public BackgroundImageView(Context context, AttributeSet attrs) { 49 this(context, attrs, R.attr.backgroundImageViewStyle); 50 } 51 BackgroundImageView(Context context, AttributeSet attrs, int defStyle)52 public BackgroundImageView(Context context, AttributeSet attrs, int defStyle) { 53 super(context, attrs, defStyle); 54 55 float extraScale; 56 int resId; 57 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, 58 R.styleable.BackgroundImageView, defStyle, 0); 59 try { 60 extraScale = a.getFloat(R.styleable.BackgroundImageView_imageAdditionalScale, 1.05f); 61 resId = a.getResourceId(R.styleable.BackgroundImageView_contentLayout, 62 R.layout.background_image); 63 mBitmapBlurPercent = a.getFloat(R.styleable.BackgroundImageView_bitmap_blur_percent, 64 getResources().getFloat(R.dimen.background_bitmap_blur_percent)); 65 66 int size = a.getInteger(R.styleable.BackgroundImageView_bitmap_target_size_px, 67 getResources().getInteger(R.integer.background_bitmap_target_size_px)); 68 mBitmapTargetSize = new Size(size, size); 69 } finally { 70 a.recycle(); 71 } 72 73 inflate(getContext(), resId, this); 74 75 mImageView = findViewById(R.id.background_image_image); 76 mDarkeningScrim = findViewById(R.id.background_image_darkening_scrim); 77 78 setImageAdditionalScale(extraScale); 79 } 80 81 /** 82 * @deprecated Use {@link #setBackgroundDrawable} instead, and make sure to only call when the 83 * image is actually different! TODO(b/139387273). 84 * Sets the image to display to a bitmap 85 * @param bitmap The image to show. It will be scaled to the correct size and blurred. 86 * @param showAnimation Whether or not to cross fade to the new image 87 */ 88 @Deprecated setBackgroundImage(@ullable Bitmap bitmap, boolean showAnimation)89 public void setBackgroundImage(@Nullable Bitmap bitmap, boolean showAnimation) { 90 Drawable drawable = (bitmap != null) ? new BitmapDrawable(bitmap) : null; 91 updateBlur(drawable, showAnimation); 92 } 93 94 /** Sets the drawable that will be displayed blurred by this view. */ setBackgroundDrawable(@ullable Drawable drawable)95 public void setBackgroundDrawable(@Nullable Drawable drawable) { 96 setBackgroundDrawable(drawable, true); 97 } 98 99 /** 100 * Sets the drawable that will be displayed blurred by this view specifying if animation is 101 * enabled. 102 */ setBackgroundDrawable(@ullable Drawable drawable, boolean showAnimation)103 public void setBackgroundDrawable(@Nullable Drawable drawable, boolean showAnimation) { 104 updateBlur(drawable, showAnimation); 105 } 106 updateBlur(@ullable Drawable drawable, boolean showAnimation)107 private void updateBlur(@Nullable Drawable drawable, boolean showAnimation) { 108 if (drawable == null) { 109 mImageView.setImageBitmap(null, false); 110 return; 111 } 112 113 Bitmap src = BitmapUtils.fromDrawable(drawable, mBitmapTargetSize); 114 Bitmap blurred = ImageUtils.blur(getContext(), src, mBitmapTargetSize, mBitmapBlurPercent); 115 mImageView.setImageBitmap(blurred, showAnimation); 116 invalidate(); 117 requestLayout(); 118 } 119 120 /** Sets the background to a color */ setBackgroundColor(int color)121 public void setBackgroundColor(int color) { 122 mImageView.setBackgroundColor(color); 123 } 124 125 /** Dims/undims the background image by 30% */ setDimmed(boolean dim)126 public void setDimmed(boolean dim) { 127 mDarkeningScrim.setVisibility(dim ? View.VISIBLE : View.GONE); 128 } 129 130 /** 131 * Sets a scale to be applied on top of the scaling that was used to fit the 132 * image to the frame of the view. 133 * 134 * See {@link 135 * com.android.car.apps.common.CropAlignedImageView#setImageAdditionalScale(float)} 136 * for more details. 137 */ setImageAdditionalScale(float scale)138 public void setImageAdditionalScale(float scale) { 139 mImageView.setImageAdditionalScale(scale); 140 } 141 } 142