You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am using the SwitchButton in a subclass of SwitchPreference, and then this preference instance is added with other standard ones (EditTextPreference, Preference,...) in a PreferenceFragment.
My SwitchButton is implemented using a widget layout like this :
The customization of preferences can be a little bit tricky, but I think my implementation is correct. Here is what this CustomSwitchPreference looks like :
publicclassCustomSwitchPreferenceextendsSwitchPreferenceimplementsSwitchButton.OnCheckedChangeListener {
privateSwitchButtonmSwitchButton;
privatebooleanmChecked;
publicCustomSwitchPreference(Contextcontext) {
this(context, null);
}
publicCustomSwitchPreference(Contextcontext, AttributeSetattrs) {
this(context, attrs, 0);
}
publicCustomSwitchPreference(Contextcontext, AttributeSetattrs, intdefStyleAttr) {
super(context, attrs, defStyleAttr);
// Inflate the custom preference layout and its custom widget.setLayoutResource(R.layout.pref_layout);
setWidgetLayoutResource(R.layout.pref_switch_widget);
}
@OverrideprotectedObjectonGetDefaultValue(TypedArraya, intindex) {
booleandefaultValue = a.getBoolean(index, false);
returndefaultValue;
}
@OverrideprotectedvoidonSetInitialValue(booleanrestorePersistedValue, ObjectdefaultValue) {
if (restorePersistedValue) {
// Restore existing statebooleanpersistingCheck = getPersistedBoolean(mChecked);
setChecked(persistingCheck);
} else {
// Set default state from the XML attributesetChecked((Boolean)defaultValue);
}
}
@OverrideprotectedvoidonBindView(Viewview) {
super.onBindView(view);
mSwitchButton = (SwitchButton) view.findViewById(R.id.switch_button);
mSwitchButton.setOnCheckedChangeListener(this);
}
publicbooleanisChecked() {
returnmChecked;
}
publicvoidsetChecked(booleanchecked) {
if (checked != mChecked) {
mChecked = checked;
persistBoolean(mChecked);
notifyChanged();
notifyDependencyChange(mChecked);
}
}
/* * SwitchButton.OnCheckedChangeListener implementation. */@OverridepublicvoidonCheckedChanged(CompoundButtonbuttonView, booleanisChecked) {
if (callChangeListener(isChecked)) {
setChecked(isChecked);
}
}
/* * Preference's lifecycle to save and restore the state. */@OverrideprotectedParcelableonSaveInstanceState() {
finalParcelablesuperState = super.onSaveInstanceState();
// Check whether this Preference is persistent (continually saved).if (isPersistent()) {
// No need to save instance state since it's persistent, use superclass state.returnsuperState;
}
// Create instance of custom BaseSavedStatefinalSavedStatemyState = newSavedState(superState);
// Set the state's value with the class member that holds current setting value.myState.checked = mChecked;
returnmyState;
}
@OverrideprotectedvoidonRestoreInstanceState(Parcelablestate) {
// Check whether we saved the state in onSaveInstanceState.if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save the state, so call superclass.super.onRestoreInstanceState(state);
return;
}
// Cast state to custom BaseSavedState and pass to superclassSavedStatemyState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
// Set this Preference's widget to reflect the restored statesetChecked(myState.checked);
}
/* * Saving and restoring the Preference's state. */privatestaticclassSavedStateextendsBaseSavedState {
// Member that holds the setting's value.booleanchecked;
publicSavedState(ParcelablesuperState) {
super(superState);
}
publicSavedState(Parcelsource) {
super(source);
// Get the current preference's value.checked = (Boolean) source.readValue(getClass().getClassLoader());
}
@OverridepublicvoidwriteToParcel(Parceldest, intflags) {
super.writeToParcel(dest, flags);
// Write the preference's value.dest.writeValue(checked);
}
// Standard creator object using an instance of this class.publicstaticfinalParcelable.Creator<SavedState> CREATOR = newParcelable.Creator<SavedState>() {
publicSavedStatecreateFromParcel(Parcelin) {
returnnewSavedState(in);
}
publicSavedState[] newArray(intsize) {
returnnewSavedState[size];
}
};
}
}
When I test all this in my app, everything is fine only if notifyChanged() and/or notifyDependencyChanged() are not called in method setChecked(boolean checked). If one of these notification methods is called, the SwitchButton starts to misbehave :
if state is changed from true to false, the state changes immediately even if the SwitchButton is set to have an animation during transition.
then if the state is changed from false to true, nothing happens... but in fact, internally, the state has changed.
finally, I have to click one more time on the SwitchButton to see the animation occur (the internal state remain to true).
I have tried many workaround, but cannot find one to fix this.
As the behavior is not the same depending on the state of the SwitchButton, I suspect that internally something is managed differently when the UI of the Preferences objects is updated.
I hope you could have a look at this and try to reproduce the case. Using the SwitchButton in Preferences is something quite normal and natural, but it is then important that the Switch behaves as expected when notifyChanged() or notifyDependencyChanged() are called.
Thanks in advance!
The text was updated successfully, but these errors were encountered:
In complement to the original post, I just want to add that one of the workaround I have tested was to set a PreferenceChangeListener on my instance of the CustomSwitchPreference during the onCreateView() of the PreferenceFragment. This listener will respond to the call to Preference.callChangeListener() during onCheckedChanged().
By doing this, if I omit to call notifyChanged() and notifyDependencyChange(), I still can try to, let's say, change the status of other preferences in the onPreferenceChange() event of the PreferenceChangeListener.
I have tried to do so, to disable some other Preferences. Unfortunately, the SwitchButton misbehave exactly the same way... This is why I suppose that the UI update is involved in the issue.
Hi there,
I am using the SwitchButton in a subclass of SwitchPreference, and then this preference instance is added with other standard ones (EditTextPreference, Preference,...) in a PreferenceFragment.
My SwitchButton is implemented using a widget layout like this :
The customization of preferences can be a little bit tricky, but I think my implementation is correct. Here is what this CustomSwitchPreference looks like :
When I test all this in my app, everything is fine only if
notifyChanged()
and/ornotifyDependencyChanged()
are not called in methodsetChecked(boolean checked)
. If one of these notification methods is called, the SwitchButton starts to misbehave :true
tofalse
, the state changes immediately even if the SwitchButton is set to have an animation during transition.false
totrue
, nothing happens... but in fact, internally, the state has changed.true
).I have tried many workaround, but cannot find one to fix this.
As the behavior is not the same depending on the state of the SwitchButton, I suspect that internally something is managed differently when the UI of the Preferences objects is updated.
I hope you could have a look at this and try to reproduce the case. Using the SwitchButton in Preferences is something quite normal and natural, but it is then important that the Switch behaves as expected when
notifyChanged()
ornotifyDependencyChanged()
are called.Thanks in advance!
The text was updated successfully, but these errors were encountered: