/*
* 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);
}
}
}
}