/* * Android helper classes. * Copyright (C) 2012 caoyachao@hotmail.com, Denis Nelubin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * http://gelin.ru * mailto:den@gelin.ru */ package ru.gelin.android.preference; import android.content.Context; import android.preference.TwoStatePreference; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.Checkable; import android.widget.CompoundButton; import android.widget.Switch; /** * The correct version of SwitchPreference which fixes this issue: * http://code.google.com/p/android/issues/detail?id=26194 * Also has not-words, but some characters for on/off states of the switch. */ public class SwitchPreference extends TwoStatePreference { private final Listener mListener = new Listener(); private class Listener implements CompoundButton.OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!callChangeListener(isChecked)) { // Listener didn't like it, change it back. // CompoundButton will make sure we don't recurse. buttonView.setChecked(!isChecked); return; } SwitchPreference.this.setChecked(isChecked); } } /** * 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 SwitchPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setWidgetLayoutResource(R.layout.preference_widget_switch); } /** * 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 SwitchPreference(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.switchPreferenceStyle); setWidgetLayoutResource(R.layout.preference_widget_switch); } /** * Construct a new SwitchPreference with default style options. * * @param context The Context that will style this preference */ public SwitchPreference(Context context) { this(context, null); setWidgetLayoutResource(R.layout.preference_widget_switch); } @Override protected void onBindView(View view) { ViewGroup viewGroup= (ViewGroup)view; clearListenerInViewGroup(viewGroup); super.onBindView(view); View checkableView = view.findViewById(R.id.switchWidget); if (checkableView != null && checkableView instanceof Checkable) { ((Checkable) checkableView).setChecked(isChecked()); if (checkableView instanceof Switch) { final Switch switchView = (Switch) checkableView; // switchView.setAccessibilityDelegate(); switchView.setOnCheckedChangeListener(mListener); } } } /** * 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); } } } }