PreferenceField
This implementation is able to provide a bit more abstraction by requiring a default value.
Creating it is very similar to the creation of the raw one:
val pref /* : PreferenceField<String> */ = sp.getStringField("pref_key", "default_value")
PreferenceField<String> pref = SharedPreferencesUtils.getStringField(sp, "pref_key", "default_value");
Like its raw counterpart it extends BasePreferenceField
, exposing the three already seen properties; the difference is that this time it only implements Field
, making it read-only. The value will be the passed default value when the preference is not present.
But why is it read only? It is because having a default value creates some problems due to the value of the field not being exactly the same as the one shared preferences provide.
For example, if the default value is 10
and someone calls pref.value = 10
, what is the correct behavior? Remove the preference? Set it to 10
? Moreover, given the the lazy nature of fields (i.e. the value doesn't change if it's the same) the value simply wouldn't get saved if the value was already 10
.
In order to modify the value associated with this preference we have two options, exposed through two MutableField
properties:
rawValue
: this field has the same value and behaves exactly has aRawPreferenceField
, i.e. it'snull
when there is no preference set. It is the safest way to change the value, but since its value can benull
it might be a bit of an hassle to manage (for instance, callingincrement()
wouldn't be possible).unsafeMutable
: this field adds the default value into the equation, making it easier to manage, but with more problems: in fact setting a value equal to the default one does not guarantee whether the preference will be saved with that value or if it will remain unset. Please notice that is field is a lazy property, so it's initialized upon the first call. Doing this creates a new mutable field that is a two-way transformation of the raw one, so every time this field changes the value will be saved, regardless if it's a default value or not. So once its created, it will affect your preference.
You can read more about unsafeMutable
behavior in the doc.
//Initially we suppose there is no value in the preferences
val num = sp.getIntField("favorite_number", 73)
num.rawValue.value = 10 //Set favorite number to 10, all OK until here
num.unsafeMutable.increment() //Increments the favorite number to 11, creating the unsafeMutable in the process
//This call now *tries* to remove the preference. The effect is that the preference is removed, the unsafeMutable detects it,
//puts as its value the default one (73) and triggers the change of rawValue to 73, which then sets the preference to 73
num.removePreference()
val num2 = sp.getIntField("favorite_number", 88) //Same preference, different default value
num2.value //Should yield 88, will yield 73
//Initially we suppose there is no value in the preferences
PreferenceField<Int> num = SharedPreferencesUtils.getIntField(sp, "favorite_number", 73);
num.getRawValue().setValue(10); //Set favorite number to 10, all OK until here
IntFieldUtils.increment(num.getUnsafeMutable()); //Increments the favorite number to 11, creating the unsafeMutable in the process
//This call now *tries* to remove the preference. The effect is that the preference is removed, the unsafeMutable detects it,
//puts as its value the default one (73) and triggers the change of rawValue to 73, which then sets the preference to 73
num.removePreference();
PreferenceField<Int> num2 = SharedPreferencesUtils.getIntField(sp, "favorite_number", 88) //Same preference, different default value
num2.getValue() //Should yield 88, will yield 73
//Initially we suppose there is no value in the preferences
val num = sp.getIntField("favorite_number", 73)
num.unsafeMutable.value = 73 //The value was already 73 so the change isn't detected and the value is not actually saved
val num2 = sp.getIntField("favorite_number", 88) //Same preference, different default value
num2.value //Should yield 73, will yield 88
//Initially we suppose there is no value in the preferences
PreferenceField<Int> num = SharedPreferencesUtils.getIntField(sp, "favorite_number", 73);
num.getUnsafeMutable().setValue(73); //The value was already 73 so the change isn't detected and the value is not actually saved
PreferenceField<Int> num2 = SharedPreferencesUtils.getIntField(sp, "favorite_number", 88);
num2.getValue(); //Should yield 73, will yield 88
As on the raw counterparts, we can pass two map transformation functions. The null
rules are the same and the behavior is the same. For more info see the correspondent section.