Status Update
Comments
mz...@gmail.com <mz...@gmail.com> #2
I also face this issue. Is there any workaround before it is fixed?
jr...@gmail.com <jr...@gmail.com> #3
I'm also seeing this bug. As Android 4.0.4 is merrily toggling settings in the background as if the user did it, I'm not sure what workaround there is, other than to use CheckBoxPreference if you have more than one boolean preference on your screen.
la...@gmail.com <la...@gmail.com> #4
I am finding exactly the same issue. As I scroll through the list of my preferences using SwitchPreference the values of the preferences when they are read back just change. The onSharedPreferenceChanged function is called as the screen scrolls with new values for the mChecked member of the switch preference. It seems that as a preference scrolls out of view the callback is invoked as if the user clicked on the preference.
ca...@gmail.com <ca...@gmail.com> #5
Here is my workaround:
public class CustomSwitchPreference 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 CustomSwitchPreference(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 CustomSwitchPreference(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 CustomSwitchPreference(Context context) {
super(context, null);
}
@Override
protected void onBindView(View view) {
// Clean listener before invoke SwitchPreference.onBindView
ViewGroup viewGroup= (ViewGroup)view;
clearListenerInViewGroup(viewGroup);
super.onBindView(view);
}
/**
* Clear listener in Switch for specify ViewGroup.
*
* @param viewGroup The ViewGroup that will need to clear the listener.
*/
private void clearListenerInViewGroup(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.setOnCheckedChangeListener(null);
return;
} else if (childView instanceof ViewGroup){
ViewGroup childGroup = (ViewGroup)childView;
clearListenerInViewGroup(childGroup);
}
}
}
}
public class CustomSwitchPreference 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 CustomSwitchPreference(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 CustomSwitchPreference(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 CustomSwitchPreference(Context context) {
super(context, null);
}
@Override
protected void onBindView(View view) {
// Clean listener before invoke SwitchPreference.onBindView
ViewGroup viewGroup= (ViewGroup)view;
clearListenerInViewGroup(viewGroup);
super.onBindView(view);
}
/**
* Clear listener in Switch for specify ViewGroup.
*
* @param viewGroup The ViewGroup that will need to clear the listener.
*/
private void clearListenerInViewGroup(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.setOnCheckedChangeListener(null);
return;
} else if (childView instanceof ViewGroup){
ViewGroup childGroup = (ViewGroup)childView;
clearListenerInViewGroup(childGroup);
}
}
}
}
al...@gmail.com <al...@gmail.com> #6
It works,Awesome,Thanks a lot!
dn...@gmail.com <dn...@gmail.com> #7
Reproducible on Android 4.2.1 (Galaxy Nexus).
gi...@gmail.com <gi...@gmail.com> #8
Galaxy Nexus @ Android 4.2.1. Russian interface. Camera app. Preferences. Geotag toggler
lu...@gmail.com <lu...@gmail.com> #9
Still happening in Nexus 4, Android 4.2.2... but the workaround mentioned in #4 works. Thank you very, VERY, *VERY* much!!!!
jo...@gmail.com <jo...@gmail.com> #10
[Comment deleted]
jo...@gmail.com <jo...@gmail.com> #11
A have this bug also on stock Android 4.3 on Nexus 7. Have been spending 2 hours to review my code to solve this and then it turns out to be a bug of over a year old. Quite serious bug to if you ask me since it is hard to detect.
My solution was to replace all SwitchPreference widgets with CheckBoxPreferences.
My solution was to replace all SwitchPreference widgets with CheckBoxPreferences.
mo...@gmail.com <mo...@gmail.com> #12
My workaround is similar to #4 <caoyachao1982@gmail.com>
public class CustomSwitchPreference extends SwitchPreference {
public CustomSwitchPreference(Context context) {
this(context, null);
}
public CustomSwitchPreference(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.switchPreferenceStyle);
}
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
public class CustomSwitchPreference extends SwitchPreference {
public CustomSwitchPreference(Context context) {
this(context, null);
}
public CustomSwitchPreference(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.switchPreferenceStyle);
}
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
gi...@gmail.com <gi...@gmail.com> #13
fixed camera ui on 4.3
thanks
thanks
mb...@gmail.com <mb...@gmail.com> #16
Issue occurs on Moto X (Android 4.4). Was able to apply workaround #11 above successfully.
za...@gmail.com <za...@gmail.com> #17
Confirming #15, issue still present in 4.4 on Moto X
po...@gmail.com <po...@gmail.com> #18
Can reproduce the issue on L Preview as well. Maybe it's time to get this fixed?
I openedhttps://code.google.com/p/android/issues/detail?id=72801 because I missed this one. Sorry for that.
I opened
al...@android.com <al...@android.com> #19
Fixed in master branch.
ne...@gmail.com <ne...@gmail.com> #20
[Comment deleted]
ne...@gmail.com <ne...@gmail.com> #21
[Comment deleted]
km...@gmail.com <km...@gmail.com> #22
It's already fixed in Lollipop. Since SwitchPreference is baked into the OS it's not possible to update/fix it without releasing a full Android update. Those take awhile to come down the pipeline and for some (even if they're relatively new) devices it may never come. It can't be fixed by pushing an update to the Play Store.
The solution in comment #4 should work just fine for supporting KitKat and before. I've used it. The only place where it would not work is if you cannot use custom views. And that's not often.
The solution in
e....@pomtech.com <e....@pomtech.com> #24
Hi, is this issue also present in "androidx.preference.SwitchPreferenceCompat
" class?
I guess no, but rather ask for a confirmation.
Thanks
Description
The bug is that state of SwitchPreference will be changed sometime when it is scrolled out of the screen.
After investigate and debug the source code, we found the reason.
This bug happens when a SwitchPreference(use SP_A for short) is scrolled out of the screen and at the same time another SwitchPreference(use SP_B for short) is scrolled in the screen. The SP_B will use the view of SP_A as the parameter of method onBindView. The onBindView method please refer to the attachment.
Please pay attention to the code in the red rectangle. The switchWidget’s setCheck is invoked first, and then its setOnCheckChangeListener is invoked. Because SP_B use the view of SP_A, so here when setCheck is invoked, it’s “OnChangeListener” is the listener of SP_A, so SP_A is notified, it will update the state of SP_A according to SP_B.mChecked. This cause the unexpected state change of SP_A while user scrolled the screen.