I have a code using SwitchPreference
that used to work with Android 4.x however it no longer works since I updated my device to Android 5.0.1.
I have a simple SwitchPreference
which displays a title on the left and an ON/OFF switch on the right.
<SwitchPreference
android:key="myPref"
android:selectable="true"
android:title="Title"
android:fragment="com.myApp.DeviceMonitorPrefsActivity"
android:switchTextOn="ON"
android:switchTextOff="OFF"/>
On the PreferenceActivity, I overrode onPreferenceTreeClick()
to perform an Action (launching a setup Activity in my case) when I click on the title of this SwitchPreference
control.
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
{
if(preference instanceof SwitchPreference){
// My Action
}
}
With Android 4.4.4, this Action used to be executed only when I pressed to the left of this control (title), but not when I changed the switch state.
Now with Android 5.0.1, the onPreferenceTreeClick() is called even when I change the switch state, and I didn't find a way to differentiate the two cases.
Is it a bug in Android 5.0.1 or is there a way to make this work cleanly?
This workaround found here seems to work : https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=172425
Here's my implementation that work on my case :
public class MySwitchPreference extends SwitchPreference {
/**
* Construct a new SwitchPreference with the given style options.
*
* @param context The Context that will style this preference
* @param attrs Style attributes that differ from the default
* @param defStyle Theme attribute defining the default style options
*/
public MySwitchPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Construct a new SwitchPreference with the given style options.
*
* @param context The Context that will style this preference
* @param attrs Style attributes that differ from the default
*/
public MySwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Construct a new SwitchPreference with default style options.
*
* @param context The Context that will style this preference
*/
public MySwitchPreference(Context context) {
super(context, null);
}
@Override
protected void onBindView(View view) {
ViewGroup viewGroup= (ViewGroup)view;
setSwitchClickable(viewGroup);
super.onBindView(view);
}
private void setSwitchClickable(ViewGroup viewGroup) {
if (null == viewGroup) {
return;
}
int count = viewGroup.getChildCount();
for(int n = 0; n < count; ++n) {
View childView = viewGroup.getChildAt(n);
if(childView instanceof Switch) {
final Switch switchView = (Switch) childView;
switchView.setClickable(true);
return;
} else if (childView instanceof ViewGroup){
ViewGroup childGroup = (ViewGroup)childView;
setSwitchClickable(childGroup);
}
}
}
Then you just have to use your own "MySwitchPreference" into SwitchPreference directly.