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

このトピックでは、階層内の Preferences をカスタマイズする方法について説明します。

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 の表示を制御する

ユーザーが設定画面に移動したときに表示される Preferences を制御できます。たとえば特定の 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 では現在選択されているリストエントリを表示する必要があります。また、Preferences では、アプリの内部または外部の状態に基づいてサマリーの更新が必要になることがあります(バージョン番号を表示する Preference など)。サマリーの更新には、SummaryProvider を使用します。

SimpleSummaryProvider を使用する

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

これらの実装を有効にするには、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 があるとします。

<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 (TextUtils.isEmpty(text)) {
        "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)){
                return "Not set";
            }
            return "Length of saved value: " + text.length();
        }
    });
}

これで Preference のサマリーに、保存されている値の長さが表示されます。保存されている値が存在しない場合は「Not set」と表示されます。

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

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

たとえば、数字のみを入力できるようにダイアログをカスタマイズできます。まず、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 に追加するには、IntentPreference に直接設定するか、より具体的なロジック用の OnPreferenceClickListener を設定します。

Intent を設定する

IntentPreference に設定すると、Preference がタップされたときに新しい FragmentActivity、または別のアプリを起動できます。これは、特定の Intent を指定して Context.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 とともに extra を含めることもできます。

<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")
webpagePreference.setIntent(intent)

Java

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

OnPreferenceClickListener

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

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

Kotlin

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

Java

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