Добавить пошаговый инструкции

Создавайте лучше с помощью Compose
Создавайте красивые пользовательские интерфейсы с минимальным количеством кода, используя Jetpack Compose для ОС Android TV.

Ваше приложение может содержать многоэтапные задачи для пользователей. Например, вашему приложению может потребоваться помочь пользователям приобрести дополнительный контент, настроить сложную конфигурацию или просто подтвердить решение. Все эти задачи требуют, чтобы пользователи выполнили один или несколько упорядоченных шагов или решений.

Библиотека androidx.leanback предоставляет классы для реализации многошаговых пользовательских задач. На этой странице описано, как использовать класс GuidedStepSupportFragment чтобы помочь пользователю принять ряд решений для выполнения задачи. GuidedStepSupportFragment использует лучшие практики пользовательского интерфейса телевизора, чтобы упростить понимание и навигацию по многоэтапным задачам на телевизионных устройствах.

Укажите подробную информацию о шаге

GuidedStepSupportFragment представляет собой один шаг в серии шагов. Визуально он предоставляет представление со списком возможных действий или решений для данного шага.

Рисунок 1. Пример пошагового руководства.

Для каждого шага многошаговой задачи расширьте GuidedStepSupportFragment и предоставьте контекстную информацию о шаге и действиях, которые может предпринять пользователь. Переопределите onCreateGuidance() и верните новый GuidanceStylist.Guidance , содержащий контекстную информацию, такую ​​как заголовок, описание и значок шага, как показано в следующем примере:

Котлин

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)
    )
}

Ява

@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);
}

Добавьте подкласс GuidedStepSupportFragment к нужному действию, вызвав GuidedStepSupportFragment.add() в методе onCreate() вашего действия.

Если ваша активность содержит только объекты GuidedStepSupportFragment , используйте GuidedStepSupportFragment.addAsRoot() вместо add() чтобы добавить первый GuidedStepSupportFragment . Использование addAsRoot() помогает гарантировать, что если пользователь нажмет кнопку «Назад» на пульте телевизора при просмотре первого GuidedStepSupportFragment , и GuidedStepSupportFragment , и родительское действие закроются.

Примечание. Добавляйте объекты GuidedStepSupportFragment программно, а не в XML-файлы макета.

Создание и обработка действий пользователя

Добавьте действия пользователя, переопределив onCreateActions() . В переопределении добавьте новое GuidedAction для каждого элемента действия и укажите строку действия, описание и идентификатор. Используйте GuidedAction.Builder для добавления новых действий.

Котлин

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())
    ...

Ява

@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());
...

Действия не ограничиваются выбором одной строки. Вот дополнительные типы действий, которые вы можете создать:

  • Добавьте действие информационной метки, чтобы предоставить дополнительную информацию о выборе пользователя, установив infoOnly(true) . Если infoOnly установлено значение true, пользователи не могут выбрать действие.
  • Добавьте редактируемое текстовое действие, установив editable(true) . Если для editable установлено значение true, пользователь может вводить текст в выбранном действии с помощью пульта дистанционного управления или подключенной клавиатуры. Переопределите onGuidedActionEditedAndProceed() чтобы получить измененный текст, введенный пользователем. Вы также можете переопределить onGuidedActionEditCanceled() чтобы узнать, когда пользователь отменяет ввод.
  • Добавьте набор действий, которые ведут себя как проверяемые переключатели, используя checkSetId() с общим значением идентификатора, чтобы сгруппировать действия в набор. Все действия в одном списке с одинаковым идентификатором набора проверок считаются связанными. Когда пользователь выбирает одно из действий в этом наборе, это действие становится отмеченным, а все остальные действия снимаются.
  • Добавьте действие выбора даты, используя GuidedDatePickerAction.Builder вместо GuidedAction.Builder в onCreateActions() . Переопределите onGuidedActionEditedAndProceed() чтобы получить измененное значение даты, введенное пользователем.
  • Добавьте действие, использующее поддействия, позволяющее пользователю выбирать из расширенного списка вариантов. Поддействия описаны в разделе Добавление поддействий .
  • Добавьте действие кнопки, которое появится справа от списка действий и будет легко доступно. Действия кнопок описаны в разделе «Добавление действий кнопок» .

Вы также можете добавить визуальный индикатор того, что выбор действия приводит к новому шагу, установив hasNext(true) .

Чтобы узнать обо всех различных атрибутах, которые вы можете установить, см. GuidedAction .

Чтобы реагировать на действия, переопределите onGuidedActionClicked() и обработайте переданное GuidedAction . Определите выбранное действие, проверив GuidedAction.getId() .

Добавить субдействия

Некоторые действия могут потребовать от вас предоставления пользователю дополнительного набора возможностей. GuidedAction может указать список подчиненных действий, которые отображаются в виде меню дочерних действий.

Рисунок 2. Пошаговые действия.

Список дополнительных действий может содержать обычные действия или действия переключателей, но не действия выбора даты или редактируемые текстовые действия. Кроме того, пододействие не может иметь собственный набор поддействий, поскольку система не поддерживает более одного уровня поддействий.

Чтобы добавить вложенные действия, сначала создайте и заполните список объектов GuidedAction , которые действуют как вложенные действия, как показано в следующем примере:

Котлин

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

Ява

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());
...

В onCreateActions() создайте GuidedAction верхнего уровня, который отображает список поддействий при выборе:

Котлин

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

Ява

@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());
...
}

Наконец, ответьте на выбор поддействий, переопределив onSubGuidedActionClicked() :

Котлин

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 menu or
    // false to keep the menu expanded
    return true
}

Ява

@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 menu or
   // false to keep the menu expanded
   return true;
}

Добавить действия кнопки

Если ваш пошаговый шаг содержит большой список действий, пользователям, возможно, придется прокручивать список, чтобы получить доступ к наиболее часто используемым действиям. Используйте действия кнопок, чтобы отделить часто используемые действия от списка действий. Действия кнопок отображаются рядом со списком действий, и к ним легко перейти.

Рис. 3. Действия кнопок с пошаговыми инструкциями.

Действия кнопок создаются и обрабатываются так же, как обычные действия, но действия кнопок создаются в onCreateButtonActions() вместо onCreateActions() . Реагируйте на действия кнопок в onGuidedActionClicked() .

Используйте действия кнопок для простых действий, таких как действия навигации между шагами. Не используйте действие выбора даты или другие редактируемые действия в качестве действий кнопок. Кроме того, действия кнопок не могут иметь поддействия.

Сгруппируйте пошаговые инструкции в управляемую последовательность

GuidedStepSupportFragment представляет один шаг. Чтобы создать упорядоченную последовательность шагов, сгруппируйте несколько объектов GuidedStepSupportFragment вместе с помощью GuidedStepSupportFragment.add() , чтобы добавить следующий шаг в последовательности в стек фрагментов.

Котлин

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

Ява

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

Если пользователь нажимает кнопку «Назад» на пульте телевизора, устройство отображает предыдущий GuidedStepSupportFragment в стеке фрагментов. Если вы предоставляете свой собственный GuidedAction , который возвращается к предыдущему шагу, вы можете реализовать поведение Back, вызвав getFragmentManager().popBackStack() . Если вам нужно вернуть пользователя к еще более раннему шагу последовательности, используйте popBackStackToGuidedStepSupportFragment() , чтобы вернуться к определенному GuidedStepSupportFragment в стеке фрагментов.

Когда пользователь завершит последний шаг в последовательности, используйте finishGuidedStepSupportFragments() чтобы удалить все экземпляры GuidedStepSupportFragment из текущего стека и вернуться к исходному родительскому действию. Если первый GuidedStepSupportFragment добавляется с помощью addAsRoot() , вызов finishGuidedStepSupportFragments() также закрывает родительское действие.

Настройте представление шагов

Класс GuidedStepSupportFragment может использовать пользовательские темы, которые управляют такими аспектами представления, как форматирование текста заголовка или анимация пошагового перехода. Пользовательские темы должны наследовать от Theme_Leanback_GuidedStep и могут предоставлять переопределяющие значения для атрибутов, определенных в GuidanceStylist и GuidedActionsStylist .

Чтобы применить пользовательскую тему к GuidedStepSupportFragment , выполните одно из следующих действий:

  • Примените тему к родительскому действию, установив атрибут android:theme для элемента действия в манифесте Android. Установка этого атрибута применяет тему ко всем дочерним представлениям и является наиболее простым способом применения пользовательской темы, если родительское действие содержит только объекты GuidedStepSupportFragment .
  • Если в вашем действии уже используется настраиваемая тема и вы не хотите применять стили GuidedStepSupportFragment к другим представлениям в действии, добавьте атрибут LeanbackGuidedStepTheme_guidedStepTheme к существующей настраиваемой теме действия. Этот атрибут указывает на пользовательскую тему, которую используют только объекты GuidedStepSupportFragment в вашем действии.
  • Если вы используете объекты GuidedStepSupportFragment в разных действиях, которые являются частью одной и той же общей многоэтапной задачи, и хотите использовать единую визуальную тему на всех этапах, переопределите GuidedStepSupportFragment.onProvideTheme() и верните свою пользовательскую тему.

Дополнительную информацию о том, как добавлять стили и темы, см. в разделе Стили и темы .

Класс GuidedStepSupportFragment использует специальные классы стилистов для доступа к атрибутам темы и их применения. Класс GuidanceStylist использует информацию о теме для управления представлением левого представления навигации, а класс GuidedActionsStylist использует информацию о теме для управления представлением правого представления действий.

Чтобы настроить визуальный стиль ваших шагов за пределами возможностей настройки темы, создайте подкласс GuidanceStylist или GuidedActionsStylist и верните свой подкласс в GuidedStepSupportFragment.onCreateGuidanceStylist() или GuidedStepSupportFragment.onCreateActionsStylist() . Подробную информацию о том, что можно настроить в этих подклассах, см. в документации GuidanceStylist и GuidedActionsStylist .