每当有变化,选择列表preference的摘要文本不会自动更新自动更新、摘要、文本、列表

2023-09-05 02:30:19 作者:醒着做梦

虽然它被记录在案,通过使用%的,我可以显示所选的值作为总结,但它无法正常工作。

Although it is being documented, by using "%s", I can display selected value as summary, it doesn't work as expected.

http://developer.android.com/reference/android/$p$pference/List$p$pference.html#getSummary%28%29

我有以下 preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/preference_xxx_category">
        <CheckBoxPreference
            android:title="@string/preference_xxx_mode_title"
            android:defaultValue="false"
            android:summary="@string/preference_xxx_mode_summary"
            android:key="xxxModePreference" />
    </PreferenceCategory>

    <PreferenceCategory
        android:title="@string/preference_yyy_category">
        <ListPreference
           android:title="@string/preference_yyy_mode_title"
           android:defaultValue="0"
           android:entries="@array/yyy"
           android:entryValues="@array/yyy_values"
           android:summary="%s"
           android:key="yyyModePreference" />         
    </PreferenceCategory>

</PreferenceScreen>

和这里是我的 arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="yyy">
        <item>Display value 0</item>
        <item>Display value 1</item>
    </string-array>

    <string-array name="yyy_values">
        <item>0</item>
        <item>1</item>
    </string-array>    
</resources>

我希望通过具有以下Java code构建一个完整的preference活动,以检查框和列表preference,列表preference摘要文本可以自动更新,每当我完成选择。摘要文本将在切换的显示值在0 和显示值1

public class Preferences extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}

不过,我意识到摘要文本列表preference不会自动更新。只有当我在复选框进行打勾/勾去掉,只能是整个活动将是无效和摘要文本列表preference时,才会更新。

However, I realize the summary text for list preference will not update automatically. Only when I perform tick/ untick on check box, only the whole activity will be invalidate and summary text for list preference will ONLY be updated.

因此​​,我不得不修改我的code如下,它看起来繁琐

Hence, I have to revise my code as follow, which looks more cumbersome.

public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onResume() {
        super.onResume();

        // Cumbersome way to make sure list preference's summary text is being updated.
        final String key = "yyyModePreference";
        ListPreference listPreference = (ListPreference)findPreference(key);
        final String value = PreferenceManager.getDefaultSharedPreferences(this).getString(key, key);
        final int index = listPreference.findIndexOfValue(value);
        if (index >= 0) {
            final String summary = (String)listPreference.getEntries()[index];         
            listPreference.setSummary(summary);
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences options, String key) {
        // Cumbersome way to make sure list preference's summary text is being updated.
        if (key.equals("yyyModePreference")) {
            ListPreference listPreference = (ListPreference)findPreference(key);
            final String value = options.getString(key, key);
            final int index = listPreference.findIndexOfValue(value);            
            if (index >= 0) {
                final String summary = (String)listPreference.getEntries()[index];         
                listPreference.setSummary(summary);
            }
        }
    }
}

这是一个正确的方法是什么?有没有什么简单的办法,以确保列表preference的摘要文本总是自动更新每当有变化的选择。

Is this a correct way? Is there any simplified way, to ensure ListPreference's summary text is always updated automatically whenever there is change in selection.

推荐答案

这是之前的奇巧(即Android的4.4_r0.7)存在于平台中的错误,而且是固定的承诺94c02a1

This is a bug that existed on platforms prior to KITKAT (i.e. android-4.4_r0.7), and it is fixed by commit 94c02a1

从@ilomambo工作,但未必是最好的解决方案。我通读目录preference 源,并提出了该解决方案:

The solution from @ilomambo works, but may not be the best one. I read through the source of ListPreference and came up with this solution:

文件:列表preferenceCompat.java

File: ListPreferenceCompat.java

package com.example.yourapplication;

import android.content.Context;
import android.os.Build;
import android.preference.ListPreference;
import android.text.TextUtils;
import android.util.AttributeSet;

public class ListPreferenceCompat extends ListPreference {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public ListPreferenceCompat(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListPreferenceCompat(Context context) {
        super(context);
    }

    // NOTE:
    // The framework forgot to call notifyChanged() in setValue() on previous versions of android.
    // This bug has been fixed in android-4.4_r0.7.
    // Commit: platform/frameworks/base/+/94c02a1a1a6d7e6900e5a459e9cc699b9510e5a2
    // Time: Tue Jul 23 14:43:37 2013 -0700
    //
    // However on previous versions, we have to workaround it by ourselves.
    @Override
    public void setValue(String value) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            super.setValue(value);
        } else {
            String oldValue = getValue();
            super.setValue(value);
            if (!TextUtils.equals(value, oldValue)) {
                notifyChanged();
            }
        }
    }
}

当你需要使用目录preference 在XML中,只需更换标签 com.example.yourapplication.List preferenceCompat

When you need to use ListPreference in xml, simply replace the tag to com.example.yourapplication.ListPreferenceCompat.

本作品整齐我运行的是Android 4.3三星S4设备上了,里面我的一个生产应用程序。

This works neatly on my Samsung S4 device running Android 4.3, and inside one of my production app.