1 /* 2 * Copyright (C) 2014 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.content.res.TypedArray; 21 import android.util.AttributeSet; 22 import android.view.View; 23 import android.view.ViewGroup; 24 25 /** 26 * A layout that places children in an evenly distributed grid based on the specified 27 * {@link android.R.attr#columnCount} and {@link android.R.attr#rowCount} attributes. 28 */ 29 public class CalculatorPadLayout extends ViewGroup { 30 31 private int mRowCount; 32 private int mColumnCount; 33 CalculatorPadLayout(Context context)34 public CalculatorPadLayout(Context context) { 35 this(context, null); 36 } 37 CalculatorPadLayout(Context context, AttributeSet attrs)38 public CalculatorPadLayout(Context context, AttributeSet attrs) { 39 this(context, attrs, 0); 40 } 41 CalculatorPadLayout(Context context, AttributeSet attrs, int defStyle)42 public CalculatorPadLayout(Context context, AttributeSet attrs, int defStyle) { 43 super(context, attrs, defStyle); 44 45 final TypedArray a = context.obtainStyledAttributes(attrs, 46 new int[] { android.R.attr.rowCount, android.R.attr.columnCount }, defStyle, 0); 47 mRowCount = a.getInt(0, 1); 48 mColumnCount = a.getInt(1, 1); 49 50 a.recycle(); 51 } 52 53 @Override shouldDelayChildPressedState()54 public boolean shouldDelayChildPressedState() { 55 return false; 56 } 57 58 @Override onLayout(boolean changed, int left, int top, int right, int bottom)59 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 60 final int paddingLeft = getPaddingLeft(); 61 final int paddingRight = getPaddingRight(); 62 final int paddingTop = getPaddingTop(); 63 final int paddingBottom = getPaddingBottom(); 64 65 final boolean isRTL = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 66 final int columnWidth = 67 Math.round((float) (right - left - paddingLeft - paddingRight)) / mColumnCount; 68 final int rowHeight = 69 Math.round((float) (bottom - top - paddingTop - paddingBottom)) / mRowCount; 70 71 int rowIndex = 0, columnIndex = 0; 72 for (int childIndex = 0; childIndex < getChildCount(); ++childIndex) { 73 final View childView = getChildAt(childIndex); 74 if (childView.getVisibility() == View.GONE) { 75 continue; 76 } 77 78 final MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams(); 79 80 final int childTop = paddingTop + lp.topMargin + rowIndex * rowHeight; 81 final int childBottom = childTop - lp.topMargin - lp.bottomMargin + rowHeight; 82 final int childLeft = paddingLeft + lp.leftMargin + 83 (isRTL ? (mColumnCount - 1) - columnIndex : columnIndex) * columnWidth; 84 final int childRight = childLeft - lp.leftMargin - lp.rightMargin + columnWidth; 85 86 final int childWidth = childRight - childLeft; 87 final int childHeight = childBottom - childTop; 88 if (childWidth != childView.getMeasuredWidth() || 89 childHeight != childView.getMeasuredHeight()) { 90 childView.measure( 91 MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY), 92 MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY)); 93 } 94 childView.layout(childLeft, childTop, childRight, childBottom); 95 96 rowIndex = (rowIndex + (columnIndex + 1) / mColumnCount) % mRowCount; 97 columnIndex = (columnIndex + 1) % mColumnCount; 98 } 99 } 100 101 @Override generateLayoutParams(AttributeSet attrs)102 public LayoutParams generateLayoutParams(AttributeSet attrs) { 103 return new MarginLayoutParams(getContext(), attrs); 104 } 105 106 @Override generateDefaultLayoutParams()107 protected LayoutParams generateDefaultLayoutParams() { 108 return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 109 } 110 111 @Override generateLayoutParams(ViewGroup.LayoutParams p)112 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 113 return new MarginLayoutParams(p); 114 } 115 116 @Override checkLayoutParams(ViewGroup.LayoutParams p)117 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 118 return p instanceof MarginLayoutParams; 119 } 120 } 121