/* * Copyright (C) 2015 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 android.support.v17.leanback.widget; import android.animation.Animator; import android.animation.AnimatorInflater; import android.content.Context; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; import android.support.v17.leanback.R; import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.List; /** * GuidanceStylist is used within a {@link android.support.v17.leanback.app.GuidedStepFragment} * to display contextual information for the decision(s) required at that step. *
* Many aspects of the base GuidanceStylist can be customized through theming; see the theme * attributes below. Note that these attributes are not set on individual elements in layout * XML, but instead would be set in a custom theme. See * Styles and Themes * for more information. *
* If these hooks are insufficient, this class may also be subclassed. Subclasses * may wish to override the {@link #onProvideLayoutId} method to change the layout file used to * display the guidance; more complex layouts may be supported by also providing a subclass of * {@link GuidanceStylist.Guidance} with extra fields. *
* Note: If an alternate layout is provided, the following view IDs should be used to refer to base * elements: *
* View IDs are allowed to be missing, in which case the corresponding views will be null. * * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeAppearingAnimation * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepImeDisappearingAnimation * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidanceContainerStyle * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidanceTitleStyle * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidanceDescriptionStyle * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidanceBreadcrumbStyle * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidanceIconStyle * @see android.support.v17.leanback.app.GuidedStepFragment * @see GuidanceStylist.Guidance */ public class GuidanceStylist implements FragmentAnimationProvider { /** * A data class representing contextual information for a {@link * android.support.v17.leanback.app.GuidedStepFragment}. Guidance consists of a short title, * a longer description, a breadcrumb to help with global navigation (often indicating where * the back button will lead), and an optional icon. All this information is intended to * provide users with the appropriate context to make the decision(s) required by the current * step. *
* Clients may provide a subclass of this if they wish to remember auxiliary data for use in * a customized GuidanceStylist. */ public static class Guidance { private final String mTitle; private final String mDescription; private final String mBreadcrumb; private final Drawable mIconDrawable; /** * Constructs a Guidance object with the specified title, description, breadcrumb, and * icon drawable. * @param title The title for the current guided step. * @param description The description for the current guided step. * @param breadcrumb The breadcrumb for the current guided step. * @param icon The icon drawable representing the current guided step. */ public Guidance(String title, String description, String breadcrumb, Drawable icon) { mBreadcrumb = breadcrumb; mTitle = title; mDescription = description; mIconDrawable = icon; } /** * Returns the title specified when this Guidance was constructed. * @return The title for this Guidance. */ public String getTitle() { return mTitle; } /** * Returns the description specified when this Guidance was constructed. * @return The description for this Guidance. */ public String getDescription() { return mDescription; } /** * Returns the breadcrumb specified when this Guidance was constructed. * @return The breadcrumb for this Guidance. */ public String getBreadcrumb() { return mBreadcrumb; } /** * Returns the icon drawable specified when this Guidance was constructed. * @return The icon for this Guidance. */ public Drawable getIconDrawable() { return mIconDrawable; } } private TextView mTitleView; private TextView mDescriptionView; private TextView mBreadcrumbView; private ImageView mIconView; private View mGuidanceContainer; /** * Creates an appropriately configured view for the given Guidance, using the provided * inflater and container. *
* Note: Does not actually add the created view to the container; the caller should do
* this.
* @param inflater The layout inflater to be used when constructing the view.
* @param container The view group to be passed in the call to
* LayoutInflater.inflate
.
* @param guidance The guidance data for the view.
* @return The view to be added to the caller's view hierarchy.
*/
public View onCreateView(
final LayoutInflater inflater, ViewGroup container, Guidance guidance) {
View guidanceView = inflater.inflate(onProvideLayoutId(), container, false);
mTitleView = (TextView) guidanceView.findViewById(R.id.guidance_title);
mBreadcrumbView = (TextView) guidanceView.findViewById(R.id.guidance_breadcrumb);
mDescriptionView = (TextView) guidanceView.findViewById(R.id.guidance_description);
mIconView = (ImageView) guidanceView.findViewById(R.id.guidance_icon);
mGuidanceContainer = guidanceView.findViewById(R.id.guidance_container);
// We allow any of the cached subviews to be null, so that subclasses can choose not to
// display a particular piece of information.
if (mTitleView != null) {
mTitleView.setText(guidance.getTitle());
}
if (mBreadcrumbView != null) {
mBreadcrumbView.setText(guidance.getBreadcrumb());
}
if (mDescriptionView != null) {
mDescriptionView.setText(guidance.getDescription());
}
if (mIconView != null) {
if (guidance.getIconDrawable() != null) {
mIconView.setImageDrawable(guidance.getIconDrawable());
} else {
mIconView.setVisibility(View.GONE);
}
}
if (mGuidanceContainer != null) {
CharSequence contentDescription = mGuidanceContainer.getContentDescription();
if (TextUtils.isEmpty(contentDescription)) {
mGuidanceContainer.setContentDescription(new StringBuilder()
.append(guidance.getBreadcrumb()).append('\n')
.append(guidance.getTitle()).append('\n')
.append(guidance.getDescription())
.toString());
}
}
return guidanceView;
}
/**
* Called when destroy the View created by GuidanceStylist.
*/
public void onDestroyView() {
mBreadcrumbView = null;
mDescriptionView = null;
mIconView = null;
mTitleView = null;
}
/**
* Provides the resource ID of the layout defining the guidance view. Subclasses may override
* to provide their own customized layouts. The base implementation returns
* {@link android.support.v17.leanback.R.layout#lb_guidance}. If overridden, the substituted
* layout should contain matching IDs for any views that should be managed by the base class;
* this can be achieved by starting with a copy of the base layout file.
* @return The resource ID of the layout to be inflated to define the guidance view.
*/
public int onProvideLayoutId() {
return R.layout.lb_guidance;
}
/**
* Returns the view displaying the title of the guidance.
* @return The text view object for the title.
*/
public TextView getTitleView() {
return mTitleView;
}
/**
* Returns the view displaying the description of the guidance.
* @return The text view object for the description.
*/
public TextView getDescriptionView() {
return mDescriptionView;
}
/**
* Returns the view displaying the breadcrumb of the guidance.
* @return The text view object for the breadcrumb.
*/
public TextView getBreadcrumbView() {
return mBreadcrumbView;
}
/**
* Returns the view displaying the icon of the guidance.
* @return The image view object for the icon.
*/
public ImageView getIconView() {
return mIconView;
}
/**
* {@inheritDoc}
*/
@Override
public void onImeAppearing(@NonNull List