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