我在我的Android应用程序中使用SwitchPreference并发现了一些非常奇怪的东西.首选项中有多个SwitchPreference.
当我使用PreferenceActivity的默认布局时,一切都运行良好.但是,在我将自定义布局设置为首选项活动后,当您单击其中任何一个时,这些开关会一起开始更改.我正在基于手机的平板电脑上进行测试.我也在我的Android手机上测试它,它的工作方式也一样.
它是如何发生的!
这是我setting.xml
的首选自定义布局():
和PreferenceScreen
在代码中,我只是设置自定义布局
public class SettingsActivity extends PreferenceActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.setting); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); setupSimplePreferencesScreen(); } private void setupSimplePreferencesScreen() { addPreferencesFromResource(R.xml.pref_general); } }
以下是首选项的屏幕截图,两个开关始终同时更改您点击它们的每一个.
似乎SwitchPreference onBindView
将使用其他Switch
视图作为参数.
以下是Google Code中Android项目中的错误问题.这不是这个问题,但类似的,都描述了开关视图将根据其他开关的状态行事.
所以我找到了解决问题的两种方法:
CheckBoxPreference
如果屏幕中有多个布尔首选项,请使用此选项.
使用此解决方法
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); } } } }
我已经测试了这两种解决方案.他们的作品.