2

我正在扩展PreferenceActivity我的设置屏幕。在这个偏好活动中,我有几个偏好,其中一个是定制的。问题如下:

在这个自定义首选项(从 扩展ListPreference)中,我希望能够设置默认值,所以我覆盖了该setDefaultValue()方法。在这种方法中,我做了一些解析,所以它会采用正确的值。当我试图用getValue()它返回的函数读取这个值时null

所以我想,当我把一些硬编码的值放在那里时会发生什么(你知道,也许我做错了什么,这不是第一次)。好吧,我还是null回来了。

任何想法我做错了什么?

编辑:
在 xml 文件中设置 defaultValue 并不是一个真正的选项,因为在我检索它们之前这些值是未知的。

我做了一个解决方法:

  • 首次启动应用时:获取数据
  • 在首选项中设置值。

这样我在收集数据时设置默认首选项

4

7 回答 7

5

我终于找到了解决方案(除了 StackOverflow,一次)。

当您创建自定义 Preference 类时,

  1. 您需要onSetInitialValue按照XåpplI'-I0llwlg'I 的方式实施 -指出
  2. 需要实施onGetDefaultValue(TypedArray a, int index)

例如,如果自定义首选项保存为 int,

@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
    setValue(restore ? getPersistedInt(FALLBACK_DEFAULT_VALUE) : (Integer) defaultValue);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
   return a.getInteger(index, FALLBACK_DEFAULT_VALUE);
}

现在PreferenceManager.setDefaultValues() 终于也加载了android:defaultValue自定义首选项。仍然无法修复 null 和 false,但是对于在其他地方发布的那些有解决方法。

于 2014-08-31T01:43:29.300 回答
2

如果您想在第一次打开 PreferenceActivity 时getValue()调用以检索默认值,则需要在您的 Preference 子类中覆盖。否则,调用时不会设置默认值,它会返回一个(如您所见)。setDefaultValue()onSetInitialValue()getValue()null

例如,如果你的默认值是一个整数,你onSetInitialValue()可能看起来像这样:

@Override
protected void onSetInitialValue(boolean restore, Object defaultValue)
{
    setValue(restore ? getPersistedInt(DEFAULT_VALUE) : (Integer) defaultValue);
}

DEFAULT_VALUE只是 Preference 中的一个私有常量,以防无法检索到持久化的 int。setValue()是补充你的getValue()公共吸气剂的公共二传手,应该是这样的:

public int getValue()
{
    return mValue;
}

public void setValue(int value)
{
    if (value != mValue)
    {
        mValue = value;
        persistInt(value);
    }
}

有关更多信息,请参阅此处onSetInitialValue()的 API 文档。

查看 Preference 类的源代码(此处)以了解为什么onSetInitialValue()需要实现也是一个好主意。尤其是先看setDefaultValue(),再看dispatchSetInitialValue()

于 2013-01-04T17:19:59.893 回答
1

setDefaultValue不像你想象的那样工作。看看源码_Preference.java你就会明白这一切背后的逻辑。

设置默认值的首选方法是在应用程序android:defaultValue的文件中指定属性。preferences.xml

于 2011-02-03T13:30:39.787 回答
1

我将偏好转换.xml为代码。所有setDefaultValues 在那里工作得很好。

val screen = preferenceManager.createPreferenceScreen(context)

val editText = EditTextPreference(context).apply {
         setIcon(R.drawable.lobat_cloud)
         key = "key"
         title = "MyPreferences"
         ...

         setDefaultValue("My Default Value")
      }

screen.addPreference(editText)

// add other preferences

preferenceScreen = screen

更多信息

PS:我发现这种方式比自定义所有偏好或其他答案更小更清晰。

于 2021-05-29T17:30:44.703 回答
0

您可以在构造过程中扩展首选项并设置默认值,如下所示:

package com.example.package.preference;

public class CustomPreference extends ListPreference{

public CustomPreference(Context context) {
    super(context);
    init();
}

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

private void init() {
    Object anyDefaultValueFromCode = ...
    setDefaultValue(anyDefaultValueFromCode );
}
}

然后你可以像这样从 XML 中使用它:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="alarm_prefs_screen"
android:title="@string/set_alarm" >

<com.example.package.preference.CustomPreference
    android:key="custom_preference"
    android:title="@string/any_title" />

</PreferenceScreen>
于 2013-06-13T09:33:17.580 回答
0

这就是我所做并为我工作的:

class DefaultValueEditTextPreference : androidx.preference.EditTextPreference {
    @Suppress("unused")
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
    @Suppress("unused")
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    @Suppress("unused")
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    @Suppress("unused")
    constructor(context: Context?) : super(context)

    init {
        text = ... //the default, dynamic text that you want to have
    }

}
于 2020-12-16T11:26:11.567 回答
-1

我认为这在任何时候也有效。

 Preference aaa = (Preference) findPreference("xxx");
 aaa.setOnPreferenceClickListener(new OnPreferenceClickListener() {

              public boolean onPreferenceClick(Preference preference) {

                    // For edit text preference
                    ((EditTextPreference)preference).getEditText().setText("foobar");


                    // for list preference
                    (ListPreference)preference).setValue("foobar");

                    // etc ...

            return true;
              }
 });

此代码将检测对话框何时即将启动并使用您的默认值填充对话框中的 EditText 或 List。

于 2011-12-17T19:32:41.153 回答