SetupWizardLibrary/library/main/src/com/android/setupwizardlib/template/ButtonFooterMixin.java
Maurice Lam 8721e6e37a Implement ButtonFooterMixin
The ButtonFooterMixin allows creating GLIF-compatible sticky footer
with buttons. The mixin assumes that buttons on the start side
(left for LTR) are borderless buttons and buttons on the end side
(right for LTR) are accent colored raised buttons.

Bug: 35448201
Test: ./gradlew connectedAndroidTest test
Change-Id: I26fc1a19290308f8d39466652308366e9677afbd
2017-02-17 21:44:43 -08:00

175 lines
6.1 KiB
Java

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.setupwizardlib.template;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import com.android.setupwizardlib.R;
import com.android.setupwizardlib.TemplateLayout;
/**
* A {@link Mixin} for managing buttons. By default, the button bar follows the GLIF design and
* expects that buttons on the start (left for LTR) are "secondary" borderless buttons, while
* buttons on the end (right for LTR) are "primary" accent-colored buttons.
*/
public class ButtonFooterMixin implements Mixin {
private final Context mContext;
@Nullable
private final ViewStub mFooterStub;
private LinearLayout mButtonContainer;
/**
* Create a mixin for managing buttons on the footer.
*
* @param layout The {@link TemplateLayout} containing this mixin.
*/
public ButtonFooterMixin(TemplateLayout layout) {
mContext = layout.getContext();
mFooterStub = (ViewStub) layout.findManagedViewById(R.id.suw_layout_footer);
}
/**
* Add a button with the given text and style. Common style for GLIF are
* {@code SuwGlifButton.Primary} and {@code SuwGlifButton.Secondary}.
*
* @param text The label for the button.
* @param theme Theme resource to be used for this button. Since this is applied as a theme,
* the resource will typically apply {@code android:buttonStyle} so it will be
* applied to the button as a style as well.
*
* @return The button that was created.
*/
public Button addButton(CharSequence text, @StyleRes int theme) {
Button button = createThemedButton(mContext, theme);
button.setText(text);
return addButton(button);
}
/**
* Add a button with the given text and style. Common style for GLIF are
* {@code SuwGlifButton.Primary} and {@code SuwGlifButton.Secondary}.
*
* @param text The label for the button.
* @param theme Theme resource to be used for this button. Since this is applied as a theme,
* the resource will typically apply {@code android:buttonStyle} so it will be
* applied to the button as a style as well.
*
* @return The button that was created.
*/
public Button addButton(@StringRes int text, @StyleRes int theme) {
Button button = createThemedButton(mContext, theme);
button.setText(text);
return addButton(button);
}
/**
* Add a button to the footer.
*
* @param button The button to be added to the footer.
* @return The button that was added.
*/
public Button addButton(Button button) {
final LinearLayout buttonContainer = ensureFooterInflated();
buttonContainer.addView(button);
return button;
}
/**
* Add a space to the footer. Spaces will share the remaining space of footer, so for example,
* [Button] [space] [Button] [space] [Button] will give you 3 buttons, left, center, and right
* aligned.
*
* @return The view that was used as space.
*/
public View addSpace() {
final LinearLayout buttonContainer = ensureFooterInflated();
View space = new View(buttonContainer.getContext());
space.setLayoutParams(new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f));
space.setVisibility(View.INVISIBLE);
buttonContainer.addView(space);
return space;
}
/**
* Remove a previously added button.
*
* @param button The button to be removed.
*/
public void removeButton(Button button) {
if (mButtonContainer != null) {
mButtonContainer.removeView(button);
}
}
/**
* Remove a previously added space.
*
* @param space The space to be removed.
*/
public void removeSpace(View space) {
if (mButtonContainer != null) {
mButtonContainer.removeView(space);
}
}
/**
* Remove all views, including spaces, from the footer. Note that if the footer container is
* already inflated, this will not remove the container itself.
*/
public void removeAllViews() {
if (mButtonContainer != null) {
mButtonContainer.removeAllViews();
}
}
@NonNull
private LinearLayout ensureFooterInflated() {
if (mButtonContainer == null) {
if (mFooterStub == null) {
throw new IllegalStateException("Footer stub is not found in this template");
}
mFooterStub.setLayoutResource(R.layout.suw_glif_footer_button_bar);
mButtonContainer = (LinearLayout) mFooterStub.inflate();
}
return mButtonContainer;
}
@SuppressLint("InflateParams")
private Button createThemedButton(Context context, @StyleRes int theme) {
// Inflate a single button from XML, which when using support lib, will take advantage of
// the injected layout inflater and give us AppCompatButton instead.
LayoutInflater inflater = LayoutInflater.from(new ContextThemeWrapper(context, theme));
return (Button) inflater.inflate(R.layout.suw_button, null, false);
}
}