1 /*
2  * Copyright (C) 2016 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.calculator2;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.HorizontalScrollView;
24 
25 import static android.view.View.MeasureSpec.UNSPECIFIED;
26 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
27 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
28 
29 public class CalculatorScrollView extends HorizontalScrollView {
30 
CalculatorScrollView(Context context)31     public CalculatorScrollView(Context context) {
32         this(context, null /* attrs */);
33     }
34 
CalculatorScrollView(Context context, AttributeSet attrs)35     public CalculatorScrollView(Context context, AttributeSet attrs) {
36         this(context, attrs, 0 /* defStyleAttr */);
37     }
38 
CalculatorScrollView(Context context, AttributeSet attrs, int defStyleAttr)39     public CalculatorScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
40         super(context, attrs, defStyleAttr);
41     }
42 
getChildMeasureSpecCompat(int spec, int padding, int childDimension)43     private static int getChildMeasureSpecCompat(int spec, int padding, int childDimension) {
44         if (MeasureSpec.getMode(spec) == UNSPECIFIED
45                 && (childDimension == MATCH_PARENT || childDimension == WRAP_CONTENT)) {
46             final int size = Math.max(0, MeasureSpec.getSize(spec) - padding);
47             return MeasureSpec.makeMeasureSpec(size, UNSPECIFIED);
48         }
49         return ViewGroup.getChildMeasureSpec(spec, padding, childDimension);
50     }
51 
52     @Override
measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec)53     protected void measureChild(View child, int parentWidthMeasureSpec,
54             int parentHeightMeasureSpec) {
55         // Allow child to be as wide as they want.
56         parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
57                 MeasureSpec.getSize(parentWidthMeasureSpec), UNSPECIFIED);
58 
59         final ViewGroup.LayoutParams lp = child.getLayoutParams();
60         final int childWidthMeasureSpec = getChildMeasureSpecCompat(parentWidthMeasureSpec,
61                 0 /* padding */, lp.width);
62         final int childHeightMeasureSpec = getChildMeasureSpecCompat(parentHeightMeasureSpec,
63                 getPaddingTop() + getPaddingBottom(), lp.height);
64 
65         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
66     }
67 
68     @Override
measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)69     protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
70             int parentHeightMeasureSpec, int heightUsed) {
71         // Allow child to be as wide as they want.
72         parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
73                 MeasureSpec.getSize(parentWidthMeasureSpec), UNSPECIFIED);
74 
75         final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
76         final int childWidthMeasureSpec = getChildMeasureSpecCompat(parentWidthMeasureSpec,
77                 lp.leftMargin + lp.rightMargin, lp.width);
78         final int childHeightMeasureSpec = getChildMeasureSpecCompat(parentHeightMeasureSpec,
79                 getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, lp.height);
80 
81         child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
82     }
83 }
84