1/* 2 * Copyright (C) 2017 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 17package com.android.setupwizardlib.template; 18 19import android.annotation.SuppressLint; 20import android.content.Context; 21import android.support.annotation.NonNull; 22import android.support.annotation.Nullable; 23import android.support.annotation.StringRes; 24import android.support.annotation.StyleRes; 25import android.view.ContextThemeWrapper; 26import android.view.LayoutInflater; 27import android.view.View; 28import android.view.ViewStub; 29import android.widget.Button; 30import android.widget.LinearLayout; 31import android.widget.LinearLayout.LayoutParams; 32 33import com.android.setupwizardlib.R; 34import com.android.setupwizardlib.TemplateLayout; 35 36/** 37 * A {@link Mixin} for managing buttons. By default, the button bar follows the GLIF design and 38 * expects that buttons on the start (left for LTR) are "secondary" borderless buttons, while 39 * buttons on the end (right for LTR) are "primary" accent-colored buttons. 40 */ 41public class ButtonFooterMixin implements Mixin { 42 43 private final Context mContext; 44 45 @Nullable 46 private final ViewStub mFooterStub; 47 48 private LinearLayout mButtonContainer; 49 50 /** 51 * Create a mixin for managing buttons on the footer. 52 * 53 * @param layout The {@link TemplateLayout} containing this mixin. 54 */ 55 public ButtonFooterMixin(TemplateLayout layout) { 56 mContext = layout.getContext(); 57 mFooterStub = (ViewStub) layout.findManagedViewById(R.id.suw_layout_footer); 58 } 59 60 /** 61 * Add a button with the given text and style. Common style for GLIF are 62 * {@code SuwGlifButton.Primary} and {@code SuwGlifButton.Secondary}. 63 * 64 * @param text The label for the button. 65 * @param theme Theme resource to be used for this button. Since this is applied as a theme, 66 * the resource will typically apply {@code android:buttonStyle} so it will be 67 * applied to the button as a style as well. 68 * 69 * @return The button that was created. 70 */ 71 public Button addButton(CharSequence text, @StyleRes int theme) { 72 Button button = createThemedButton(mContext, theme); 73 button.setText(text); 74 return addButton(button); 75 } 76 77 /** 78 * Add a button with the given text and style. Common style for GLIF are 79 * {@code SuwGlifButton.Primary} and {@code SuwGlifButton.Secondary}. 80 * 81 * @param text The label for the button. 82 * @param theme Theme resource to be used for this button. Since this is applied as a theme, 83 * the resource will typically apply {@code android:buttonStyle} so it will be 84 * applied to the button as a style as well. 85 * 86 * @return The button that was created. 87 */ 88 public Button addButton(@StringRes int text, @StyleRes int theme) { 89 Button button = createThemedButton(mContext, theme); 90 button.setText(text); 91 return addButton(button); 92 } 93 94 /** 95 * Add a button to the footer. 96 * 97 * @param button The button to be added to the footer. 98 * @return The button that was added. 99 */ 100 public Button addButton(Button button) { 101 final LinearLayout buttonContainer = ensureFooterInflated(); 102 buttonContainer.addView(button); 103 return button; 104 } 105 106 /** 107 * Add a space to the footer. Spaces will share the remaining space of footer, so for example, 108 * [Button] [space] [Button] [space] [Button] will give you 3 buttons, left, center, and right 109 * aligned. 110 * 111 * @return The view that was used as space. 112 */ 113 public View addSpace() { 114 final LinearLayout buttonContainer = ensureFooterInflated(); 115 View space = new View(buttonContainer.getContext()); 116 space.setLayoutParams(new LayoutParams(0, 0, 1.0f)); 117 space.setVisibility(View.INVISIBLE); 118 buttonContainer.addView(space); 119 return space; 120 } 121 122 /** 123 * Remove a previously added button. 124 * 125 * @param button The button to be removed. 126 */ 127 public void removeButton(Button button) { 128 if (mButtonContainer != null) { 129 mButtonContainer.removeView(button); 130 } 131 } 132 133 /** 134 * Remove a previously added space. 135 * 136 * @param space The space to be removed. 137 */ 138 public void removeSpace(View space) { 139 if (mButtonContainer != null) { 140 mButtonContainer.removeView(space); 141 } 142 } 143 144 /** 145 * Remove all views, including spaces, from the footer. Note that if the footer container is 146 * already inflated, this will not remove the container itself. 147 */ 148 public void removeAllViews() { 149 if (mButtonContainer != null) { 150 mButtonContainer.removeAllViews(); 151 } 152 } 153 154 @NonNull 155 private LinearLayout ensureFooterInflated() { 156 if (mButtonContainer == null) { 157 if (mFooterStub == null) { 158 throw new IllegalStateException("Footer stub is not found in this template"); 159 } 160 mFooterStub.setLayoutResource(R.layout.suw_glif_footer_button_bar); 161 mButtonContainer = (LinearLayout) mFooterStub.inflate(); 162 } 163 return mButtonContainer; 164 } 165 166 @SuppressLint("InflateParams") 167 private Button createThemedButton(Context context, @StyleRes int theme) { 168 // Inflate a single button from XML, which when using support lib, will take advantage of 169 // the injected layout inflater and give us AppCompatButton instead. 170 LayoutInflater inflater = LayoutInflater.from(new ContextThemeWrapper(context, theme)); 171 return (Button) inflater.inflate(R.layout.suw_button, null, false); 172 } 173} 174