設定をカスタマイズする Android Jetpack の一部。

このドキュメントでは、階層内の Preference オブジェクトをカスタマイズする方法について説明します。

設定を確認する

Preference 値の取得や設定を行う場合など、個々の Preference にアクセスするには、PreferenceFragmentCompat.findPreference() を使用します。このメソッドは、特定のキーが設定された Preference を階層全体から検索します。

たとえば、キー "signature"EditTextPreference にアクセスする手順は次のとおりです。

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

次のコードを使用して、この Preference を取得します。

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    val signaturePreference: EditTextPreference? = findPreference("signature")
    // Do something with this preference.
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    EditTextPreference signaturePreference = findPreference("signature");
    // Do something with this preference.
}

Preference の表示を制御する

ユーザーが設定画面に移動したときに表示される Preference オブジェクトを制御できます。たとえば特定の Preference が、対応する機能が有効な場合にのみ意味を持つ場合、その機能が無効な場合にはその Preference を非表示にすることをおすすめします。

条件が満たされた場合にのみ Preference を表示するには、まず、次の例に示すように、XML 内で Preference の公開設定を false に設定します。

<EditTextPreference
        app:key="signature"
        app:title="Your signature"
        app:isPreferenceVisible="false"/>

onCreatePreferences() で、対応する条件が満たされたときに Preference を表示します。

Kotlin

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    if(/*some feature*/) {
        val signaturePreference: EditTextPreference? = findPreference("signature")
        signaturePreference?.isVisible = true
    }
}

Java

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
    if(/*some feature*/) {
        EditTextPreference signaturePreference = findPreference("signature");
        if (signaturePreference != null) {
            signaturePreference.setVisible(true);
        }
    }
}

サマリーを動的に更新する

データを保持する Preference は、ユーザーが Preference の現在の状態をよりよく理解できるように、サマリーに現在の値を表示する必要があります。たとえば、EditTextPreference は保存されたテキスト値を示し、ListPreference は選択されたリストエントリを表示する必要があります。また、アプリの内部または外部の状態に基づいて概要を更新する必要がある Preference オブジェクト(バージョン番号を表示する Preference など)が存在する場合もあります。そのためには、SummaryProvider を使用します。

SimpleSummaryProvider を使用する

ListPreferenceEditTextPreference には、保存されている Preference 値をサマリーとして自動的に表示するシンプルな SummaryProvider の実装が含まれています。値が保存されていない場合は、「未設定」と表示されます。

XML からこれらの実装を有効にするには、app:useSimpleSummaryProvider="true" を設定します。

また、次の例に示すように、コード内で ListPreference.SimpleSummaryProvider.getInstance()EditTextPreference.SimpleSummaryProvider.getInstance() を使用してシンプルな SummaryProvider インスタンスを取得し、Preference にそのインスタンスを設定することもできます。

Kotlin

listPreference.summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()

Java

listPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
editTextPreference.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());

カスタムの SummaryProvider を使用する

独自の SummaryProvider を作成して provideSummary() をオーバーライドすることで、Preference からリクエストされるたびにサマリーをカスタマイズできます。たとえば、次の EditTextPreference は、保存された値の長さをサマリーとして表示します。

EditTextPreference の例を示す画像
図 1. EditTextPreference の例

たとえば、次のような EditTextPreference があるとします。

<EditTextPreference
        app:key="counting"
        app:title="Counting preference"/>

onCreatePreferences() で新しい SummaryProvider を作成し、provideSummary() をオーバーライドして、表示するサマリーを返すことができます。

Kotlin

val countingPreference: EditTextPreference? = findPreference("counting")

countingPreference?.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (text.isNullOrEmpty()) {
        "Not set"
    } else {
        "Length of saved value: " + text.length
    }
}

Java

EditTextPreference countingPreference = findPreference("counting");

if (countingPreference != null) {
    countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
        @Override
        public CharSequence provideSummary(EditTextPreference preference) {
            String text = preference.getText();
            if (TextUtils.isEmpty(text) || text == null){
                return "Not set";
            }
            return "Length of saved value: " + text.length();
        }
    });
}

Preference の概要には、保存した値の長さが表示されます。保存されている値が存在しない場合は、「未設定」と表示されます。

EditTextPreference ダイアログをカスタマイズする

EditTextPreference ダイアログで OnBindEditTextListener をアタッチして、テキスト フィールドの動作をカスタマイズできます。このリスナーは、ユーザーにダイアログが表示されたときに呼び出されます。

たとえば、数字のみを受け入れるようにダイアログをカスタマイズできます。まず、EditTextPreference を作成します。

<EditTextPreference
        app:key="number"
        app:title="Numbers only preference"/>

次に、onCreatePreferences() で新しい OnBindEditTextListener を作成し、onBindEditText() をオーバーライドして、ユーザーに表示される EditText をカスタマイズします。

Kotlin

val numberPreference: EditTextPreference? = findPreference("number")

numberPreference?.setOnBindEditTextListener { editText ->
    editText.inputType = InputType.TYPE_CLASS_NUMBER
}

Java

EditTextPreference numberPreference = findPreference("number");

if (numberPreference != null) {
    numberPreference.setOnBindEditTextListener(
            new EditTextPreference.OnBindEditTextListener() {
                @Override
                public void onBindEditText(@NonNull EditText editText) {
                    editText.setInputType(InputType.TYPE_CLASS_NUMBER);
                }
            });
}

これで、ユーザーにダイアログが表示されると、キーボードが数字のみのモードで開き、EditText に数字のみを入力できるようになりました。

Preference のアクション

Preference には、タップされたときの特定のアクションを設定できます。たとえば、Preference はアプリの別の部分へのリンクとして機能します。Preference にアクションを追加するには、Preference に直接 Intent を設定するか、OnPreferenceClickListener を設定してより具体的なロジックを設定します。

Intent を設定する

PreferenceIntent を設定すると、Preference がタップされるたびに新しい FragmentActivity、または別のアプリを起動できます。これは、特定の IntentContext.startActivity() を使用するのと同じです。

Intent は、XML でネストされた <intent> タグを使用して設定できます。次の例では、Activity を起動する Intent を定義しています。

<Preference
        app:key="activity"
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity"/>
</Preference>

または、次のように、PreferencesetIntent() を直接使用することもできます。

Kotlin

val intent = Intent(context, ExampleActivity::class.java)
activityPreference.setIntent(intent)

Java

Intent intent = new Intent(getContext(), ExampleActivity.class);
activityPreference.setIntent(intent);

また、XML を使用して Intent でエクストラを含めることもできます。

<Preference
        app:key="activity"
        app:title="Launch activity">
    <intent
            android:targetPackage="com.example"
            android:targetClass="com.example.ExampleActivity">
        <extra
                android:name="example_key"
                android:value="example_value"/>
    </intent>
</Preference>

以下に、ウェブページを起動する Intent を含む Preference の例を示します。

<Preference
        app:key="webpage"
        app:title="View webpage">
    <intent
            android:action="android.intent.action.VIEW"
            android:data="http://www.google.com" />
</Preference>

Kotlin

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://www.google.com")

val webpagePreference = findPreference("webpage")
webpagePreference?.intent = intent

Java

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
webpagePreference.setIntent(intent);

OnPreferenceClickListener

PreferenceOnPreferenceClickListener を設定すると、Preference がタップされたときに onPreferenceClick() にコールバックが追加されます。たとえば、ナビゲーションを処理する複雑なロジックがある場合は、リスナーを使用して別の FragmentActivity に移動できます。

OnPreferenceClickListener を設定するには、次のようなコードを使用します。

Kotlin

onClickPreference.setOnPreferenceClickListener({
    // Do something.
    true
})

Java

onClickPreference.setOnPreferenceClickListener(preference -> {
    // Do something.
    return true;
});