Reputation: 1733
I'm extending PreferenceActivity
for my settings screen. In this preference activity i have a couple of preferences one of which is custom made. The problem is as follows:
in this custom preference (which extends from ListPreference
) i want to be able to set the default value, so i override the setDefaultValue()
method. In this method i do some parsing so it'll take the correct value. When i'm trying to read this value with the getValue()
function it just returns null
.
So i figured, what happens when i just put some hardcoded value in there (you know, maybe i did something wrong, wouldn't be the first time). Well, i still get null
back.
Any ideas what i'm doing wrong?
Edit:
Setting the defaultValue in the xml file isn't really an option because the values aren't known until i retrieve them.
I made a workaround:
This way i set the default preference when i'm collection the data
Upvotes: 3
Views: 7654
Reputation: 5744
I converted preferences .xml
to code. All setDefaultValue
s works well there.
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
P.S: I found this way more smaller and clear than customizing all preferences or other answers.
Upvotes: 1
Reputation: 116040
This is what I did and worked for me:
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
}
}
Upvotes: 0
Reputation: 1677
I finally found the solution (somewhere besides StackOverflow, for once).
When you create a custom Preference class,
onSetInitialValue
as XåpplI'-I0llwlg'I - pointed outonGetDefaultValue(TypedArray a, int index)
For example, if the custom preference is saved as an 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);
}
Now PreferenceManager.setDefaultValues()
finally loads the android:defaultValue
for the custom preferences too. Still no fix for nulls and false, but there are workarounds for those posted elsewhere.
Upvotes: 5
Reputation: 10765
You can extend preference and set the default value during constructing like this:
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 );
}
}
then you can use it from XML like this:
<?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>
Upvotes: 0
Reputation: 22404
If you want to call getValue()
after calling setDefaultValue()
to retrieve a default value the first time your PreferenceActivity opens, you need to override onSetInitialValue()
in your Preference subclass. Otherwise, the default value will not be set when you call getValue()
and it will return a null
(as you experienced).
For example, if your default value is an integer, your onSetInitialValue()
might look like this:
@Override
protected void onSetInitialValue(boolean restore, Object defaultValue)
{
setValue(restore ? getPersistedInt(DEFAULT_VALUE) : (Integer) defaultValue);
}
DEFAULT_VALUE
is just a private constant inside the Preference to be used in case the persisted int cannot be retrieved. setValue()
is the public setter to complement your getValue()
public getter, and should look something like this:
public int getValue()
{
return mValue;
}
public void setValue(int value)
{
if (value != mValue)
{
mValue = value;
persistInt(value);
}
}
For more information about onSetInitialValue()
, refer to the API documentation here.
It's also a good idea to look at the source code of the Preference class (here) to understand why onSetInitialValue()
needs to be implemented. In particular, have a look at setDefaultValue()
, and then look at dispatchSetInitialValue()
.
Upvotes: 2
Reputation: 6104
setDefaultValue
doesn't work the way you think it does. Look at the source of Preference.java
and you'll the logic behind it all.
The preferred way to set a default is to specify the android:defaultValue
attribute in the preferences.xml
file of your app.
Upvotes: 1
Reputation: 148
I think this works too at anytime.
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;
}
});
This code will detect when the dialog is about to launch and populate the EditText or List in the dialog with your default value.
Upvotes: -1