Чтобы показать новичку, как максимально эффективно использовать ваше приложение, представьте вводную информацию при запуске приложения. Вот несколько примеров вводной информации:
- Предоставьте подробную информацию о том, какие каналы доступны, когда пользователь впервые обращается к приложению канала.
- Обратите внимание на примечательные функции вашего приложения.
- Проиллюстрируйте все необходимые или рекомендуемые действия, которые пользователи должны предпринять при первом использовании приложения.
Библиотека androidx.leanback предоставляет класс OnboardingSupportFragment
для представления информации о первом пользователе. В этом руководстве описывается, как использовать класс OnboardingSupportFragment
для представления вводной информации, которая отображается при первом запуске приложения.
OnboardingSupportFragment
использует лучшие практики пользовательского интерфейса ТВ для представления информации таким образом, который соответствует стилям пользовательского интерфейса ТВ и обеспечивает удобную навигацию на телевизионных устройствах.
OnboardingSupportFragment
подходит не для каждого варианта использования. Не используйте OnboardingSupportFragment
, если вам нужно включить элементы пользовательского интерфейса, требующие ввода данных пользователем, например кнопки и поля. Кроме того, не используйте OnboardingSupportFragment
для задач, которые пользователь будет выполнять регулярно. Наконец, если вам нужно представить многостраничный пользовательский интерфейс, требующий ввода данных пользователем, рассмотрите возможность использования GuidedStepSupportFragment
.
Добавьте OnboardingSupportFragment
Чтобы добавить 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)) } } }
Ява
@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() } }
Ява
@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
отображает контент в виде серии упорядоченных страниц. После добавления 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 } }
Ява
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)
Ява
@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)
Ява
@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() } }
Ява
@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
Ява
@Override public int onProvideTheme() { return R.style.Theme_Leanback_Onboarding; }