Чтобы показать пользователю, впервые использующему ваше приложение, как извлечь из него максимальную пользу, предоставьте вводную информацию при запуске приложения. Вот несколько примеров вводной информации:
- Предоставьте пользователю подробную информацию о том, какие каналы доступны при первом доступе к приложению канала.
- Обратите внимание на примечательные особенности вашего приложения.
- Проиллюстрируйте любые необходимые или рекомендуемые шаги, которые пользователи должны предпринять при первом использовании приложения.
Библиотека androidx.leanback предоставляет класс OnboardingSupportFragment для отображения информации для пользователей, впервые запускающих приложение. В этом руководстве описывается, как использовать класс OnboardingSupportFragment для отображения вводной информации, которая показывается при первом запуске приложения.
OnboardingSupportFragment использует лучшие практики пользовательского интерфейса для телевизоров, чтобы представлять информацию таким образом, который соответствует стилю интерфейса телевизоров и обеспечивает удобную навигацию на телевизионных устройствах.

Рисунок 1. Пример фрагмента OnboardingSupportFragment .
OnboardingSupportFragment подходит не для всех случаев. Не используйте OnboardingSupportFragment если вам необходимо включить элементы пользовательского интерфейса, требующие ввода данных от пользователя, такие как кнопки и поля. Также не используйте OnboardingSupportFragment для задач, которые пользователь будет выполнять регулярно. Наконец, если вам необходимо отобразить многостраничный пользовательский интерфейс, требующий ввода данных от пользователя, рассмотрите возможность использования GuidedStepSupportFragment .
Добавить фрагмент поддержки процесса адаптации
Чтобы добавить OnboardingSupportFragment в ваше приложение, реализуйте класс, расширяющий класс OnboardingSupportFragment . Добавьте этот фрагмент в активность, используя XML-макет активности или программно. Убедитесь, что активность или фрагмент использует тему, производную от Theme_Leanback_Onboarding , как описано в разделе «Настройка тем» .
В методе onCreate() главной активности вашего приложения вызовите startActivity() с Intent , указывающим на родительскую активность вашего OnboardingSupportFragment . Это поможет гарантировать, что ваш OnboardingSupportFragment появится сразу после запуска приложения.
Чтобы гарантировать, что OnboardingSupportFragment будет отображаться только при первом запуске приложения пользователем, используйте объект SharedPreferences для отслеживания того, просматривал ли пользователь уже OnboardingSupportFragment . Задайте логическое значение, которое изменится на true, когда пользователь завершит просмотр OnboardingSupportFragment . Проверяйте это значение в методе onCreate() вашей основной активности и запускайте родительскую активность OnboardingSupportFragment только в том случае, если значение равно false.
В следующем примере показана переопределенная функция onCreate() , которая проверяет значение SharedPreferences и, если оно не равно true, вызывает startActivity() для отображения OnboardingSupportFragment :
Котлин
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) PreferenceManager.getDefaultSharedPreferences(this).apply { // Check if we need to display our OnboardingSupportFragment if (!getBoolean(MyOnboardingSupportFragment.COMPLETED_ONBOARDING_PREF_NAME, false)) { // The user hasn't seen the OnboardingSupportFragment yet, so show it startActivity(Intent(this@OnboardingActivity, OnboardingActivity::class.java)) } } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); // Check if we need to display our OnboardingSupportFragment if (!sharedPreferences.getBoolean( MyOnboardingSupportFragment.COMPLETED_ONBOARDING_PREF_NAME, false)) { // The user hasn't seen the OnboardingSupportFragment yet, so show it startActivity(new Intent(this, OnboardingActivity.class)); } }
После того, как пользователь просмотрит OnboardingSupportFragment , отметьте его как просмотренный с помощью объекта SharedPreferences . Для этого переопределите onFinishFragment() в вашем OnboardingSupportFragment и установите значение SharedPreferences равным true, как показано в следующем примере:
Котлин
override fun onFinishFragment() { super.onFinishFragment() // User has seen OnboardingSupportFragment, so mark our SharedPreferences // flag as completed so that we don't show our OnboardingSupportFragment // the next time the user launches the app PreferenceManager.getDefaultSharedPreferences(context).edit().apply { putBoolean(COMPLETED_ONBOARDING_PREF_NAME, true) apply() } }
Java
@Override protected void onFinishFragment() { super.onFinishFragment(); // User has seen OnboardingSupportFragment, so mark our SharedPreferences // flag as completed so that we don't show our OnboardingSupportFragment // the next time the user launches the app SharedPreferences.Editor sharedPreferencesEditor = PreferenceManager.getDefaultSharedPreferences(getContext()).edit(); sharedPreferencesEditor.putBoolean( COMPLETED_ONBOARDING_PREF_NAME, true); sharedPreferencesEditor.apply(); }
Добавить страницы фрагмента поддержки процесса адаптации
Компонент OnboardingSupportFragment отображает контент в виде последовательности упорядоченных страниц. После добавления компонента OnboardingSupportFragment необходимо определить страницы адаптации. Каждая страница может иметь заголовок, описание и несколько дочерних представлений, которые могут содержать изображения или анимацию.

Рисунок 2. Элементы страницы OnboardingSupportFragment .
На рисунке 2 показан пример страницы с выносками, указывающими на настраиваемые элементы страницы, которые может предоставлять ваш OnboardingSupportFragment . Элементы страницы следующие:
- Заголовок страницы.
- Описание страницы.
- В данном случае это просто зеленая галочка в сером прямоугольнике. Этот режим отображения необязателен. Используйте его для иллюстрации деталей страницы. Например, вы можете добавить скриншот, демонстрирующий функцию приложения, описанную на странице.
- Фоновое изображение страницы, в данном случае — простой синий градиент. Это изображение всегда отображается позади других элементов на странице. Это необязательное изображение.
- Основной элемент страницы, в данном случае логотип. Этот элемент всегда отображается поверх всех остальных элементов на странице. Он является необязательным.
Инициализируйте информацию о странице при первом создании или прикреплении вашего OnboardingSupportFragment к родительской активности, поскольку система запрашивает информацию о странице при создании представления фрагмента. Вы можете инициализировать информацию о странице в конструкторе вашего класса или в переопределении метода onAttach() .
Переопределите каждый из следующих методов, которые предоставляют системе информацию о странице:
-
getPageCount()возвращает количество страниц в вашемOnboardingSupportFragment. -
getPageTitle()возвращает заголовок для запрошенной страницы. -
getPageDescription()возвращает описание для запрошенной страницы.
Переопределите каждый из следующих методов, чтобы предоставить необязательные дочерние представления для отображения изображений или анимации:
-
onCreateBackgroundView()возвращаетView, который вы создаете для использования в качестве фонового представления, или null, если фоновое представление не требуется. -
onCreateContentView()возвращаетView, который вы создаете для использования в качестве представления контента, или null, если представление контента не требуется. -
onCreateForegroundView()возвращаетView, который вы создаете для использования в качестве представления на переднем плане, или null, если представление на переднем плане не требуется.
Система добавляет созданное вами View в макет страницы. В следующем примере переопределяется onCreateContentView() и возвращается ImageView :
Котлин
private lateinit var contentView: ImageView ... override fun onCreateContentView(inflater: LayoutInflater?, container: ViewGroup?): View? { return ImageView(context).apply { scaleType = ImageView.ScaleType.CENTER_INSIDE setImageResource(R.drawable.onboarding_content_view) setPadding(0, 32, 0, 32) contentView = this } }
Java
private ImageView contentView; ... @Override protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) { contentView = new ImageView(getContext()); contentView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); contentView.setImageResource(R.drawable.onboarding_content_view); contentView.setPadding(0, 32, 0, 32); return contentView; }
Добавить начальный экран с логотипом.
Ваш OnboardingSupportFragment может начинаться с необязательного экрана с логотипом, представляющего ваше приложение. Если вы хотите отобразить Drawable в качестве экрана с логотипом, вызовите setLogoResourceId() с идентификатором вашего Drawable в методе onCreate() вашего OnboardingSupportFragment . Система плавно отобразит Drawable , а затем плавно Drawable перед отображением первой страницы вашего OnboardingSupportFragment .
Если вы хотите задать собственную анимацию для экрана с логотипом, вместо вызова метода setLogoResourceId() переопределите onCreateLogoAnimation() и верните объект Animator , который будет отображать вашу пользовательскую анимацию, как показано в следующем примере:
Котлин
public override fun onCreateLogoAnimation(): Animator = AnimatorInflater.loadAnimator(context, R.animator.onboarding_logo_screen_animation)
Java
@Override public Animator onCreateLogoAnimation() { return AnimatorInflater.loadAnimator(getContext(), R.animator.onboarding_logo_screen_animation); }
Настройка анимации страниц
Система использует стандартные анимации при отображении первой страницы вашего OnboardingSupportFragment и при переходе пользователя на другую страницу. Вы можете настроить эти анимации, переопределив методы в вашем OnboardingSupportFragment .
Чтобы настроить анимацию, отображаемую на первой странице, переопределите метод onCreateEnterAnimation() и верните объект Animator . В следующем примере создается Animator , который масштабирует содержимое по горизонтали:
Котлин
override fun onCreateEnterAnimation(): Animator = ObjectAnimator.ofFloat(contentView, View.SCALE_X, 0.2f, 1.0f) .setDuration(ANIMATION_DURATION)
Java
@Override protected Animator onCreateEnterAnimation() { Animator startAnimator = ObjectAnimator.ofFloat(contentView, View.SCALE_X, 0.2f, 1.0f).setDuration(ANIMATION_DURATION); return startAnimator; }
Чтобы настроить анимацию, используемую при переходе пользователя на другую страницу, переопределите метод onPageChanged() . В методе onPageChanged() создайте объекты Animator , которые удаляют предыдущую страницу и отображают следующую, добавьте их в AnimatorSet и воспроизведите набор. В следующем примере используется анимация затухания для удаления предыдущей страницы, обновление изображения в представлении контента и анимация появления для отображения следующей страницы:
Котлин
override fun onPageChanged(newPage: Int, previousPage: Int) { // Create a fade-out animation for previousPage and, once // done, swap the contentView image with the next page's image val fadeOut = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 1.0f, 0.0f) .setDuration(ANIMATION_DURATION) .apply { addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { mContentView.setImageResource(pageImages[newPage]) } }) } // Create a fade-in animation for nextPage val fadeIn = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 0.0f, 1.0f) .setDuration(ANIMATION_DURATION) // Create AnimatorSet with fade-out and fade-in animators and start it AnimatorSet().apply { playSequentially(fadeOut, fadeIn) start() } }
Java
@Override protected void onPageChanged(final int newPage, int previousPage) { // Create a fade-out animation for previousPage and, once // done, swap the contentView image with the next page's image Animator fadeOut = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 1.0f, 0.0f).setDuration(ANIMATION_DURATION); fadeOut.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mContentView.setImageResource(pageImages[newPage]); } }); // Create a fade-in animation for nextPage Animator fadeIn = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 0.0f, 1.0f).setDuration(ANIMATION_DURATION); // Create AnimatorSet with fade-out and fade-in animators and start it AnimatorSet set = new AnimatorSet(); set.playSequentially(fadeOut, fadeIn); set.start(); }
Более подробную информацию о создании объектов Animator и AnimatorSet см. в разделе «Обзор анимации свойств» .
Настройте темы
Любая реализация OnboardingSupportFragment должна использовать либо тему Theme_Leanback_Onboarding , либо тему, наследующую от Theme_Leanback_Onboarding . Установить тему для вашего OnboardingSupportFragment можно одним из следующих способов:
- Установите для родительского элемента
OnboardingSupportFragmentжелаемую тему оформления. В следующем примере показано, как настроить элемент оформления для использованияTheme_Leanback_Onboardingв манифесте приложения:<activity android:name=".OnboardingActivity" android:enabled="true" android:exported="true" android:theme="@style/Theme.Leanback.Onboarding"> </activity>
- Задайте тему в родительском действии, используя атрибут
LeanbackOnboardingTheme_onboardingThemeв пользовательской теме действия. Укажите в этом атрибуте другую пользовательскую тему, которую используют только объектыOnboardingSupportFragmentв вашем действии. Используйте этот подход, если ваше действие уже использует пользовательскую тему, и вы не хотите применять стилиOnboardingSupportFragmentк другим представлениям в действии. - Переопределите
onProvideTheme()и верните желаемую тему. Используйте этот подход, если несколько активностей используют вашOnboardingSupportFragmentили если родительская активность не может использовать желаемую тему. В следующем примере методonProvideTheme()переопределяет метод и возвращаетTheme_Leanback_Onboarding:Котлин
override fun onProvideTheme(): Int = R.style.Theme_Leanback_Onboarding
Java
@Override public int onProvideTheme() { return R.style.Theme_Leanback_Onboarding; }
