初めてのユーザーにアプリを紹介する

Compose を利用して魅力的なアプリを作成する
Android TV OS 向け Jetpack Compose を使用して、最小限のコードで美しい UI を作成します。

初めてのユーザーにアプリを最大限に活用する方法を提示するには、アプリの起動時に導入用の情報を提示します。オンボーディング情報の例を以下に示します。

  • ユーザーが最初にチャンネル アプリにアクセスしたときに、利用可能なチャンネルに関する詳細情報を提示します。
  • アプリの注目機能をアピールします。
  • アプリを初めて使用する際に実行しなければならない手順や、推奨される手順をわかりやすく説明します。

androidx.leanback ライブラリは、初めてのユーザーに情報を提示するための OnboardingSupportFragment クラスを提供します。このガイドでは、OnboardingSupportFragment クラスを使用して、アプリの初回起動時に表示される導入用情報を提供する方法について説明します。

OnboardingSupportFragment は、TV UI に関するベスト プラクティスを活用して、TV UI スタイルにマッチする方法で情報を提示し、TV デバイス上で簡単にアクセスできるようにします。

図 1. 例: OnboardingSupportFragment

OnboardingSupportFragment はすべてのユースケースに適しているわけではありません。ボタンやフィールドなど、ユーザー入力を必要とする UI 要素を含める必要がある場合は、OnboardingSupportFragment を使用しないでください。また、ユーザーが定期的に実行するタスクに OnboardingSupportFragment を使用しないでください。最後に、ユーザー入力が必要なマルチページ UI を表示する必要がある場合は、GuidedStepSupportFragment の使用を検討してください。

OnboardingSupportFragment を追加する

アプリに OnboardingSupportFragment を追加するには、OnboardingSupportFragment クラスを拡張するクラスを実装します。アクティビティのレイアウト XML かプログラムで、このフラグメントをアクティビティに追加します。テーマをカスタマイズするで説明しているように、アクティビティやフラグメントが Theme_Leanback_Onboarding から派生したテーマを使用しているか確認します。

アプリのメイン アクティビティの onCreate() メソッドで、OnboardingSupportFragment の親アクティビティをポイントする Intent を使用して startActivity() を呼び出します。これにより、アプリが起動するとすぐに OnboardingSupportFragment が表示されるようになります。

OnboardingSupportFragment の表示を、ユーザーがアプリを初めて起動したときだけに限定する場合は、SharedPreferences オブジェクトを使用して、ユーザーが OnboardingSupportFragment を表示済みかどうかをトラッキングします。ユーザーが OnboardingSupportFragment の表示を終了すると true に変わるブール値を定義します。メイン アクティビティの onCreate() メソッドでこの値をチェックし、値が false の場合に限り OnboardingSupportFragment 親アクティビティを起動します。

SharedPreferences 値をチェックし、true に設定されていない場合に startActivity() を呼び出して OnboardingSupportFragment を表示する onCreate() のオーバーライドの例を以下に示します。

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

ユーザーが OnboardingSupportFragment を表示したら、SharedPreferences オブジェクトを使用して「表示済み」としてマーキングします。これを行うには、下記の例に示すように、OnboardingSupportFragment 内で onFinishFragment() をオーバーライドし、SharedPreferences 値を true に設定します。

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

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 を返す例を以下に示します。

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

初期ロゴ画面を追加する

OnboardingSupportFragment は、アプリを紹介するオプションのロゴ画面から開始できます。ロゴ画面として Drawable を表示するには、OnboardingSupportFragmentonCreate() メソッドで、Drawable の ID を使用して setLogoResourceId() を呼び出します。システムは、Drawable にフェードインして短時間表示し、Drawable をフェードアウトしてから、OnboardingSupportFragment の最初のページを表示します。

ロゴ画面用にカスタム アニメーションを提供する場合、下記の例に示すように、setLogoResourceId() を呼び出す代わりに onCreateLogoAnimation() をオーバーライドして、カスタム アニメーションをレンダリングする Animator オブジェクトを返します。

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

ページ アニメーションをカスタマイズする

OnboardingSupportFragment の最初のページを表示するときや、ユーザーが別のページに移動したときに、システムはデフォルト アニメーションを使用します。OnboardingSupportFragment のメソッドをオーバーライドすることで、アニメーションをカスタマイズできます。

最初のページに表示されるアニメーションをカスタマイズするには、onCreateEnterAnimation() をオーバーライドして Animator を返します。コンテンツ ビューを水平方向に拡大縮小する Animator を作成する例を以下に示します。

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

ユーザーが別のページに移動するときに使用されるアニメーションをカスタマイズするには、onPageChanged() をオーバーライドします。onPageChanged() メソッド内で、前のページを削除して次のページを表示する Animator オブジェクトを作成し、AnimatorSet に追加して、セットを再生します。フェードアウト アニメーションを使用して前のページを削除し、コンテンツ ビューの画像を更新して、フェードイン アニメーションを使用して次のページを表示する例を以下に示します。

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

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 を返す例を以下に示します。

    Kotlin

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

    Java

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