Cómo agregar un paso guiado

Tu aplicación puede tener tareas de varios pasos para los usuarios. Por ejemplo, es posible que tu necesite guiarlos para comprar contenido adicional, configurar de una opción compleja o simplemente confirmar una decisión. Todas estas tareas requieren seguir un proceso de uno o más pasos o decisiones.

La biblioteca de Leanback de AndroidX proporciona clases que permiten implementar tareas de varios pasos para los usuarios. En esta lección, se analiza el uso de la clase GuidedStepFragment para guiar al usuario a través de una serie de decisiones que le permitirán completar una tarea. GuidedStepFragment usa las prácticas recomendadas de la IU de TV para facilitar la comprensión de las tareas de varios pasos y simplificar la navegación en dispositivos de TV.

Cómo proporcionar detalles para un paso

Un objeto GuidedStepFragment representa un solo paso en una serie. Visualmente, proporciona una vista de guía a la izquierda con información del paso. A la derecha, GuidedStepFragment muestra la lista de posibles acciones o decisiones para el paso.

Figura 1: Un ejemplo de paso guiado

Para cada paso de tu tarea de varios pasos, extiende GuidedStepFragment y brinda información de contexto acerca del paso y las acciones que puede realizar el usuario. Anula onCreateGuidance() y muestra un nuevo objeto GuidanceStylist.Guidance que contenga información de contexto, como el título del paso, una descripción y un ícono.

Kotlin

    override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {
        return GuidanceStylist.Guidance(
                getString(R.string.guidedstep_first_title),
                getString(R.string.guidedstep_first_description),
                getString(R.string.guidedstep_first_breadcrumb),
                activity.getDrawable(R.drawable.guidedstep_main_icon_1)
        )
    }
    

Java

    @Override
    public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
        String title = getString(R.string.guidedstep_first_title);
        String breadcrumb = getString(R.string.guidedstep_first_breadcrumb);
        String description = getString(R.string.guidedstep_first_description);
        Drawable icon = getActivity().getDrawable(R.drawable.guidedstep_main_icon_1);
        return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
    }
    

Agrega tu subclase GuidedStepFragment a tu actividad deseada. Para ello, llama a GuidedStepFragment.add() en el método onCreate() de tu actividad. Si tu actividad solo contiene objetos GuidedStepFragment, usa GuidedStepFragment.addAsRoot() en lugar de add() para agregar el primer objeto GuidedStepFragment. El uso de addAsRoot() garantiza que, si el usuario presiona el botón Atrás en el control remoto de la TV cuando mira el primer objeto GuidedStepFragment, se cierren tanto GuidedStepFragment como la actividad principal.

Nota: Agrega objetos GuidedStepFragment de manera programática y no en tus archivos XML de diseño.

Cómo crear y administrar acciones de usuarios

Anula onCreateActions() para agregar acciones de usuarios. En tu anulación, agrega un nuevo objeto GuidedAction por cada elemento de acción y proporciona la string de la acción, una descripción y un ID. Usa GuidedAction.Builder para agregar nuevas acciones.

Kotlin

    override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
        super.onCreateActions(actions, savedInstanceState)

        // Add "Continue" user action for this step
        actions.add(GuidedAction.Builder()
                .id(CONTINUE)
                .title(getString(R.string.guidedstep_continue))
                .description(getString(R.string.guidedstep_letsdoit))
                .hasNext(true)
                .build())
        ...
    

Java

    @Override
    public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
        // Add "Continue" user action for this step
        actions.add(new GuidedAction.Builder()
               .id(CONTINUE)
               .title(getString(R.string.guidedstep_continue))
               .description(getString(R.string.guidedstep_letsdoit))
               .hasNext(true)
               .build());
    ...
    

Las acciones no se limitan a selecciones de una sola línea. Aquí puedes ver otros tipos de acciones que puedes crear:

  • Configura infoOnly(true) para agregar una acción de etiqueta de información. Si configuras infoOnly en verdadero, el usuario no podrá seleccionar la acción. Usa acciones de etiqueta para proporcionar información adicional sobre las elecciones del usuario.
  • Configura editable(true) para agregar una acción de texto editable. Si editable se configura en verdadero, al seleccionar la acción, el usuario puede ingresar texto con el control remoto o un teclado conectado. Anula onGuidedActionEdited() o onGuidedActionEditedAndProceed() para obtener el texto modificado que ingresó el usuario.
  • Configura checkSetId() con un valor de ID común para agrupar acciones en un conjunto a fin de agregar un conjunto de acciones que se comporten como botones de selección que se pueden marcar. Todas las acciones que aparecen en la misma lista con el mismo ID de conjunto de marca se consideran vinculadas. Cuando el usuario selecciona una de las acciones de ese conjunto, esa acción aparece marcada, mientras que las otras opciones aparecen desmarcadas.
  • Agrega una acción de selector de fecha. Para ello, usa GuidedDatePickerAction.Builder en lugar de GuidedAction.Builder en onCreateActions(). Anula onGuidedActionEdited() o onGuidedActionEditedAndProceed() para obtener el valor de fecha modificado que ingresó el usuario.
  • Agrega una acción que use subacciones para permitir al usuario elegir entre una lista ampliada de opciones. Las subacciones se describen en Cómo agregar subacciones.
  • Agrega una acción de botón de fácil acceso en la parte derecha de la lista de acciones. Las acciones de botones se describen en Cómo agregar acciones de botones.

También puedes configurar hasNext(true) para agregar un indicador visual de que la selección de la acción lleva a un nuevo paso. Para ver todos los atributos diferentes que puedes configurar, consulta GuidedAction.

Para responder a acciones, anula onGuidedActionClicked() y procesa el objeto GuidedAction. Examina GuidedAction.getId() a fin de identificar la acción seleccionada.

Cómo agregar subacciones

Es posible que algunas acciones requieran dar al usuario un conjunto adicional de opciones. Un objeto GuidedAction puede especificar una lista de subacciones que se muestran como lista desplegable de acciones secundarias.

Figura 2: Subacciones de pasos guiados

La lista de subacciones puede contener acciones normales o de botón de selección, pero no acciones de selección de fechas ni texto editable. Además, una subacción no puede tener su propio conjunto de subacciones, ya que el sistema no admite más de un nivel de subacciones. Los conjuntos de acciones profundamente anidados crean una experiencia del usuario negativa.

Para agregar subacciones, crea una lista de GuidedActions, que actuarán como subacciones, y complétala:

Kotlin

    subActions.add(GuidedAction.Builder()
            .id(SUBACTION1)
            .title(getString(R.string.guidedstep_subaction1_title))
            .description(getString(R.string.guidedstep_subaction1_desc))
            .build())
    ...
    

Java

    List<GuidedAction> subActions = new ArrayList<GuidedAction>();
    subActions.add(new GuidedAction.Builder()
           .id(SUBACTION1)
           .title(getString(R.string.guidedstep_subaction1_title))
           .description(getString(R.string.guidedstep_subaction1_desc))
           .build());
    ...
    

En onCreateActions(), crea un objeto GuidedAction de nivel superior que mostrará la lista de subacciones cuando se lo seleccione:

Kotlin

        ...
        actions.add(GuidedAction.Builder()
                .id(SUBACTIONS)
                .title(getString(R.string.guidedstep_subactions_title))
                .description(getString(R.string.guidedstep_subactions_desc))
                .subActions(subActions)
                .build())
        ...
    

Java

    @Override
    public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
    ...
        actions.add(new GuidedAction.Builder()
               .id(SUBACTIONS)
               .title(getString(R.string.guidedstep_subactions_title))
               .description(getString(R.string.guidedstep_subactions_desc))
               .subActions(subActions)
               .build());
    ...
    }
    

Por último, anula onSubGuidedActionClicked() para responder a las selecciones de subacciones:

Kotlin

    override fun onSubGuidedActionClicked(action: GuidedAction): Boolean {
        // Check for which action was clicked, and handle as needed
        when(action.id) {
            SUBACTION1 -> {
                // Subaction 1 selected
            }
        }
        // Return true to collapse the subactions drop-down list, or
        // false to keep the drop-down list expanded.
        return true
    }
    

Java

    @Override
    public boolean onSubGuidedActionClicked(GuidedAction action) {
       // Check for which action was clicked, and handle as needed
       if (action.getId() == SUBACTION1) {
           // Subaction 1 selected
       }
       // Return true to collapse the subactions drop-down list, or
       // false to keep the drop-down list expanded.
       return true;
    }
    

Cómo agregar acciones de botones

Si tu paso guiado tiene una lista larga de acciones, los usuarios podrían tener que desplazarse por la lista para acceder a las acciones que más suelen usarse. Usa acciones de botones para separar las acciones comúnmente usadas de la lista de acciones. Las acciones de botones aparecen a la derecha de la lista de acciones y resulta simple navegar en ellas.

Figura 3: Acciones de botones de pasos guiados

Las acciones de botones se crean y administran como acciones normales, pero en onCreateButtonActions(), en lugar de onCreateActions(). Responde a acciones de botones en onGuidedActionClicked().

Usa acciones de botones para acciones simples, como navegación entre pasos. No uses acciones de selección de fechas o editables como acciones de botones. También, ten en cuenta que las acciones de botones no pueden tener subacciones.

Cómo agrupar pasos guiados en una secuencia guiada

Un objeto GuidedStepFragment representa un solo paso, pero puedes tener varios pasos en una secuencia ordenada. Agrupa varios objetos GuidedStepFragment mediante GuidedStepFragment.add() para agregar el próximo paso a la secuencia de la pila de fragmentos.

Kotlin

    override fun onGuidedActionClicked(action: GuidedAction) {
        val fm = fragmentManager
        when(action.id) {
            CONTINUE -> GuidedStepFragment.add(fm, SecondStepFragment())
        }
    }
    

Java

    @Override
    public void onGuidedActionClicked(GuidedAction action) {
        FragmentManager fm = getFragmentManager();
        if (action.getId() == CONTINUE) {
           GuidedStepFragment.add(fm, new SecondStepFragment());
        }
    ...
    

Si el usuario presiona el botón Atrás en el control remoto de la TV, el dispositivo muestra el objeto GuidedStepFragment anterior de la pila de fragmentos. Si decides proporcionar tu propio objeto GuidedAction que regrese al paso anterior, puedes implementar el comportamiento "Atrás" llamando a getFragmentManager().popBackStack(). Si necesitas que el usuario regrese a un paso anterior en la secuencia, usa popBackStackToGuidedStepFragment() para volver a un elemento GuidedStepFragment específico de la pila de fragmentos.

Cuando el usuario haya finalizado el último paso de la secuencia, usa finishGuidedStepFragments() para quitar todos los objetos GuidedStepFragments de la pila actual y volver a la actividad principal original. Si el primer objeto GuidedStepFragment se agregó con addAsRoot(), llamar a finishGuidedStepFragments() también elegirá la actividad principal.

Cómo personalizar una presentación de pasos

La clase GuidedStepFragment puede usar temas personalizados que controlan los aspectos de presentación, como el formateo del texto del título o las animaciones de transición de pasos. Los temas personalizados deben heredarse de Theme_Leanback_GuidedStep y pueden proporcionar valores de anulación para los atributos definidos en GuidanceStylist y GuidedActionsStylist.

Para aplicar un tema personalizado a tu objeto GuidedStepFragment, realiza una de las siguientes tareas:

  • Para aplicar el tema a la actividad principal, configura el atributo android:theme para el elemento de la actividad en el manifiesto de Android. Al configurar este atributo, se aplica el tema a todas las vistas secundarias. Además, es la forma más fácil de aplicar un tema personalizado si la actividad principal solo contiene objetos GuidedStepFragment.
  • Si tu actividad ya usa un tema personalizado y no quieres aplicar estilos de GuidedStepFragment a otras de sus vistas, agrega el atributo LeanbackGuidedStepTheme_guidedStepTheme al tema de la actividad personalizada existente. Este atributo apunta al tema personalizado que solo usan los objetos GuidedStepFragment de tu actividad.
  • Si usas objetos GuidedStepFragment en diferentes actividades que son parte de la misma tarea de varios pasos general y quieres usar un tema visual constante entre todos los pasos, anula GuidedStepFragment.onProvideTheme() y muestra tu tema personalizado.

Para obtener más información sobre cómo agregar estilos y temas, consulta Estilos y temas.

La clase GuidedStepFragment usa clases de estilo especiales para acceder a atributos de temas y aplicarlos. La clase GuidanceStylist usa información de tema para controlar la presentación de la vista de guía de la izquierda, mientras que la clase GuidedActionsStylist usa información del tema para controlar la presentación de la vista de acciones de la derecha.

Para personalizar el estilo visual de tus pasos más allá de lo que la personalización de temas pueda proporcionar, usa la subclase GuidanceStylist o GuidedActionsStylist y muestra tu subclase en GuidedStepFragment.onCreateGuidanceStylist() o GuidedStepFragment.onCreateActionsStylist(). Para obtener información sobre qué puedes personalizar en estas subclases, consulta la documentación acerca de GuidanceStylist y GuidedActionsStylist.