15e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam/* 25e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * Copyright (C) 2017 The Android Open Source Project 35e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * 45e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 55e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * you may not use this file except in compliance with the License. 65e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * You may obtain a copy of the License at 75e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * 85e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * http://www.apache.org/licenses/LICENSE-2.0 95e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * 105e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * Unless required by applicable law or agreed to in writing, software 115e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 125e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * See the License for the specific language governing permissions and 145e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * limitations under the License. 155e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam */ 165e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 175e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lampackage com.android.setupwizardlib.view; 185e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 195e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lamimport android.content.Context; 205e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lamimport android.util.AttributeSet; 215e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lamimport android.view.View; 225e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lamimport android.widget.LinearLayout; 235e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 245e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lamimport com.android.setupwizardlib.R; 255e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 265e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam/** 275e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * An extension of LinearLayout that automatically switches to vertical orientation when it can't 285e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * fit its child views horizontally. 295e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * 305e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam * Modified from {@code com.android.internal.widget.ButtonBarLayout} 315e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam */ 325e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lampublic class ButtonBarLayout extends LinearLayout { 335e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 345e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam private boolean mStacked = false; 355e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam private int mOriginalPaddingLeft; 365e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam private int mOriginalPaddingRight; 375e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 385e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam public ButtonBarLayout(Context context) { 395e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam super(context); 405e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 415e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 425e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam public ButtonBarLayout(Context context, AttributeSet attrs) { 435e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam super(context, attrs); 445e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 455e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 465e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam @Override 475e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 485e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 495e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 505e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam setStacked(false); 515e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 525e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam boolean needsRemeasure = false; 535e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 545e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam int initialWidthMeasureSpec = widthMeasureSpec; 555e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { 565e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // Measure with WRAP_CONTENT, so that we can compare the measured size with the 575e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // available size to see if we need to stack. 585e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 595e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 605e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // We'll need to remeasure again to fill excess space. 615e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam needsRemeasure = true; 625e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 635e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 645e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec); 655e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 665e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (getMeasuredWidth() > widthSize) { 675e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam setStacked(true); 685e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 695e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // Measure again in the new orientation. 705e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam needsRemeasure = true; 715e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 725e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 735e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (needsRemeasure) { 745e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam super.onMeasure(widthMeasureSpec, heightMeasureSpec); 755e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 765e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 775e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 785e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam private void setStacked(boolean stacked) { 795e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (mStacked == stacked) { 805e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam return; 815e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 825e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam mStacked = stacked; 835e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam int childCount = getChildCount(); 845e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam for (int i = 0; i < childCount; i++) { 855e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam View child = getChildAt(i); 865e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam LayoutParams childParams = (LayoutParams) child.getLayoutParams(); 875e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (stacked) { 885e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam child.setTag(R.id.suw_original_weight, childParams.weight); 895e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam childParams.weight = 0; 905e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } else { 915e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam Float weight = (Float) child.getTag(R.id.suw_original_weight); 925e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (weight != null) { 935e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam childParams.weight = weight; 945e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 955e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 965e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam child.setLayoutParams(childParams); 975e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 985e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 995e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); 1005e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 1015e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // Reverse the child order, so that the primary button is towards the top when vertical 1025e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam for (int i = childCount - 1; i >= 0; i--) { 1035e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam bringChildToFront(getChildAt(i)); 1045e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 1055e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam 1065e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam if (stacked) { 1075e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // HACK: In the default button bar style, the left and right paddings are not 1085e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // balanced to compensate for different alignment for borderless (left) button and 1095e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // the raised (right) button. When it's stacked, we want the buttons to be centered, 1105e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam // so we balance out the paddings here. 1115e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam mOriginalPaddingLeft = getPaddingLeft(); 1125e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam mOriginalPaddingRight = getPaddingRight(); 1135e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam int paddingHorizontal = Math.max(mOriginalPaddingLeft, mOriginalPaddingRight); 1145e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam setPadding( 1155e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam paddingHorizontal, getPaddingTop(), paddingHorizontal, getPaddingBottom()); 1165e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } else { 1175e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam setPadding( 1185e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam mOriginalPaddingLeft, 1195e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam getPaddingTop(), 1205e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam mOriginalPaddingRight, 1215e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam getPaddingBottom()); 1225e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 1235e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam } 1245e98278ebfad7aa858fbfcc4dd53db7442f9bc15Maurice Lam} 125