1 /*
2  * Copyright (C) 2017 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.wallpaper.widget;
17 
18 import android.content.Context;
19 import android.graphics.Matrix;
20 import android.util.AttributeSet;
21 import android.widget.ImageView;
22 
23 import androidx.annotation.Nullable;
24 
25 /**
26  * Custom ImageView that mimics the home launcher screen wallpaper position by aligning start and
27  * centering vertically its drawable. Scales down the image as much as possible without
28  * letterboxing.
29  */
30 public class WallpaperThumbnailView extends ImageView {
31 
WallpaperThumbnailView(Context context)32     public WallpaperThumbnailView(Context context) {
33         super(context);
34         setScaleType(ScaleType.MATRIX);
35     }
36 
WallpaperThumbnailView(Context context, @Nullable AttributeSet attrs)37     public WallpaperThumbnailView(Context context, @Nullable AttributeSet attrs) {
38         super(context, attrs);
39         setScaleType(ScaleType.MATRIX);
40     }
41 
42     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)43     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
44         super.onLayout(changed, left, top, right, bottom);
45         recomputeImageMatrix();
46     }
47 
recomputeImageMatrix()48     private void recomputeImageMatrix() {
49         // The drawable may be null on the first layout pass.
50         if (getDrawable() == null) {
51             return;
52         }
53 
54         final Matrix matrix = getImageMatrix();
55 
56         final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
57         final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
58         final int drawableWidth = getDrawable().getIntrinsicWidth();
59         final int drawableHeight = getDrawable().getIntrinsicHeight();
60 
61         float scale;
62         if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
63             scale = (float) viewHeight / drawableHeight;
64         } else {
65             scale = (float) viewWidth / drawableWidth;
66         }
67 
68         // Set scale such that the maximum area of the drawable is shown without letterboxing.
69         matrix.setScale(scale, scale);
70 
71         // Center the drawable vertically within the view.
72         if ((drawableHeight * scale) > viewHeight) {
73             float dy = -(((drawableHeight * scale) - viewHeight) / 2f);
74             matrix.postTranslate(0, dy);
75         }
76 
77         // If layout direction is RTL, then matrix should align the image towards the right.
78         if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
79             float dx = -((drawableWidth * scale) - viewWidth);
80             matrix.postTranslate(dx, 0);
81         }
82 
83         setImageMatrix(matrix);
84         invalidate();
85     }
86 }
87