1816aa142023c75cf427401c21831193998bdf233Alan Viverette/* 2816aa142023c75cf427401c21831193998bdf233Alan Viverette * Copyright (C) 2015 The Android Open Source Project 3816aa142023c75cf427401c21831193998bdf233Alan Viverette * 4816aa142023c75cf427401c21831193998bdf233Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5816aa142023c75cf427401c21831193998bdf233Alan Viverette * you may not use this file except in compliance with the License. 6816aa142023c75cf427401c21831193998bdf233Alan Viverette * You may obtain a copy of the License at 7816aa142023c75cf427401c21831193998bdf233Alan Viverette * 8816aa142023c75cf427401c21831193998bdf233Alan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9816aa142023c75cf427401c21831193998bdf233Alan Viverette * 10816aa142023c75cf427401c21831193998bdf233Alan Viverette * Unless required by applicable law or agreed to in writing, software 11816aa142023c75cf427401c21831193998bdf233Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12816aa142023c75cf427401c21831193998bdf233Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816aa142023c75cf427401c21831193998bdf233Alan Viverette * See the License for the specific language governing permissions and 14816aa142023c75cf427401c21831193998bdf233Alan Viverette * limitations under the License. 15816aa142023c75cf427401c21831193998bdf233Alan Viverette */ 16816aa142023c75cf427401c21831193998bdf233Alan Viverette 17816aa142023c75cf427401c21831193998bdf233Alan Viverettepackage com.android.internal.widget; 18816aa142023c75cf427401c21831193998bdf233Alan Viverette 19816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.content.Context; 20816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.graphics.drawable.Drawable; 21816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.util.AttributeSet; 22816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.view.View; 23816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport android.widget.ViewAnimator; 24816aa142023c75cf427401c21831193998bdf233Alan Viverette 25816aa142023c75cf427401c21831193998bdf233Alan Viveretteimport java.util.ArrayList; 26816aa142023c75cf427401c21831193998bdf233Alan Viverette 27816aa142023c75cf427401c21831193998bdf233Alan Viverette/** 28816aa142023c75cf427401c21831193998bdf233Alan Viverette * ViewAnimator with a more reasonable handling of MATCH_PARENT. 29816aa142023c75cf427401c21831193998bdf233Alan Viverette */ 30816aa142023c75cf427401c21831193998bdf233Alan Viverettepublic class DialogViewAnimator extends ViewAnimator { 31816aa142023c75cf427401c21831193998bdf233Alan Viverette private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1); 32816aa142023c75cf427401c21831193998bdf233Alan Viverette 33816aa142023c75cf427401c21831193998bdf233Alan Viverette public DialogViewAnimator(Context context) { 34816aa142023c75cf427401c21831193998bdf233Alan Viverette super(context); 35816aa142023c75cf427401c21831193998bdf233Alan Viverette } 36816aa142023c75cf427401c21831193998bdf233Alan Viverette 37816aa142023c75cf427401c21831193998bdf233Alan Viverette public DialogViewAnimator(Context context, AttributeSet attrs) { 38816aa142023c75cf427401c21831193998bdf233Alan Viverette super(context, attrs); 39816aa142023c75cf427401c21831193998bdf233Alan Viverette } 40816aa142023c75cf427401c21831193998bdf233Alan Viverette 41816aa142023c75cf427401c21831193998bdf233Alan Viverette @Override 42816aa142023c75cf427401c21831193998bdf233Alan Viverette protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 43816aa142023c75cf427401c21831193998bdf233Alan Viverette final boolean measureMatchParentChildren = 44816aa142023c75cf427401c21831193998bdf233Alan Viverette MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY || 45816aa142023c75cf427401c21831193998bdf233Alan Viverette MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY; 46816aa142023c75cf427401c21831193998bdf233Alan Viverette 47816aa142023c75cf427401c21831193998bdf233Alan Viverette int maxHeight = 0; 48816aa142023c75cf427401c21831193998bdf233Alan Viverette int maxWidth = 0; 49816aa142023c75cf427401c21831193998bdf233Alan Viverette int childState = 0; 50816aa142023c75cf427401c21831193998bdf233Alan Viverette 51816aa142023c75cf427401c21831193998bdf233Alan Viverette // First measure all children and record maximum dimensions where the 52816aa142023c75cf427401c21831193998bdf233Alan Viverette // spec isn't MATCH_PARENT. 53816aa142023c75cf427401c21831193998bdf233Alan Viverette final int count = getChildCount(); 54816aa142023c75cf427401c21831193998bdf233Alan Viverette for (int i = 0; i < count; i++) { 55816aa142023c75cf427401c21831193998bdf233Alan Viverette final View child = getChildAt(i); 56816aa142023c75cf427401c21831193998bdf233Alan Viverette if (getMeasureAllChildren() || child.getVisibility() != GONE) { 57816aa142023c75cf427401c21831193998bdf233Alan Viverette final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 58816aa142023c75cf427401c21831193998bdf233Alan Viverette final boolean matchWidth = lp.width == LayoutParams.MATCH_PARENT; 59816aa142023c75cf427401c21831193998bdf233Alan Viverette final boolean matchHeight = lp.height == LayoutParams.MATCH_PARENT; 60816aa142023c75cf427401c21831193998bdf233Alan Viverette if (measureMatchParentChildren && (matchWidth || matchHeight)) { 61816aa142023c75cf427401c21831193998bdf233Alan Viverette mMatchParentChildren.add(child); 62816aa142023c75cf427401c21831193998bdf233Alan Viverette } 63816aa142023c75cf427401c21831193998bdf233Alan Viverette 64816aa142023c75cf427401c21831193998bdf233Alan Viverette measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); 65816aa142023c75cf427401c21831193998bdf233Alan Viverette 66816aa142023c75cf427401c21831193998bdf233Alan Viverette // Measured dimensions only count against the maximum 67816aa142023c75cf427401c21831193998bdf233Alan Viverette // dimensions if they're not MATCH_PARENT. 68816aa142023c75cf427401c21831193998bdf233Alan Viverette int state = 0; 69816aa142023c75cf427401c21831193998bdf233Alan Viverette 70816aa142023c75cf427401c21831193998bdf233Alan Viverette if (measureMatchParentChildren && !matchWidth) { 71816aa142023c75cf427401c21831193998bdf233Alan Viverette maxWidth = Math.max(maxWidth, child.getMeasuredWidth() 72816aa142023c75cf427401c21831193998bdf233Alan Viverette + lp.leftMargin + lp.rightMargin); 73816aa142023c75cf427401c21831193998bdf233Alan Viverette state |= child.getMeasuredWidthAndState() & MEASURED_STATE_MASK; 74816aa142023c75cf427401c21831193998bdf233Alan Viverette } 75816aa142023c75cf427401c21831193998bdf233Alan Viverette 76816aa142023c75cf427401c21831193998bdf233Alan Viverette if (measureMatchParentChildren && !matchHeight) { 77816aa142023c75cf427401c21831193998bdf233Alan Viverette maxHeight = Math.max(maxHeight, child.getMeasuredHeight() 78816aa142023c75cf427401c21831193998bdf233Alan Viverette + lp.topMargin + lp.bottomMargin); 79816aa142023c75cf427401c21831193998bdf233Alan Viverette state |= (child.getMeasuredHeightAndState() >> MEASURED_HEIGHT_STATE_SHIFT) 80816aa142023c75cf427401c21831193998bdf233Alan Viverette & (MEASURED_STATE_MASK >> MEASURED_HEIGHT_STATE_SHIFT); 81816aa142023c75cf427401c21831193998bdf233Alan Viverette } 82816aa142023c75cf427401c21831193998bdf233Alan Viverette 83816aa142023c75cf427401c21831193998bdf233Alan Viverette childState = combineMeasuredStates(childState, state); 84816aa142023c75cf427401c21831193998bdf233Alan Viverette } 85816aa142023c75cf427401c21831193998bdf233Alan Viverette } 86816aa142023c75cf427401c21831193998bdf233Alan Viverette 87816aa142023c75cf427401c21831193998bdf233Alan Viverette // Account for padding too. 88816aa142023c75cf427401c21831193998bdf233Alan Viverette maxWidth += getPaddingLeft() + getPaddingRight(); 89816aa142023c75cf427401c21831193998bdf233Alan Viverette maxHeight += getPaddingTop() + getPaddingBottom(); 90816aa142023c75cf427401c21831193998bdf233Alan Viverette 91816aa142023c75cf427401c21831193998bdf233Alan Viverette // Check against our minimum height and width. 92816aa142023c75cf427401c21831193998bdf233Alan Viverette maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); 93816aa142023c75cf427401c21831193998bdf233Alan Viverette maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); 94816aa142023c75cf427401c21831193998bdf233Alan Viverette 95816aa142023c75cf427401c21831193998bdf233Alan Viverette // Check against our foreground's minimum height and width. 96816aa142023c75cf427401c21831193998bdf233Alan Viverette final Drawable drawable = getForeground(); 97816aa142023c75cf427401c21831193998bdf233Alan Viverette if (drawable != null) { 98816aa142023c75cf427401c21831193998bdf233Alan Viverette maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); 99816aa142023c75cf427401c21831193998bdf233Alan Viverette maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); 100816aa142023c75cf427401c21831193998bdf233Alan Viverette } 101816aa142023c75cf427401c21831193998bdf233Alan Viverette 102816aa142023c75cf427401c21831193998bdf233Alan Viverette setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), 103816aa142023c75cf427401c21831193998bdf233Alan Viverette resolveSizeAndState(maxHeight, heightMeasureSpec, 104816aa142023c75cf427401c21831193998bdf233Alan Viverette childState << MEASURED_HEIGHT_STATE_SHIFT)); 105816aa142023c75cf427401c21831193998bdf233Alan Viverette 106816aa142023c75cf427401c21831193998bdf233Alan Viverette // Measure remaining MATCH_PARENT children again using real dimensions. 107816aa142023c75cf427401c21831193998bdf233Alan Viverette final int matchCount = mMatchParentChildren.size(); 108816aa142023c75cf427401c21831193998bdf233Alan Viverette for (int i = 0; i < matchCount; i++) { 109816aa142023c75cf427401c21831193998bdf233Alan Viverette final View child = mMatchParentChildren.get(i); 110816aa142023c75cf427401c21831193998bdf233Alan Viverette final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 111816aa142023c75cf427401c21831193998bdf233Alan Viverette 112816aa142023c75cf427401c21831193998bdf233Alan Viverette final int childWidthMeasureSpec; 113816aa142023c75cf427401c21831193998bdf233Alan Viverette if (lp.width == LayoutParams.MATCH_PARENT) { 114816aa142023c75cf427401c21831193998bdf233Alan Viverette childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( 115816aa142023c75cf427401c21831193998bdf233Alan Viverette getMeasuredWidth() - getPaddingLeft() - getPaddingRight() 116816aa142023c75cf427401c21831193998bdf233Alan Viverette - lp.leftMargin - lp.rightMargin, 117816aa142023c75cf427401c21831193998bdf233Alan Viverette MeasureSpec.EXACTLY); 118816aa142023c75cf427401c21831193998bdf233Alan Viverette } else { 119816aa142023c75cf427401c21831193998bdf233Alan Viverette childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, 120816aa142023c75cf427401c21831193998bdf233Alan Viverette getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, 121816aa142023c75cf427401c21831193998bdf233Alan Viverette lp.width); 122816aa142023c75cf427401c21831193998bdf233Alan Viverette } 123816aa142023c75cf427401c21831193998bdf233Alan Viverette 124816aa142023c75cf427401c21831193998bdf233Alan Viverette final int childHeightMeasureSpec; 125816aa142023c75cf427401c21831193998bdf233Alan Viverette if (lp.height == LayoutParams.MATCH_PARENT) { 126816aa142023c75cf427401c21831193998bdf233Alan Viverette childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( 127816aa142023c75cf427401c21831193998bdf233Alan Viverette getMeasuredHeight() - getPaddingTop() - getPaddingBottom() 128816aa142023c75cf427401c21831193998bdf233Alan Viverette - lp.topMargin - lp.bottomMargin, 129816aa142023c75cf427401c21831193998bdf233Alan Viverette MeasureSpec.EXACTLY); 130816aa142023c75cf427401c21831193998bdf233Alan Viverette } else { 131816aa142023c75cf427401c21831193998bdf233Alan Viverette childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, 132816aa142023c75cf427401c21831193998bdf233Alan Viverette getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, 133816aa142023c75cf427401c21831193998bdf233Alan Viverette lp.height); 134816aa142023c75cf427401c21831193998bdf233Alan Viverette } 135816aa142023c75cf427401c21831193998bdf233Alan Viverette 136816aa142023c75cf427401c21831193998bdf233Alan Viverette child.measure(childWidthMeasureSpec, childHeightMeasureSpec); 137816aa142023c75cf427401c21831193998bdf233Alan Viverette } 138816aa142023c75cf427401c21831193998bdf233Alan Viverette 139816aa142023c75cf427401c21831193998bdf233Alan Viverette mMatchParentChildren.clear(); 140816aa142023c75cf427401c21831193998bdf233Alan Viverette } 141816aa142023c75cf427401c21831193998bdf233Alan Viverette} 142