【问题标题】:ListPreference's summary text is not updated automatically whenever there is change in selectionListPreference's summary text is not updated automatically whenever there is change in selection
【发布时间】:2012-04-12 08:15:51
【问题描述】:

虽然它正在被记录,但通过使用"%s",我可以将所选值显示为摘要,但它不能按预期工作。

http://developer.android.com/reference/android/preference/ListPreference.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 代码构建一个完整的首选项活动,带有复选框和列表首选项,每当我执行选择时,列表首选项的摘要文本可以自动更新。摘要文本将在 Display value 0Display value 1 之间切换。

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

但是,我意识到列表首选项的摘要文本不会自动更新。只有当我对复选框执行勾选/取消勾选时,只有整个活动才会失效,并且列表首选项的摘要文本只会被更新。

因此,我必须修改我的代码如下,这看起来更麻烦

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);
            }
        }
    }
}

这是正确的方法吗?是否有任何简化的方法来确保 ListPreference 的摘要文本在选择发生变化时始终自动更新。

【问题讨论】:

标签: android


【解决方案1】:

这是在 KITKAT 之前的平台(即 android-4.4_r0.7)上存在的错误,已通过提交 94c02a1 修复

@ilomambo 的解决方案有效,但可能不是最好的。我通读了ListPreference 的来源并想出了这个解决方案:

文件: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 work around 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();
            }
        }
    }
}

当您需要在xml中使用ListPreference时,只需将标签替换为com.example.yourapplication.ListPreferenceCompat即可。

这在我运行 Android 4.3 的三星 S4 设备上以及在我的一个生产应用程序中运行良好。

【讨论】:

  • 谢谢,你为我省去了很多无聊的东西!!
【解决方案2】:

我猜这是某种奇怪的错误,因为我已经在运行 Android 2.3.3 的模拟器上对其进行了测试,但它不起作用,但是当我在 4.0 上进行测试时.3 它奏效了。我所做的是 ListPreference 的 xml 中的 android:summary="%s",仅此而已。

【讨论】:

  • 这不是错误。这是 api 级别 15(或者可能是 14)中添加的功能。
  • 感谢@Waqas 指出这一点,一周前,我在谷歌上搜索了一个更复杂的答案,其中必须附加一个侦听器,并且以编程方式访问摘要以执行相同的操作。
【解决方案3】:

恕我直言,这是一个错误。 ListPreference.java#builder.setSingleChoiceItems()中定义的onClickListener()不会调用notifyChanged()

我碰巧正在根据该代码编写自己的 ListPreference,并遇到与 OP 相同的问题,我添加了 notifyChanged()

            ...
            dialog.dismiss();
            notifyChanged(); // <<<<<<<<<<
        }
});

现在首选项摘要在我选择后立即更新。 它不依赖于Android版本,ListPreference一直都是这样编码的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    相关资源
    最近更新 更多