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. Veja 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 Leanback androidx oferece a classe OnboardingSupportFragment para apresentar informações a novos usuários. Esta lição descreve como usar a classe OnboardingSupportFragment para mostrar informações introdutórias, que são exibidas 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. Exemplo de um OnboardingSupportFragment.

Seu OnboardingSupportFragment não pode conter elementos de IU que precisam de entrada do usuário, como botões e campos. Da mesma forma, ele não pode ser usado como um elemento de IU para uma tarefa que o usuário realizará regularmente. Caso você precise apresentar uma IU 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 por meio do XML de layout dela ou programaticamente. Verifique se a atividade ou o fragmento usa um tema derivado de Theme_Leanback_Onboarding, conforme descrito em 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's. Isso garante que o OnboardingSupportFragment apareça assim que o app é inicializado.

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 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 exibir 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, no OnboardingSupportFragment, modifique onFinishFragment() e configure 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

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

Figura 2. Elementos da página do OnboardingFragment.

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. Essa visualização é opcional. Use-a para ilustrar detalhes da página, como 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 pai pela primeira vez, 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().

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

Modifique cada um dos métodos a seguir para oferecer subvisualizações opcionais usadas para exibir imagens ou animações:

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

O sistema adiciona a View criada por você ao layout da página. O exemplo a seguir modifica onCreateContentView() e retorna uma 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, no método OnboardingSupportFragment's do seu onCreate(), chame setLogoResourceId() com o código do seu Drawable. O sistema esmaecerá e exibirá rapidamente esse Drawable. Depois disso, o Drawable esmaecerá 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 Animators 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 used to fade out previousPage and, once
        // done, swaps 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 used to fade in nextPage
        val fadeIn = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 0.0f, 1.0f)
                .setDuration(ANIMATION_DURATION)
        // Create AnimatorSet with our 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 used to fade out previousPage and, once
        // done, swaps 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 used to fade in nextPage
        Animator fadeIn = ObjectAnimator.ofFloat(mContentView,
                View.ALPHA, 0.0f, 1.0f).setDuration(ANIMATION_DURATION);
        // Create AnimatorSet with our 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 Animators e AnimatorSets, consulte Animações 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 OnboardingSupportFragment's para usar o tema escolhido. 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 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;
        }