自訂設定 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,請先在 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 包含簡單的 SummaryProvider 實作,其自動顯示儲存的 Preference 值做為摘要。如未儲存任何值,則會顯示「未設定」。

如要透過 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 上設定 Intent,也可以設定 OnPreferenceClickListener 以取得更多特定的邏輯。

設定意圖

您可以在 Preference 上設定 Intent,以便在輕觸 Preference 時啟動新的 FragmentActivity 或獨立應用程式。這與使用具有指定 IntentContext.startActivity() 相同。

您可以使用巢狀 <intent> 標記在 XML 中設定 Intent。以下範例定義可啟動 ActivityIntent

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

也可以直接在 Preference 上使用 setIntent(),如下所示:

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>

以下是具有 IntentPreference 範例,其可啟動網頁:

<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

您可以在 Preference 上設定 OnPreferenceClickListener,以便在輕觸 Preference 時新增對 onPreferenceClick() 的回呼。舉例來說,如果處理導覽的邏輯更複雜,您可以使用事件監聽器前往另一個 FragmentActivity

如要設定 OnPreferenceClickListener,可以使用類似於以下內容的程式碼:

Kotlin

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

Java

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