Przedstaw swoją aplikację nowym użytkownikom

Ulepszaj dzięki funkcji tworzenia wiadomości
Dzięki Jetpack Compose na system operacyjny Android TV możesz tworzyć atrakcyjne interfejsy użytkownika przy użyciu minimalnej ilości pisania.

Aby pokazać nowemu użytkownikowi, jak w pełni wykorzystać możliwości aplikacji, dołącz informacje o niej podczas jej uruchamiania. Oto kilka przykładów informacji wprowadzających:

  • Pokaż szczegółowe informacje o tym, które kanały są dostępne, gdy użytkownik po raz pierwszy otwiera aplikację kanału.
  • Zwróć uwagę na najważniejsze funkcje aplikacji.
  • Opisz wymagane lub zalecane kroki, które użytkownicy powinni wykonać, gdy po raz pierwszy używają aplikacji.

Biblioteka androidx.leanback udostępnia klasę OnboardingSupportFragment do prezentowania informacji o użytkowniku po raz pierwszy. Z tego przewodnika dowiesz się, jak za pomocą klasy OnboardingSupportFragment przedstawić informacje wprowadzające wyświetlane przy pierwszym uruchomieniu aplikacji.

OnboardingSupportFragment korzysta ze sprawdzonych metod korzystania z interfejsu telewizora, aby prezentować informacje w sposób dopasowany do stylów interfejsu telewizora i łatwa w nawigacji na takich urządzeniach.

Rysunek 1. Przykład: OnboardingSupportFragment.

Element OnboardingSupportFragment nie jest odpowiedni w każdym przypadku użycia. Nie używaj OnboardingSupportFragment, gdy chcesz uwzględnić elementy interfejsu, które wymagają danych wejściowych użytkownika, takie jak przyciski i pola. Nie używaj też OnboardingSupportFragment do zadań, które użytkownik będzie regularnie wykonywać. Jeśli chcesz zaprezentować wielostronicowy interfejs użytkownika, który wymaga danych wejściowych użytkownika, rozważ użycie właściwości GuidedStepSupportFragment.

Dodaj fragment OnboardingSupportFragment

Aby dodać do aplikacji obiekt OnboardingSupportFragment, zaimplementuj klasę, która rozszerza klasę OnboardingSupportFragment. Dodaj ten fragment do aktywności, korzystając z kodu XML układu aktywności lub automatycznie. Upewnij się, że działanie lub fragment korzysta z motywu Theme_Leanback_Onboarding, jak opisano w sekcji Dostosowywanie motywów.

W metodzie onCreate() w przypadku głównej aktywności w Twojej aplikacji wywołaj polecenie startActivity() z parametrem Intent wskazującym aktywność nadrzędną wobec elementu OnboardingSupportFragment. Dzięki temu OnboardingSupportFragment pojawi się od razu po uruchomieniu aplikacji.

Aby mieć pewność, że OnboardingSupportFragment pojawi się tylko przy pierwszym uruchomieniu aplikacji przez użytkownika, użyj obiektu SharedPreferences do śledzenia, czy użytkownik wyświetlił już obiekt OnboardingSupportFragment. Zdefiniuj wartość logiczną, która zmieni się na „prawda”, gdy użytkownik obejrzy OnboardingSupportFragment. Sprawdź tę wartość w metodzie onCreate() aktywności głównej i uruchamiaj aktywność nadrzędną OnboardingSupportFragment tylko wtedy, gdy ma ona wartość false (fałsz).

Ten przykład pokazuje zastąpienie parametru onCreate(), które sprawdza wartość SharedPreferences, a jeśli nie jest ustawione, wywołuje startActivity(), aby wyświetlić OnboardingSupportFragment:

Kotlin

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

Gdy użytkownik wyświetli obiekt OnboardingSupportFragment, oznacz go za pomocą obiektu SharedPreferences jako wyświetlony. Aby to zrobić, zastąp zmienną onFinishFragment() w OnboardingSupportFragment i ustaw wartość SharedPreferences na „true” (prawda), jak w tym przykładzie:

Kotlin

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

Dodaj strony OnboardingSupportFragment

OnboardingSupportFragment wyświetla treść w serii uporządkowanych stron. Po dodaniu OnboardingSupportFragment musisz określić strony wprowadzenia. Każda strona może mieć tytuł, opis i kilka widoków podrzędnych z obrazami lub animacjami.

Rysunek 2. OnboardingSupportFragment.

Ilustracja 2 przedstawia przykładową stronę z objaśnieniami oznaczającymi możliwe do dostosowania elementy strony (OnboardingSupportFragment). Elementy strony to:

  1. Tytuł strony.
  2. Opis strony.
  3. Widok treści strony, w tym przypadku prosty zielony znacznik wyboru w szarym polu. Ten widok jest opcjonalny. Użyj tego widoku do zilustrowania szczegółów strony. Możesz np. dołączyć zrzut ekranu z opisem funkcji aplikacji.
  4. Widok tła strony, w tym przypadku prosty niebieski gradient. Ten widok zawsze wyświetla się za innymi wyświetleniami na stronie. Ten widok jest opcjonalny.
  5. Widok na pierwszym planie strony, w tym przypadku logo. Ten widok jest zawsze renderowany przed wszystkimi innymi widokami na stronie. Ten widok jest opcjonalny.

Inicjuj informacje o stronie podczas tworzenia elementu OnboardingSupportFragment lub dołączania do aktywności nadrzędnej, ponieważ system żąda informacji o stronie podczas tworzenia widoku fragmentu. Informacje o stronie możesz zainicjować w konstruktorze klas lub w zastąpieniu reguły onAttach().

Zastąp każdą z tych metod, które przekazują systemowi informacje o stronie:

Zastąp każdą z tych metod, aby udostępnić opcjonalne widoki podrzędne do wyświetlania obrazów lub animacji:

  • onCreateBackgroundView() zwraca obiekt View utworzony przez Ciebie, który ma działać jako widok tła, lub wartość null, jeśli widok tła nie jest potrzebny.
  • onCreateContentView() zwraca obiekt View utworzony przez Ciebie, który ma działać jako wyświetlenie treści, lub wartość null, jeśli wyświetlenie treści nie jest potrzebne.
  • onCreateForegroundView() zwraca obiekt View, który został utworzony, aby działać jako widok na pierwszym planie, lub wartość null, jeśli nie jest potrzebny żaden widok na pierwszym planie.

System doda utworzony przez Ciebie obiekt View do układu strony. Ten przykład zastępuje zmienną onCreateContentView() i zwraca ImageView:

Kotlin

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

Dodaj początkowy ekran z logo

OnboardingSupportFragment może zacząć od opcjonalnego ekranu z logo, który przedstawia Twoją aplikację. Jeśli chcesz wyświetlać Drawable jako ekran z logo, wywołaj setLogoResourceId() z identyfikatorem Drawable w metodzie onCreate() w OnboardingSupportFragment. System zanika i na chwilę pojawia się Drawable, a następnie zanikanie Drawable przed wyświetleniem pierwszej strony komponentu OnboardingSupportFragment.

Jeśli chcesz utworzyć niestandardową animację na ekranie z logo, zamiast wywoływać setLogoResourceId(), zastąp onCreateLogoAnimation() i zwracaj obiekt Animator, który renderuje Twoją animację niestandardową, jak w tym przykładzie:

Kotlin

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

Dostosuj animacje na stronie

System używa animacji domyślnych, gdy wyświetla się pierwsza strona atrybutu OnboardingSupportFragment i gdy użytkownik przechodzi na inną stronę. Możesz dostosować te animacje, zastępując metody w OnboardingSupportFragment.

Aby dostosować animację, która pojawi się na pierwszej stronie, zastąp onCreateEnterAnimation() i zwróć Animator. Ten przykładowy element tworzy obiekt Animator, który skaluje widok treści w poziomie:

Kotlin

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

Aby dostosować animację używaną, gdy użytkownik przechodzi na inną stronę, zastąp parametr onPageChanged(). W metodzie onPageChanged() utwórz obiekty Animator, które usuwają poprzednią stronę i wyświetlają następną stronę, dodaj je do AnimatorSet i odtwórz zestaw. W tym przykładzie użyto animacji zanikania, aby usunąć poprzednią stronę, zaktualizować obraz widoku treści, a następną stronę wyświetlić za pomocą animacji zanikania:

Kotlin

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

Więcej informacji o tworzeniu obiektów Animator i AnimatorSet znajdziesz w opisie animacji właściwości.

Dostosuj motywy

W każdej implementacji OnboardingSupportFragment musi być używany motyw Theme_Leanback_Onboarding lub motyw dziedziczony z elementu Theme_Leanback_Onboarding. Ustaw motyw dla panelu OnboardingSupportFragment, wykonując jedną z tych czynności:

  • Ustaw aktywność nadrzędną elementu OnboardingSupportFragment tak, aby wykorzystywała odpowiedni motyw. Ten przykład pokazuje, jak skonfigurować aktywność, aby używać w manifeście aplikacji Theme_Leanback_Onboarding:
    <activity
       android:name=".OnboardingActivity"
       android:enabled="true"
       android:exported="true"
       android:theme="@style/Theme.Leanback.Onboarding">
    </activity>
    
  • Ustaw motyw w aktywności nadrzędnej, używając atrybutu LeanbackOnboardingTheme_onboardingTheme w niestandardowym motywie aktywności. Przypisz ten atrybut do innego motywu niestandardowego, z którego korzystają tylko obiekty OnboardingSupportFragment w Twojej aktywności. Skorzystaj z tej metody, jeśli Twoja aktywność używa już motywu niestandardowego i nie chcesz stosować stylów OnboardingSupportFragment do innych widoków w tej aktywności.
  • Zastąp onProvideTheme() i zwróć wybrany motyw. Zastosuj tę metodę, jeśli wiele aktywności korzysta z Twojego elementu (OnboardingSupportFragment) lub gdy aktywność nadrzędna nie może wykorzystywać wybranego motywu. Ten przykład zastępuje zmienną onProvideTheme() i zwraca Theme_Leanback_Onboarding:

    Kotlin

    override fun onProvideTheme(): Int = R.style.Theme_Leanback_Onboarding
    

    Java

    @Override
    public int onProvideTheme() {
       return R.style.Theme_Leanback_Onboarding;
    }