• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.settings.widget;
16 
17 import android.content.Context;
18 import android.content.res.TypedArray;
19 import android.support.annotation.VisibleForTesting;
20 import android.util.AttributeSet;
21 import android.widget.FrameLayout;
22 
23 import com.android.settings.R;
24 
25 /**
26  * A {@link FrameLayout} with customizable aspect ratio.
27  * This is used to avoid dynamically calculating the height for the frame. Default aspect
28  * ratio will be 1 if none is set in layout attribute.
29  */
30 public final class AspectRatioFrameLayout extends FrameLayout {
31 
32     private static final float ASPECT_RATIO_CHANGE_THREASHOLD = 0.01f;
33 
34     @VisibleForTesting
35     float mAspectRatio = 1.0f;
36 
AspectRatioFrameLayout(Context context)37     public AspectRatioFrameLayout(Context context) {
38         this(context, null);
39     }
40 
AspectRatioFrameLayout(Context context, AttributeSet attrs)41     public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
42         this(context, attrs, 0);
43     }
44 
AspectRatioFrameLayout(Context context, AttributeSet attrs, int defStyle)45     public AspectRatioFrameLayout(Context context, AttributeSet attrs, int defStyle) {
46         super(context, attrs, defStyle);
47         if (attrs != null) {
48             TypedArray array =
49                     context.obtainStyledAttributes(attrs, R.styleable.AspectRatioFrameLayout);
50             mAspectRatio = array.getFloat(
51                     R.styleable.AspectRatioFrameLayout_aspectRatio, 1.0f);
52             array.recycle();
53         }
54     }
55 
setAspectRatio(float aspectRadio)56     public void setAspectRatio(float aspectRadio) {
57         mAspectRatio = aspectRadio;
58     }
59 
60     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)61     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
62         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
63         int width = getMeasuredWidth();
64         int height = getMeasuredHeight();
65         if (width == 0 || height == 0) {
66             return;
67         }
68         final float viewAspectRatio = (float) width / height;
69         final float aspectRatioDiff = mAspectRatio - viewAspectRatio;
70         if (Math.abs(aspectRatioDiff) <= ASPECT_RATIO_CHANGE_THREASHOLD) {
71             // Close enough, skip.
72             return;
73         }
74 
75         width = (int) (height * mAspectRatio);
76 
77         super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
78                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
79     }
80 
81 }
82