public class

GuidedAction

extends Action

 java.lang.Object

androidx.leanback.widget.Action

↳androidx.leanback.widget.GuidedAction

Subclasses:

GuidedDatePickerAction

Gradle dependencies

compile group: 'androidx.leanback', name: 'leanback', version: '1.2.0-alpha02'

  • groupId: androidx.leanback
  • artifactId: leanback
  • version: 1.2.0-alpha02

Artifact androidx.leanback:leanback:1.2.0-alpha02 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.leanback:leanback com.android.support:leanback-v17

Androidx class mapping:

androidx.leanback.widget.GuidedAction android.support.v17.leanback.widget.GuidedAction

Overview

A data class which represents an action within a GuidedStepFragment. GuidedActions contain at minimum a title and a description, and typically also an icon.

A GuidedAction typically represents a single action a user may take, but may also represent a possible choice out of a group of mutually exclusive choices (similar to radio buttons), or an information-only label (in which case the item cannot be clicked).

GuidedActions may optionally be checked. They may also indicate that they will request further user input on selection, in which case they will be displayed with a chevron indicator.

GuidedAction recommends to use GuidedAction.Builder. When application subclass GuidedAction, it can subclass GuidedAction.BuilderBase, implement its own builder() method where it should call GuidedAction.BuilderBase.applyValues(GuidedAction).

Summary

Fields
public static final longACTION_ID_CANCEL

Id of standard Cancel action.

public static final longACTION_ID_CONTINUE

Id of standard Finish action.

public static final longACTION_ID_CURRENT

When finishing editing, stay on current action.

public static final longACTION_ID_FINISH

Id of standard Finish action.

public static final longACTION_ID_NEXT

When finishing editing, goes to next action.

public static final longACTION_ID_NO

Id of standard No action.

public static final longACTION_ID_OK

Id of standard OK action.

public static final longACTION_ID_YES

Id of standard Yes action.

public static final intCHECKBOX_CHECK_SET_ID

Checkset Id for checkbox.

public static final intDEFAULT_CHECK_SET_ID

Default checkset Id for radio.

public static final intNO_CHECK_SET

Special check set Id that is neither checkbox nor radio.

from ActionNO_ID
Constructors
protectedGuidedAction()

Methods
public java.lang.StringgetAutofillHints()

Returns autofill hints, see android.view.View.

public intgetCheckSetId()

Returns the check set id this action is a part of.

public java.lang.CharSequencegetDescription()

Returns the description of this action.

public intgetDescriptionEditInputType()

Returns InputType of action description in editing; only valid when GuidedAction.isDescriptionEditable() is true.

public intgetDescriptionInputType()

Returns InputType of action description not in editing.

public java.lang.CharSequencegetEditDescription()

Returns the optional description text to edit.

public intgetEditInputType()

Returns InputType of action title in editing; only valid when GuidedAction.isEditable() is true.

public java.lang.CharSequencegetEditTitle()

Returns the optional title text to edit.

public intgetInputType()

Returns InputType of action title not in editing.

public IntentgetIntent()

Returns the intent associated with this action.

public java.util.List<GuidedAction>getSubActions()

public java.lang.CharSequencegetTitle()

Returns the title of this action.

public booleanhasEditableActivatorView()

Returns whether this action can be activated to edit, e.g.

public booleanhasMultilineDescription()

Returns whether this action is has a multiline description.

public booleanhasNext()

Returns whether this action will request further user input when selected, such as showing another GuidedStepFragment or launching a new activity.

public booleanhasSubActions()

public booleanhasTextEditable()

Returns if this action has editable title or editable description.

public booleaninfoOnly()

Returns whether the action will only display information and is thus not clickable.

public final booleanisAutoSaveRestoreEnabled()

Returns true if Action will be saved to instanceState and restored later, false otherwise.

public booleanisChecked()

Returns whether this action is checked.

public booleanisDescriptionEditable()

Returns whether this action description is editable.

public booleanisEditable()

Returns whether this action title is editable.

public booleanisEditTitleUsed()

Returns true if GuidedAction.getEditTitle() is not null.

public booleanisEnabled()

Returns whether this action is enabled.

public booleanisFocusable()

Returns whether this action is focusable.

public voidonRestoreInstanceState(Bundle bundle, java.lang.String key)

Restore action from a bundle using a given key.

public voidonSaveInstanceState(Bundle bundle, java.lang.String key)

Save action into a bundle using a given key.

public voidsetChecked(boolean checked)

Sets whether this action is checked.

public voidsetDescription(java.lang.CharSequence description)

Sets the description of this action.

public voidsetEditDescription(java.lang.CharSequence editDescription)

Sets the optional description text to edit instead of GuidedAction.setDescription(CharSequence).

public voidsetEditTitle(java.lang.CharSequence editTitle)

Sets the optional title text to edit instead of GuidedAction.setTitle(CharSequence).

public voidsetEnabled(boolean enabled)

Sets whether this action is enabled.

public voidsetFocusable(boolean focusable)

Sets whether this action is focusable.

public voidsetIntent(Intent intent)

Sets the intent of this action.

public voidsetSubActions(java.util.List<GuidedAction> actions)

Change sub actions list.

public voidsetTitle(java.lang.CharSequence title)

Sets the title of this action.

from ActionaddKeyCode, getIcon, getId, getLabel1, getLabel2, removeKeyCode, respondsToKeyCode, setIcon, setId, setLabel1, setLabel2, toString
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Fields

public static final int NO_CHECK_SET

Special check set Id that is neither checkbox nor radio.

public static final int DEFAULT_CHECK_SET_ID

Default checkset Id for radio.

public static final int CHECKBOX_CHECK_SET_ID

Checkset Id for checkbox.

public static final long ACTION_ID_NEXT

When finishing editing, goes to next action.

public static final long ACTION_ID_CURRENT

When finishing editing, stay on current action.

public static final long ACTION_ID_OK

Id of standard OK action.

public static final long ACTION_ID_CANCEL

Id of standard Cancel action.

public static final long ACTION_ID_FINISH

Id of standard Finish action.

public static final long ACTION_ID_CONTINUE

Id of standard Finish action.

public static final long ACTION_ID_YES

Id of standard Yes action.

public static final long ACTION_ID_NO

Id of standard No action.

Constructors

protected GuidedAction()

Methods

public java.lang.CharSequence getTitle()

Returns the title of this action.

Returns:

The title set when this action was built.

public void setTitle(java.lang.CharSequence title)

Sets the title of this action.

Parameters:

title: The title set when this action was built.

public java.lang.CharSequence getEditTitle()

Returns the optional title text to edit. When not null, it is being edited instead of GuidedAction.getTitle().

Returns:

Optional title text to edit instead of GuidedAction.getTitle().

public void setEditTitle(java.lang.CharSequence editTitle)

Sets the optional title text to edit instead of GuidedAction.setTitle(CharSequence).

Parameters:

editTitle: Optional title text to edit instead of GuidedAction.setTitle(CharSequence).

public java.lang.CharSequence getEditDescription()

Returns the optional description text to edit. When not null, it is being edited instead of GuidedAction.getDescription().

Returns:

Optional description text to edit instead of GuidedAction.getDescription().

public void setEditDescription(java.lang.CharSequence editDescription)

Sets the optional description text to edit instead of GuidedAction.setDescription(CharSequence).

Parameters:

editDescription: Optional description text to edit instead of GuidedAction.setDescription(CharSequence).

public boolean isEditTitleUsed()

Returns true if GuidedAction.getEditTitle() is not null. When true, the GuidedAction.getEditTitle() is being edited instead of GuidedAction.getTitle().

Returns:

true if GuidedAction.getEditTitle() is not null.

public java.lang.CharSequence getDescription()

Returns the description of this action.

Returns:

The description of this action.

public void setDescription(java.lang.CharSequence description)

Sets the description of this action.

Parameters:

description: The description of the action.

public Intent getIntent()

Returns the intent associated with this action.

Returns:

The intent set when this action was built.

public void setIntent(Intent intent)

Sets the intent of this action.

Parameters:

intent: New intent to set on this action.

public boolean isEditable()

Returns whether this action title is editable.

Returns:

true if the action title is editable, false otherwise.

public boolean isDescriptionEditable()

Returns whether this action description is editable.

Returns:

true if the action description is editable, false otherwise.

public boolean hasTextEditable()

Returns if this action has editable title or editable description.

Returns:

True if this action has editable title or editable description, false otherwise.

public boolean hasEditableActivatorView()

Returns whether this action can be activated to edit, e.g. a DatePicker.

Returns:

true if the action can be activated to edit.

public int getEditInputType()

Returns InputType of action title in editing; only valid when GuidedAction.isEditable() is true.

Returns:

InputType of action title in editing.

public int getDescriptionEditInputType()

Returns InputType of action description in editing; only valid when GuidedAction.isDescriptionEditable() is true.

Returns:

InputType of action description in editing.

public int getInputType()

Returns InputType of action title not in editing.

Returns:

InputType of action title not in editing.

public int getDescriptionInputType()

Returns InputType of action description not in editing.

Returns:

InputType of action description not in editing.

public boolean isChecked()

Returns whether this action is checked.

Returns:

true if the action is currently checked, false otherwise.

public void setChecked(boolean checked)

Sets whether this action is checked.

Parameters:

checked: Whether this action should be checked.

public int getCheckSetId()

Returns the check set id this action is a part of. All actions in the same list with the same check set id are considered linked. When one of the actions within that set is selected, that action becomes checked, while all the other actions become unchecked.

Returns:

an integer representing the check set this action is a part of, or GuidedAction.CHECKBOX_CHECK_SET_ID if this is a checkbox, or GuidedAction.NO_CHECK_SET if this action is not a checkbox or radiobutton.

public boolean hasMultilineDescription()

Returns whether this action is has a multiline description.

Returns:

true if the action was constructed as having a multiline description, false otherwise.

public boolean isEnabled()

Returns whether this action is enabled.

Returns:

true if the action is currently enabled, false otherwise.

public void setEnabled(boolean enabled)

Sets whether this action is enabled.

Parameters:

enabled: Whether this action should be enabled.

public boolean isFocusable()

Returns whether this action is focusable.

Returns:

true if the action is currently focusable, false otherwise.

public void setFocusable(boolean focusable)

Sets whether this action is focusable.

Parameters:

focusable: Whether this action should be focusable.

public java.lang.String getAutofillHints()

Returns autofill hints, see android.view.View.

public boolean hasNext()

Returns whether this action will request further user input when selected, such as showing another GuidedStepFragment or launching a new activity. Configured during construction.

Returns:

true if the action will request further user input when selected, false otherwise.

public boolean infoOnly()

Returns whether the action will only display information and is thus not clickable. If both this and GuidedAction.hasNext() are true, infoOnly takes precedence. The default is false. For example, this might represent e.g. the amount of storage a document uses, or the cost of an app.

Returns:

true if will only display information, false otherwise.

public void setSubActions(java.util.List<GuidedAction> actions)

Change sub actions list.

Parameters:

actions: Sub actions list to set on this action. Sets null to disable sub actions.

public java.util.List<GuidedAction> getSubActions()

Returns:

List of sub actions or null if sub actions list is not enabled.

public boolean hasSubActions()

Returns:

True if has sub actions list, even it's currently empty.

public final boolean isAutoSaveRestoreEnabled()

Returns true if Action will be saved to instanceState and restored later, false otherwise. The default value is true. When isAutoSaveRestoreEnabled() is true and Action.getId() is not Action.NO_ID:

App may explicitly disable auto restore and handle by itself. App should override Fragment onSaveInstanceState() and onCreateActions()

Returns:

True if Action will be saved to instanceState and restored later, false otherwise.

public void onSaveInstanceState(Bundle bundle, java.lang.String key)

Save action into a bundle using a given key. When isAutoRestoreEna() is true:

Subclass may override this method.

Parameters:

bundle: Bundle to save the Action.
key: Key used to save the Action.

public void onRestoreInstanceState(Bundle bundle, java.lang.String key)

Restore action from a bundle using a given key. When isAutoRestore() is true:

Subclass may override this method.

Parameters:

bundle: Bundle to restore the Action from.
key: Key used to restore the Action.

Source

/*
 * 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 androidx.leanback.widget;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.InputType;

import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.leanback.R;

import java.util.List;

/**
 * A data class which represents an action within a {@link
 * androidx.leanback.app.GuidedStepFragment}. GuidedActions contain at minimum a title
 * and a description, and typically also an icon.
 * <p>
 * A GuidedAction typically represents a single action a user may take, but may also represent a
 * possible choice out of a group of mutually exclusive choices (similar to radio buttons), or an
 * information-only label (in which case the item cannot be clicked).
 * <p>
 * GuidedActions may optionally be checked. They may also indicate that they will request further
 * user input on selection, in which case they will be displayed with a chevron indicator.
 * <p>
 * GuidedAction recommends to use {@link Builder}. When application subclass GuidedAction, it
 * can subclass {@link BuilderBase}, implement its own builder() method where it should
 * call {@link BuilderBase#applyValues(GuidedAction)}.
 */
public class GuidedAction extends Action {

    private static final String TAG = "GuidedAction";

    /**
     * Special check set Id that is neither checkbox nor radio.
     */
    public static final int NO_CHECK_SET = 0;
    /**
     * Default checkset Id for radio.
     */
    public static final int DEFAULT_CHECK_SET_ID = 1;
    /**
     * Checkset Id for checkbox.
     */
    public static final int CHECKBOX_CHECK_SET_ID = -1;

    /**
     * When finishing editing, goes to next action.
     */
    public static final long ACTION_ID_NEXT = -2;
    /**
     * When finishing editing, stay on current action.
     */
    public static final long ACTION_ID_CURRENT = -3;

    /**
     * Id of standard OK action.
     */
    public static final long ACTION_ID_OK = -4;

    /**
     * Id of standard Cancel action.
     */
    public static final long ACTION_ID_CANCEL = -5;

    /**
     * Id of standard Finish action.
     */
    public static final long ACTION_ID_FINISH = -6;

    /**
     * Id of standard Finish action.
     */
    public static final long ACTION_ID_CONTINUE = -7;

    /**
     * Id of standard Yes action.
     */
    public static final long ACTION_ID_YES = -8;

    /**
     * Id of standard No action.
     */
    public static final long ACTION_ID_NO = -9;

    static final int EDITING_NONE = 0;
    static final int EDITING_TITLE = 1;
    static final int EDITING_DESCRIPTION = 2;
    static final int EDITING_ACTIVATOR_VIEW = 3;

    /**
     * Base builder class to build a {@link GuidedAction} object.  When subclass GuidedAction, you
     * can override this BuilderBase class, implements your build() method which should call
     * {@link #applyValues(GuidedAction)}.  When using GuidedAction directly, use {@link Builder}.
     *
     * @param <B> the type of BuilderBase
     */
    @SuppressWarnings("unchecked")
    public abstract static class BuilderBase<B extends BuilderBase> {
        private Context mContext;
        private long mId;
        private CharSequence mTitle;
        private CharSequence mEditTitle;
        private CharSequence mDescription;
        private CharSequence mEditDescription;
        private String[] mAutofillHints;
        private Drawable mIcon;
        /**
         * The mActionFlags holds various action states such as whether title or description are
         * editable, or the action is focusable.
         *
         */
        private int mActionFlags;

        private int mEditable = EDITING_NONE;
        private int mInputType = InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
        private int mDescriptionInputType = InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
        private int mEditInputType = InputType.TYPE_CLASS_TEXT;
        private int mDescriptionEditInputType = InputType.TYPE_CLASS_TEXT;
        private int mCheckSetId = NO_CHECK_SET;
        private List<GuidedAction> mSubActions;
        private Intent mIntent;

        /**
         * Creates a BuilderBase for GuidedAction or its subclass.
         * @param context Context object used to build the GuidedAction.
         */
        public BuilderBase(Context context) {
            mContext = context;
            mActionFlags = PF_ENABLED | PF_FOCUSABLE | PF_AUTORESTORE;
        }

        /**
         * Returns Context of this Builder.
         * @return Context of this Builder.
         */
        public Context getContext() {
            return mContext;
        }

        private void setFlags(int flag, int mask) {
            mActionFlags = (mActionFlags & ~mask) | (flag & mask);
        }

        /**
         * Subclass of BuilderBase should call this function to apply values.
         * @param action GuidedAction to apply BuilderBase values.
         */
        protected final void applyValues(GuidedAction action) {
            // Base Action values
            action.setId(mId);
            action.setLabel1(mTitle);
            action.setEditTitle(mEditTitle);
            action.setLabel2(mDescription);
            action.setEditDescription(mEditDescription);
            action.setIcon(mIcon);

            // Subclass values
            action.mIntent = mIntent;
            action.mEditable = mEditable;
            action.mInputType = mInputType;
            action.mDescriptionInputType = mDescriptionInputType;
            action.mAutofillHints = mAutofillHints;
            action.mEditInputType = mEditInputType;
            action.mDescriptionEditInputType = mDescriptionEditInputType;
            action.mActionFlags = mActionFlags;
            action.mCheckSetId = mCheckSetId;
            action.mSubActions = mSubActions;
        }

        /**
         * Construct a clickable action with associated id and auto assign pre-defined title for the
         * action. If the id is not supported, the method simply does nothing.
         * @param id One of {@link GuidedAction#ACTION_ID_OK} {@link GuidedAction#ACTION_ID_CANCEL}
         * {@link GuidedAction#ACTION_ID_FINISH} {@link GuidedAction#ACTION_ID_CONTINUE}
         * {@link GuidedAction#ACTION_ID_YES} {@link GuidedAction#ACTION_ID_NO}.
         * @return The same BuilderBase object.
         */
        public B clickAction(long id) {
            if (id == ACTION_ID_OK) {
                mId = ACTION_ID_OK;
                mTitle = mContext.getString(android.R.string.ok);
            } else if (id == ACTION_ID_CANCEL) {
                mId = ACTION_ID_CANCEL;
                mTitle = mContext.getString(android.R.string.cancel);
            } else if (id == ACTION_ID_FINISH) {
                mId = ACTION_ID_FINISH;
                mTitle = mContext.getString(R.string.lb_guidedaction_finish_title);
            } else if (id == ACTION_ID_CONTINUE) {
                mId = ACTION_ID_CONTINUE;
                mTitle = mContext.getString(R.string.lb_guidedaction_continue_title);
            } else if (id == ACTION_ID_YES) {
                mId = ACTION_ID_YES;
                mTitle = mContext.getString(android.R.string.ok);
            } else if (id == ACTION_ID_NO) {
                mId = ACTION_ID_NO;
                mTitle = mContext.getString(android.R.string.cancel);
            }
            return (B) this;
        }

        /**
         * Sets the ID associated with this action.  The ID can be any value the client wishes;
         * it is typically used to determine what to do when an action is clicked.
         * @param id The ID to associate with this action.
         */
        public B id(long id) {
            mId = id;
            return (B) this;
        }

        /**
         * Sets the title for this action.  The title is typically a short string indicating the
         * action to be taken on click, e.g. "Continue" or "Cancel".
         * @param title The title for this action.
         */
        public B title(CharSequence title) {
            mTitle = title;
            return (B) this;
        }

        /**
         * Sets the title for this action.  The title is typically a short string indicating the
         * action to be taken on click, e.g. "Continue" or "Cancel".
         * @param titleResourceId The resource id of title for this action.
         */
        public B title(@StringRes int titleResourceId) {
            mTitle = getContext().getString(titleResourceId);
            return (B) this;
        }

        /**
         * Sets the optional title text to edit.  When TextView is activated, the edit title
         * replaces the string of title.
         * @param editTitle The optional title text to edit when TextView is activated.
         */
        public B editTitle(CharSequence editTitle) {
            mEditTitle = editTitle;
            return (B) this;
        }

        /**
         * Sets the optional title text to edit.  When TextView is activated, the edit title
         * replaces the string of title.
         * @param editTitleResourceId String resource id of the optional title text to edit when
         * TextView is activated.
         */
        public B editTitle(@StringRes int editTitleResourceId) {
            mEditTitle = getContext().getString(editTitleResourceId);
            return (B) this;
        }

        /**
         * Sets the description for this action.  The description is typically a longer string
         * providing extra information on what the action will do.
         * @param description The description for this action.
         */
        public B description(CharSequence description) {
            mDescription = description;
            return (B) this;
        }

        /**
         * Sets the description for this action.  The description is typically a longer string
         * providing extra information on what the action will do.
         * @param descriptionResourceId String resource id of the description for this action.
         */
        public B description(@StringRes int descriptionResourceId) {
            mDescription = getContext().getString(descriptionResourceId);
            return (B) this;
        }

        /**
         * Sets the optional description text to edit.  When TextView is activated, the edit
         * description replaces the string of description.
         * @param description The description to edit for this action.
         */
        public B editDescription(CharSequence description) {
            mEditDescription = description;
            return (B) this;
        }

        /**
         * Sets the optional description text to edit.  When TextView is activated, the edit
         * description replaces the string of description.
         * @param descriptionResourceId String resource id of the description to edit for this
         * action.
         */
        public B editDescription(@StringRes int descriptionResourceId) {
            mEditDescription = getContext().getString(descriptionResourceId);
            return (B) this;
        }

        /**
         * Sets the intent associated with this action.  Clients would typically fire this intent
         * directly when the action is clicked.
         * @param intent The intent associated with this action.
         */
        public B intent(Intent intent) {
            mIntent = intent;
            return (B) this;
        }

        /**
         * Sets the action's icon drawable.
         * @param icon The drawable for the icon associated with this action.
         */
        public B icon(Drawable icon) {
            mIcon = icon;
            return (B) this;
        }

        /**
         * Sets the action's icon drawable by retrieving it by resource ID from the specified
         * context. This is a convenience function that simply looks up the drawable and calls
         * {@link #icon(Drawable)}.
         * @param iconResourceId The resource ID for the icon associated with this action.
         * @param context The context whose resource ID should be retrieved.
         * @deprecated Use {@link #icon(int)}.
         */
        @Deprecated
        public B iconResourceId(@DrawableRes int iconResourceId, Context context) {
            return icon(ContextCompat.getDrawable(context, iconResourceId));
        }

        /**
         * Sets the action's icon drawable by retrieving it by resource ID from Builder's
         * context. This is a convenience function that simply looks up the drawable and calls
         * {@link #icon(Drawable)}.
         * @param iconResourceId The resource ID for the icon associated with this action.
         */
        public B icon(@DrawableRes int iconResourceId) {
            return icon(ContextCompat.getDrawable(getContext(), iconResourceId));
        }

        /**
         * Indicates whether this action title is editable. Note: Editable actions cannot also be
         * checked, or belong to a check set.
         * @param editable Whether this action is editable.
         */
        public B editable(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_TITLE) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_TITLE;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action's description is editable
         * @param editable Whether this action description is editable.
         */
        public B descriptionEditable(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_DESCRIPTION) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_DESCRIPTION;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action has a view can be activated to edit, e.g. a DatePicker.
         * @param editable Whether this action has view can be activated to edit.
         */
        public B hasEditableActivatorView(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_ACTIVATOR_VIEW) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_ACTIVATOR_VIEW;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action title not in editing.
         *
         * @param inputType InputType for the action title not in editing.
         */
        public B inputType(int inputType) {
            mInputType = inputType;
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action description not in editing.
         *
         * @param inputType InputType for the action description not in editing.
         */
        public B descriptionInputType(int inputType) {
            mDescriptionInputType = inputType;
            return (B) this;
        }


        /**
         * Sets {@link InputType} of this action title in editing.
         *
         * @param inputType InputType for the action title in editing.
         */
        public B editInputType(int inputType) {
            mEditInputType = inputType;
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action description in editing.
         *
         * @param inputType InputType for the action description in editing.
         */
        public B descriptionEditInputType(int inputType) {
            mDescriptionEditInputType = inputType;
            return (B) this;
        }


        private boolean isChecked() {
            return (mActionFlags & PF_CHECKED) == PF_CHECKED;
        }
        /**
         * Indicates whether this action is initially checked.
         * @param checked Whether this action is checked.
         */
        public B checked(boolean checked) {
            setFlags(checked ? PF_CHECKED : 0, PF_CHECKED);
            if (mEditable != EDITING_NONE) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action is part of a single-select group similar to radio buttons
         * or this action is a checkbox. When one item in a check set is checked, all others with
         * the same check set ID will be checked automatically.
         * @param checkSetId The check set ID, or {@link GuidedAction#NO_CHECK_SET} to indicate not
         * radio or checkbox, or {@link GuidedAction#CHECKBOX_CHECK_SET_ID} to indicate a checkbox.
         */
        public B checkSetId(int checkSetId) {
            mCheckSetId = checkSetId;
            if (mEditable != EDITING_NONE) {
                throw new IllegalArgumentException("Editable actions cannot also be in check sets");
            }
            return (B) this;
        }

        /**
         * Indicates whether the title and description are long, and should be displayed
         * appropriately.
         * @param multilineDescription Whether this action has a multiline description.
         */
        public B multilineDescription(boolean multilineDescription) {
            setFlags(multilineDescription ? PF_MULTI_LINE_DESCRIPTION : 0,
                PF_MULTI_LINE_DESCRIPTION);
            return (B) this;
        }

        /**
         * Indicates whether this action has a next state and should display a chevron.
         * @param hasNext Whether this action has a next state.
         */
        public B hasNext(boolean hasNext) {
            setFlags(hasNext ? PF_HAS_NEXT : 0, PF_HAS_NEXT);
            return (B) this;
        }

        /**
         * Indicates whether this action is for information purposes only and cannot be clicked.
         * @param infoOnly Whether this action has a next state.
         */
        public B infoOnly(boolean infoOnly) {
            setFlags(infoOnly ? PF_INFO_ONLY : 0, PF_INFO_ONLY);
            return (B) this;
        }

        /**
         * Indicates whether this action is enabled.  If not enabled, an action cannot be clicked.
         * @param enabled Whether the action is enabled.
         */
        public B enabled(boolean enabled) {
            setFlags(enabled ? PF_ENABLED : 0, PF_ENABLED);
            return (B) this;
        }

        /**
         * Indicates whether this action can take focus.
         * @param focusable
         * @return The same BuilderBase object.
         */
        public B focusable(boolean focusable) {
            setFlags(focusable ? PF_FOCUSABLE : 0, PF_FOCUSABLE);
            return (B) this;
        }

        /**
         * Sets sub actions list.
         * @param subActions
         * @return The same BuilderBase object.
         */
        public B subActions(List<GuidedAction> subActions) {
            mSubActions = subActions;
            return (B) this;
        }

        /**
         * Explicitly sets auto restore feature on the GuidedAction.  It's by default true.
         * @param autoSaveRestoreEnabled True if turn on auto save/restore of GuidedAction content,
         *                                false otherwise.
         * @return The same BuilderBase object.
         * @see GuidedAction#isAutoSaveRestoreEnabled()
         */
        public B autoSaveRestoreEnabled(boolean autoSaveRestoreEnabled) {
            setFlags(autoSaveRestoreEnabled ? PF_AUTORESTORE : 0, PF_AUTORESTORE);
            return (B) this;
        }

        /**
         * Sets autofill hints. See {@link android.view.View#setAutofillHints}
         * @param hints List of hints for autofill.
         * @return The same BuilderBase object.
         */
        public B autofillHints(String... hints) {
            mAutofillHints = hints;
            return (B) this;
        }
    }

    /**
     * Builds a {@link GuidedAction} object.
     */
    public static class Builder extends BuilderBase<Builder> {

        /**
         * @deprecated Use {@link GuidedAction.Builder#Builder(Context)}.
         */
        @Deprecated
        public Builder() {
            super(null);
        }

        /**
         * Creates a Builder for GuidedAction.
         * @param context Context to build GuidedAction.
         */
        public Builder(Context context) {
            super(context);
        }

        /**
         * Builds the GuidedAction corresponding to this Builder.
         * @return The GuidedAction as configured through this Builder.
         */
        public GuidedAction build() {
            GuidedAction action = new GuidedAction();
            applyValues(action);
            return action;
        }

    }

    static final int PF_CHECKED = 0x00000001;
    static final int PF_MULTI_LINE_DESCRIPTION = 0x00000002;
    static final int PF_HAS_NEXT = 0x00000004;
    static final int PF_INFO_ONLY = 0x00000008;
    static final int PF_ENABLED = 0x00000010;
    static final int PF_FOCUSABLE = 0x00000020;
    static final int PF_AUTORESTORE = 0x00000040;
    int mActionFlags;

    private CharSequence mEditTitle;
    private CharSequence mEditDescription;
    int mEditable;
    int mInputType;
    int mDescriptionInputType;
    int mEditInputType;
    int mDescriptionEditInputType;
    String[] mAutofillHints;

    int mCheckSetId;

    List<GuidedAction> mSubActions;

    Intent mIntent;

    protected GuidedAction() {
        super(0);
    }

    private void setFlags(int flag, int mask) {
        mActionFlags = (mActionFlags & ~mask) | (flag & mask);
    }

    /**
     * Returns the title of this action.
     * @return The title set when this action was built.
     */
    public CharSequence getTitle() {
        return getLabel1();
    }

    /**
     * Sets the title of this action.
     * @param title The title set when this action was built.
     */
    public void setTitle(CharSequence title) {
        setLabel1(title);
    }

    /**
     * Returns the optional title text to edit.  When not null, it is being edited instead of
     * {@link #getTitle()}.
     * @return Optional title text to edit instead of {@link #getTitle()}.
     */
    public CharSequence getEditTitle() {
        return mEditTitle;
    }

    /**
     * Sets the optional title text to edit instead of {@link #setTitle(CharSequence)}.
     * @param editTitle Optional title text to edit instead of {@link #setTitle(CharSequence)}.
     */
    public void setEditTitle(CharSequence editTitle) {
        mEditTitle = editTitle;
    }

    /**
     * Returns the optional description text to edit.  When not null, it is being edited instead of
     * {@link #getDescription()}.
     * @return Optional description text to edit instead of {@link #getDescription()}.
     */
    public CharSequence getEditDescription() {
        return mEditDescription;
    }

    /**
     * Sets the optional description text to edit instead of {@link #setDescription(CharSequence)}.
     * @param editDescription Optional description text to edit instead of
     * {@link #setDescription(CharSequence)}.
     */
    public void setEditDescription(CharSequence editDescription) {
        mEditDescription = editDescription;
    }

    /**
     * Returns true if {@link #getEditTitle()} is not null.  When true, the {@link #getEditTitle()}
     * is being edited instead of {@link #getTitle()}.
     * @return true if {@link #getEditTitle()} is not null.
     */
    public boolean isEditTitleUsed() {
        return mEditTitle != null;
    }

    /**
     * Returns the description of this action.
     * @return The description of this action.
     */
    public CharSequence getDescription() {
        return getLabel2();
    }

    /**
     * Sets the description of this action.
     * @param description The description of the action.
     */
    public void setDescription(CharSequence description) {
        setLabel2(description);
    }

    /**
     * Returns the intent associated with this action.
     * @return The intent set when this action was built.
     */
    public Intent getIntent() {
        return mIntent;
    }

    /**
     * Sets the intent of this action.
     * @param intent New intent to set on this action.
     */
    public void setIntent(Intent intent) {
        mIntent = intent;
    }

    /**
     * Returns whether this action title is editable.
     * @return true if the action title is editable, false otherwise.
     */
    public boolean isEditable() {
        return mEditable == EDITING_TITLE;
    }

    /**
     * Returns whether this action description is editable.
     * @return true if the action description is editable, false otherwise.
     */
    public boolean isDescriptionEditable() {
        return mEditable == EDITING_DESCRIPTION;
    }

    /**
     * Returns if this action has editable title or editable description.
     * @return True if this action has editable title or editable description, false otherwise.
     */
    public boolean hasTextEditable() {
        return mEditable == EDITING_TITLE || mEditable == EDITING_DESCRIPTION;
    }

    /**
     * Returns whether this action can be activated to edit, e.g. a DatePicker.
     * @return true if the action can be activated to edit.
     */
    public boolean hasEditableActivatorView() {
        return mEditable == EDITING_ACTIVATOR_VIEW;
    }

    /**
     * Returns InputType of action title in editing; only valid when {@link #isEditable()} is true.
     * @return InputType of action title in editing.
     */
    public int getEditInputType() {
        return mEditInputType;
    }

    /**
     * Returns InputType of action description in editing; only valid when
     * {@link #isDescriptionEditable()} is true.
     * @return InputType of action description in editing.
     */
    public int getDescriptionEditInputType() {
        return mDescriptionEditInputType;
    }

    /**
     * Returns InputType of action title not in editing.
     * @return InputType of action title not in editing.
     */
    public int getInputType() {
        return mInputType;
    }

    /**
     * Returns InputType of action description not in editing.
     * @return InputType of action description not in editing.
     */
    public int getDescriptionInputType() {
        return mDescriptionInputType;
    }

    /**
     * Returns whether this action is checked.
     * @return true if the action is currently checked, false otherwise.
     */
    public boolean isChecked() {
        return (mActionFlags & PF_CHECKED) == PF_CHECKED;
    }

    /**
     * Sets whether this action is checked.
     * @param checked Whether this action should be checked.
     */
    public void setChecked(boolean checked) {
        setFlags(checked ? PF_CHECKED : 0, PF_CHECKED);
    }

    /**
     * Returns the check set id this action is a part of. All actions in the same list with the same
     * check set id are considered linked. When one of the actions within that set is selected, that
     * action becomes checked, while all the other actions become unchecked.
     *
     * @return an integer representing the check set this action is a part of, or
     *         {@link #CHECKBOX_CHECK_SET_ID} if this is a checkbox, or {@link #NO_CHECK_SET} if
     *         this action is not a checkbox or radiobutton.
     */
    public int getCheckSetId() {
        return mCheckSetId;
    }

    /**
     * Returns whether this action is has a multiline description.
     * @return true if the action was constructed as having a multiline description, false
     * otherwise.
     */
    public boolean hasMultilineDescription() {
        return (mActionFlags & PF_MULTI_LINE_DESCRIPTION) == PF_MULTI_LINE_DESCRIPTION;
    }

    /**
     * Returns whether this action is enabled.
     * @return true if the action is currently enabled, false otherwise.
     */
    public boolean isEnabled() {
        return (mActionFlags & PF_ENABLED) == PF_ENABLED;
    }

    /**
     * Sets whether this action is enabled.
     * @param enabled Whether this action should be enabled.
     */
    public void setEnabled(boolean enabled) {
        setFlags(enabled ? PF_ENABLED : 0, PF_ENABLED);
    }

    /**
     * Returns whether this action is focusable.
     * @return true if the action is currently focusable, false otherwise.
     */
    public boolean isFocusable() {
        return (mActionFlags & PF_FOCUSABLE) == PF_FOCUSABLE;
    }

    /**
     * Sets whether this action is focusable.
     * @param focusable Whether this action should be focusable.
     */
    public void setFocusable(boolean focusable) {
        setFlags(focusable ? PF_FOCUSABLE : 0, PF_FOCUSABLE);
    }

    /**
     * Returns autofill hints, see {@link android.view.View#setAutofillHints(String...)}.
     */
    public String[] getAutofillHints() {
        return mAutofillHints;
    }

    /**
     * Returns whether this action will request further user input when selected, such as showing
     * another GuidedStepFragment or launching a new activity. Configured during construction.
     * @return true if the action will request further user input when selected, false otherwise.
     */
    public boolean hasNext() {
        return (mActionFlags & PF_HAS_NEXT) == PF_HAS_NEXT;
    }

    /**
     * Returns whether the action will only display information and is thus not clickable. If both
     * this and {@link #hasNext()} are true, infoOnly takes precedence. The default is false. For
     * example, this might represent e.g. the amount of storage a document uses, or the cost of an
     * app.
     * @return true if will only display information, false otherwise.
     */
    public boolean infoOnly() {
        return (mActionFlags & PF_INFO_ONLY) == PF_INFO_ONLY;
    }

    /**
     * Change sub actions list.
     * @param actions Sub actions list to set on this action.  Sets null to disable sub actions.
     */
    public void setSubActions(List<GuidedAction> actions) {
        mSubActions = actions;
    }

    /**
     * @return List of sub actions or null if sub actions list is not enabled.
     */
    public List<GuidedAction> getSubActions() {
        return mSubActions;
    }

    /**
     * @return True if has sub actions list, even it's currently empty.
     */
    public boolean hasSubActions() {
        return mSubActions != null;
    }

    /**
     * Returns true if Action will be saved to instanceState and restored later, false otherwise.
     * The default value is true.  When isAutoSaveRestoreEnabled() is true and {@link #getId()} is
     * not {@link #NO_ID}:
     * <ul>
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * </ul>
     * App may explicitly disable auto restore and handle by itself. App should override Fragment
     * onSaveInstanceState() and onCreateActions()
     * @return True if Action will be saved to instanceState and restored later, false otherwise.
     */
    public final boolean isAutoSaveRestoreEnabled() {
        return (mActionFlags & PF_AUTORESTORE) == PF_AUTORESTORE;
    }

    /**
     * Save action into a bundle using a given key. When isAutoRestoreEna() is true:
     * <ul>
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * </ul>
     * Subclass may override this method.
     * @param bundle  Bundle to save the Action.
     * @param key Key used to save the Action.
     */
    public void onSaveInstanceState(Bundle bundle, String key) {
        if (needAutoSaveTitle() && getTitle() != null) {
            bundle.putString(key, getTitle().toString());
        } else if (needAutoSaveDescription() && getDescription() != null) {
            bundle.putString(key, getDescription().toString());
        } else if (getCheckSetId() != NO_CHECK_SET) {
            bundle.putBoolean(key, isChecked());
        }
    }

    /**
     * Restore action from a bundle using a given key. When isAutoRestore() is true:
     * <ul>
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * </ul>
     * Subclass may override this method.
     * @param bundle  Bundle to restore the Action from.
     * @param key Key used to restore the Action.
     */
    public void onRestoreInstanceState(Bundle bundle, String key) {
        if (needAutoSaveTitle()) {
            String title = bundle.getString(key);
            if (title != null) {
                setTitle(title);
            }
        } else if (needAutoSaveDescription()) {
            String description = bundle.getString(key);
            if (description != null) {
                setDescription(description);
            }
        } else if (getCheckSetId() != NO_CHECK_SET) {
            setChecked(bundle.getBoolean(key, isChecked()));
        }
    }

    static boolean isPasswordVariant(int inputType) {
        final int variation = inputType & InputType.TYPE_MASK_VARIATION;
        return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD
                || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
                || variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
    }

    final boolean needAutoSaveTitle() {
        return isEditable() && !isPasswordVariant(getEditInputType());
    }

    final boolean needAutoSaveDescription() {
        return isDescriptionEditable() && !isPasswordVariant(getDescriptionEditInputType());
    }

}