Apresentar novos usuários ao seu app

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 quais canais estão disponíveis quando um usuário acessa um app de canais pela primeira vez.
  • Chame atenção para recursos interessantes do app.
  • Ilustrar as etapas necessárias ou recomendadas que os usuários podem seguir ao usar o app pela primeira vez.

A Biblioteca Leanback androidx fornece a classe OnboardingSupportFragment para apresentar informações de novos usuários. Este guia descreve como usar a classe OnboardingSupportFragment para apresentar informações introdutórias que são exibidas quando o app é iniciado pela primeira vez.

O OnboardingSupportFragment usa as práticas recomendadas da interface da TV para apresentar informações de uma maneira que corresponda aos estilos dessa interface e seja fácil de navegar em dispositivos de TV.

Figura 1. Exemplo de OnboardingSupportFragment.

OnboardingSupportFragment não é apropriado para todos os casos de uso. Não use OnboardingSupportFragment quando precisar incluir elementos da interface que exigem entrada do usuário, como botões e campos. Além disso, não use OnboardingSupportFragment para tarefas que o usuário realizará regularmente. Por fim, se você precisar apresentar uma interface de várias páginas que exija 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 da atividade ou programaticamente. 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 mãe do OnboardingSupportFragment. Isso ajuda a garantir que o OnboardingSupportFragment apareça assim que o app for iniciado.

Para garantir que o OnboardingSupportFragment apareça apenas 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. Confira esse valor no método onCreate() da atividade principal e inicie a atividade mãe OnboardingSupportFragment apenas se o valor for "false".

O exemplo a seguir mostra uma substituição de onCreate() que verifica se há um valor SharedPreferences e, se ele não estiver definido como verdadeiro, 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 verdadeiro, 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 exibe conteúdo em uma série de páginas ordenadas. Depois de adicionar o OnboardingSupportFragment, você precisa definir as páginas de integração. Cada página pode ter um título, uma descrição e várias subvisualizações que podem conter imagens ou animações.

Figura 2. OnboardingSupportFragment.

A Figura 2 mostra um exemplo com frases de destaque que marcam elementos personalizáveis que o OnboardingSupportFragment pode oferecer. 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 os detalhes da página. Por exemplo, é possível incluir uma captura de tela que destaque o recurso do app descrito na página.
  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 a OnboardingSupportFragment for criada pela primeira vez ou anexada à atividade mãe, 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 substituição de onAttach().

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

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

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

O sistema vai adicionar o View criado 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

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

Se você quiser fornecer uma animação personalizada para a tela do seu logotipo, em vez de chamar setLogoResourceId(), substitua 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 mostrar a primeira página da OnboardingSupportFragment e quando o usuário navega para outra página. Você pode personalizar essas animações substituindo métodos no seu OnboardingSupportFragment.

Para personalizar a animação que aparece na sua primeira página, modifique onCreateEnterAnimation() e retorne um Animator. O exemplo a seguir cria um 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, substitua onPageChanged(). No método onPageChanged(), crie objetos Animator que removam a página anterior e mostrem a próxima, adicione-os a um AnimatorSet e execute o conjunto. O exemplo a seguir usa uma animação de esmaecimento para remover a página anterior, atualiza a imagem de visualização de conteúdo e usa uma animação de esmaecimento para exibir a próxima página:

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 de OnboardingSupportFragment precisa usar o tema Theme_Leanback_Onboarding ou um tema herdado de Theme_Leanback_Onboarding. Defina o tema para o OnboardingSupportFragment seguindo um destes procedimentos:

  • Defina a atividade mãe do OnboardingSupportFragment para usar o tema desejado. O exemplo abaixo mostra como definir uma atividade para usar Theme_Leanback_Onboarding no manifesto do app:
    <activity
       android:name=".OnboardingActivity"
       android:enabled="true"
       android:exported="true"
       android:theme="@style/Theme.Leanback.Onboarding">
    </activity>
    
  • Defina o tema na atividade mãe usando o atributo LeanbackOnboardingTheme_onboardingTheme em um tema de atividade personalizado. Aponte esse atributo para outro tema personalizado usado apenas pelos objetos OnboardingSupportFragment na sua atividade. Escolha essa abordagem se a 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 desejado. Use essa abordagem se várias atividades usarem o OnboardingSupportFragment ou se a atividade mãe não puder usar o tema escolhido. O exemplo a seguir modifica 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;
    }