Познакомьте новых пользователей с вашим приложением

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

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

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

Библиотека androidx.leanback предоставляет класс OnboardingSupportFragment для отображения информации для впервые запускающего приложения. В этом руководстве описывается использование класса OnboardingSupportFragment для отображения вводной информации при первом запуске приложения.

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

Рисунок 1. Пример 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 .

На рисунке 2 показан пример страницы с выносками, обозначающими настраиваемые элементы страницы, которые может предоставить ваш OnboardingSupportFragment . Элементы страницы:

  1. Заголовок страницы.
  2. Описание страницы.
  3. Представление содержимого страницы, в данном случае — простая зелёная галочка в сером поле. Это представление необязательно. Используйте его для отображения информации о странице. Например, можно добавить скриншот, демонстрирующий функцию приложения, описанную на странице.
  4. Фон страницы, в данном случае — простой синий градиент. Этот вид всегда отображается на фоне других видов на странице. Этот вид необязателен.
  5. Вид переднего плана страницы, в данном случае логотип. Этот вид всегда отображается поверх всех остальных видов на странице. Этот вид необязателен.

Инициализируйте информацию о странице при первом создании фрагмента 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;
    }