Apresentar novos usuários ao seu app

Criar da melhor forma com o Compose
Crie interfaces bonitas com o mínimo de código usando o Jetpack Compose para Android TV OS.

Para mostrar a um novo usuário como aproveitar ao máximo seu app, apresente informações de integração na inicialização do app. Confira alguns exemplos de informações de integração:

  • Apresente informações detalhadas sobre os canais disponíveis quando o usuário acessar um app do canal pela primeira vez.
  • Chame atenção para recursos interessantes do app.
  • Ilustre qualquer etapa obrigatória ou recomendada que os usuários precisam seguir ao usar o app pela primeira vez.

A biblioteca androidx.leanback oferece a classe OnboardingSupportFragment para apresentar informações a novos usuários. Este guia descreve como usar a classe OnboardingSupportFragment para apresentar informações introdutórias que são mostradas quando o app é iniciado pela primeira vez.

O OnboardingSupportFragment usa as práticas recomendadas da IU da TV para apresentar as informações de maneira correspondente aos estilos dessa IU e facilitando a navegação nos dispositivos de TV.

Figura 1. Por exemplo, OnboardingSupportFragment.

O OnboardingSupportFragment não é adequado para todos os casos de uso. Não use OnboardingSupportFragment quando precisar incluir elementos de interface que precisam de entrada do usuário, como botões e campos. Além disso, não use OnboardingSupportFragment para tarefas que o usuário vai realizar regularmente. Por fim, se você precisar apresentar uma interface de várias páginas que requer entrada do usuário, use um GuidedStepSupportFragment.

Adicionar um OnboardingSupportFragment

Para adicionar um OnboardingSupportFragment ao app, implemente uma classe que estenda a classe OnboardingSupportFragment. Adicione esse fragmento a uma atividade usando o XML de layout dela ou de forma programática. Verifique se a atividade ou o fragmento usa um tema derivado de Theme_Leanback_Onboarding, conforme descrito na seção Personalizar temas.

No método onCreate() da atividade principal do app, chame startActivity() com um Intent que aponte para a atividade pai do seu OnboardingSupportFragment. Isso garante que o OnboardingSupportFragment apareça assim que o app é iniciado.

Para garantir que o OnboardingSupportFragment só apareça na primeira vez que o usuário iniciar o app, use um objeto SharedPreferences para rastrear se o usuário já visualizou o OnboardingSupportFragment. Defina um valor booleano que mude para "true" quando o usuário terminar de visualizar o OnboardingSupportFragment. Verifique esse valor no método onCreate() da atividade principal e só inicie a atividade pai do OnboardingSupportFragment se o valor for "false".

O exemplo a seguir mostra uma modificação de onCreate(), que verifica se há um valor de SharedPreferences e, caso ele não esteja definido como "true", chama startActivity() para mostrar o 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));
    }
}

Depois que o usuário visualizar o OnboardingSupportFragment, marque-o como "visualizado" usando o objeto SharedPreferences. Para fazer isso, substitua onFinishFragment() no OnboardingSupportFragment e defina o valor SharedPreferences como "true", conforme mostrado no exemplo a seguir:

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

Adicionar páginas de OnboardingSupportFragment

Um OnboardingSupportFragment mostra conteúdo em uma série de páginas ordenadas. Depois de adicionar seu OnboardingSupportFragment, você precisa definir as páginas de integração. Cada página tem um título, uma descrição e diversas subvisualizações que podem conter imagens ou animações.

Figura 2. OnboardingSupportFragment elementos de página.

A figura 2 mostra um exemplo de página com frases de destaque que marcam elementos de página personalizáveis que o OnboardingSupportFragment pode fornecer. Os elementos de página são:

  1. Título da página.
  2. Descrição da página.
  3. Visualização do conteúdo da página. Nesse caso, uma simples marca verde de verificação em uma caixa cinza. Ela é opcional. Use essa visualização para ilustrar detalhes da página. Por exemplo, você pode incluir uma captura de tela que destaca o recurso do app que a página descreve.
  4. Visualização do plano de fundo da página. Nesse caso, um simples gradiente azul. Essa visualização é sempre renderizada atrás de outras visualizações na página. Ela é opcional.
  5. Primeiro plano da página. Nesse caso, um logotipo. Essa visualização é sempre renderizada na frente de todas as outras visualizações na página. Ela é opcional.

Inicialize as informações da página quando seu OnboardingSupportFragment for criado ou relacionado à atividade principal, já que o sistema solicita informações da página quando cria a visualização do fragmento. Você pode inicializar as informações da página no construtor de classe ou em uma modificação de onAttach().

Substitua cada um dos métodos a seguir, que fornecem informações da página para o sistema:

Substitua cada um dos métodos a seguir para fornecer subvisualizações opcionais para mostrar imagens ou animações:

  • onCreateBackgroundView() retorna uma View que você cria para servir como a visualização em segundo plano ou nulo se nenhuma visualização em segundo plano for necessária.
  • onCreateContentView() retorna uma View que você cria para servir como a visualização de conteúdo ou nulo se nenhuma visualização de conteúdo for necessária.
  • onCreateForegroundView() retorna uma View que você cria para servir como a visualização em primeiro plano ou nulo se nenhuma visualização em primeiro plano for necessária.

O sistema adiciona a View criada por você ao layout da página. O exemplo a seguir modifica onCreateContentView() e retorna um 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;
}

Adicionar uma tela inicial com logotipo

Seu OnboardingSupportFragment pode começar com uma tela opcional com logotipo que introduz seu app. Se você quiser exibir um Drawable como sua tela com logotipo, chame setLogoResourceId() com o ID do seu Drawable no método onCreate() do seu OnboardingSupportFragment. O sistema esmaece e exibe brevemente o Drawable. Depois disso, o Drawable esmaece antes de exibir a primeira página do seu OnboardingSupportFragment.

Se quiser fornecer uma animação personalizada para sua tela com logotipo, em vez de chamar setLogoResourceId(), modifique onCreateLogoAnimation() e retorne um objeto Animator que renderize sua animação personalizada, conforme mostrado no exemplo a seguir:

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

Personalizar animações de páginas

O sistema usa animações padrão ao exibir a primeira página do seu OnboardingSupportFragment e quando o usuário navega para outra página. Você pode personalizar essas animações modificando métodos no seu OnboardingSupportFragment.

Para personalizar a animação que aparece na primeira página, modifique onCreateEnterAnimation() e retorne um Animator. O exemplo a seguir cria uma Animator que dimensiona a visualização de conteúdo horizontalmente:

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

Para personalizar a animação usada quando o usuário navega para outra página, modifique onPageChanged(). No seu método onPageChanged(), crie objetos Animator que removam a página anterior e exibam a página seguinte, adicione-os a um AnimatorSet e execute a configuração. O exemplo a seguir usa uma animação de esmaecimento para remover a página anterior, atualiza a imagem de visualização do conteúdo e usa uma animação de esmaecimento para exibir a página seguinte:

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

Para mais detalhes sobre como criar objetos Animator e AnimatorSet, consulte Visão geral da animação de propriedade.

Personalizar temas

Qualquer implementação OnboardingSupportFragment precisa usar o tema Theme_Leanback_Onboarding ou um tema herdado de Theme_Leanback_Onboarding. Configure o tema para seu OnboardingSupportFragment seguindo uma das etapas a seguir:

  • Configure a atividade pai do OnboardingSupportFragment para usar o tema desejado. O exemplo a seguir mostra como configurar uma atividade para que ela use Theme_Leanback_Onboarding no manifesto do app:
    <activity
       android:name=".OnboardingActivity"
       android:enabled="true"
       android:exported="true"
       android:theme="@style/Theme.Leanback.Onboarding">
    </activity>
  • Configure o tema na atividade pai usando o atributo LeanbackOnboardingTheme_onboardingTheme em um tema personalizado de atividade. Aponte esse atributo para outro tema personalizado usado apenas pelos objetos OnboardingSupportFragment da sua atividade. Escolha essa abordagem se sua atividade já usa um tema personalizado e você não quer aplicar estilos OnboardingSupportFragment a outras visualizações na atividade.
  • Modifique onProvideTheme() e retorne o tema escolhido. Escolha essa abordagem se várias atividades usam seu OnboardingSupportFragment ou se a atividade pai não pode usar o tema desejado. O exemplo a seguir substitui onProvideTheme() e retorna Theme_Leanback_Onboarding:

    Kotlin

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

    Java

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