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

Создавайте лучше с помощью 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;
    }