設定を整理する Android Jetpack の一部。

設定画面が大きく複雑になると、ユーザーが変更したい設定を見つけにくい場合があります。Preference ライブラリには、以下の方法で設定画面を適切に整理できます。

Preference のカテゴリ

1 つの画面上に複数の関連する Preference オブジェクトがある場合は、PreferenceCategory を使用してグループ化できます。PreferenceCategory はカテゴリのタイトルを表示し、視覚的にカテゴリを区切ります。

XML で PreferenceCategory を定義するには、次のように Preference タグを PreferenceCategory でラップします。

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        app:key="notifications_category"
        app:title="Notifications">

        <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>

    </PreferenceCategory>

    <PreferenceCategory
        app:key="help_category"
        app:title="Help">

        <Preference
            app:key="feedback"
            app:summary="Report technical issues or suggest new features"
            app:title="Send feedback"/>

    </PreferenceCategory>

</PreferenceScreen>

結果は次のようになります。

好みとカテゴリを示す画像
図 1. カテゴリ内の設定。

階層を複数の画面に分割する

多数の Preference オブジェクトや個別のカテゴリがある場合は、別々の画面に表示できます。各画面は、独自の階層を持つ PreferenceFragmentCompat です。初期画面の Preference オブジェクトは、関連する設定を含むサブ画面にリンクできます。

図 2 は、メッセージ同期という 2 つのカテゴリを含む単純な階層を示しています。

階層を表示した設定画面を示す画像
図 2. 2 つのカテゴリを持つ単純な階層。

図 3 では、同じ設定が複数の画面に分かれています。

複数の画面に分割された階層を示す画像
図 3. 複数の画面に分割された階層。

画面を Preference にリンクするには、XML で app:fragment を宣言するか、Preference.setFragment() を使用します。次の例に示すように、Preference をタップしたら、PreferenceFragmentCompat の完全なパッケージ名を起動します。

<Preference
        app:fragment="com.example.SyncFragment"
        .../>

関連する Fragment を含む Preference をユーザーがタップすると、インターフェース メソッドの PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment() が呼び出されます。このメソッドでは、新しい画面の表示を処理し、周囲の Activity に画面が実装されます。

標準的な実装は次のようになります。

Kotlin

class MyActivity : AppCompatActivity(),
    PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
    ...
    override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
        // Instantiate the new Fragment.
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
                classLoader,
                pref.fragment)
        fragment.arguments = args
        fragment.setTargetFragment(caller, 0)
        // Replace the existing Fragment with the new Fragment.
        supportFragmentManager.beginTransaction()
                .replace(R.id.settings_container, fragment)
                .addToBackStack(null)
                .commit()
        return true
    }
}

Java

public class MyActivity extends AppCompatActivity implements
        PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
    ...
    @Override
    public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
        // Instantiate the new Fragment.
        final Bundle args = pref.getExtras();
        final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate(
                getClassLoader(),
                pref.getFragment());
        fragment.setArguments(args);
        fragment.setTargetFragment(caller, 0);
        // Replace the existing Fragment with the new Fragment.
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.settings_container, fragment)
                .addToBackStack(null)
                .commit();
        return true;
    }
}

PreferenceScreens

ネストされた &lt;PreferenceScreen&gt; を使用して同じ XML リソース内でネストされた階層を宣言することはサポートされなくなりました。代わりに、ネストされた Fragment オブジェクトを使用してください。

別々の Activity を使用する

また、各画面を詳細にカスタマイズする必要がある場合や、画面間で Activity を完全に遷移する場合は、PreferenceFragmentCompat ごとに別々の Activity を使用できます。こうすることで、各 Activity とそれに対応する設定画面を完全にカスタマイズできます。ほとんどのアプリでは、この方法はおすすめしません。代わりに、前述の Fragments を使用してください。

Preference から Activity を起動する方法について詳しくは、設定アクションをご覧ください。