Слушатель SwitchPreference с пользовательской разметкой
Я пытаюсь использовать SwitchPreference на своей странице настроек, но не могу заставить слушателя работать. Я использую пользовательский макет виджета для стилизации переключателя, так как не могу найти, как использовать темы для этого. В моем файле settings.xml у меня есть следующее:
<SwitchPreference
android:key="uitestmode"
android:summary="Enable to display test data in fragments"
android:title="UI Test Mode"
android:widgetLayout="@layout/widget_custom_switch_on_off" >
</SwitchPreference>
и мой SettingsFragment выглядит так:
SwitchPreference uiTestModePref = (SwitchPreference) findPreference("uitestmode");
uiTestModePref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.d(preference.getKey(), newValue.toString());
return false;
}
});
и мой пользовательский макет для моего переключателя:
<?xml version="1.0" encoding="utf-8"?>
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_switch_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:textIsSelectable="false"
android:textSize="18sp"
android:textOn="On"
android:textOff="Off"
android:textStyle="bold"
android:thumb="@drawable/carcast_switch_inner_holo_dark"
android:track="@drawable/carcast_switch_track_holo_dark" />
У меня проблема в том, что когда я нажимаю на переключатель, слушатель не вызывается. Кто-нибудь знает почему и как это исправить?
2 ответа
Я столкнулся с той же проблемой, мое решение похоже на следующее:
В свой собственный макет переключателя добавьте следующий код. Это "раскрывает" предпочтение и делает весь блок кликабельным. Вот почему слушатель не срабатывает вообще.
android: clickable = "false" android: focusable = "false"
Расширьте "SwitchPreference" и в классе "onBindView" получите состояния от SharedPreferences и обработайте изменения состояний переключателей.
public class MySwitchPreference extends SwitchPreference { public MySwitchPreference(Context context) { super(context, null); } public MySwitchPreference(Context context, AttributeSet attrs) { super(context, attrs); } public MySwitchPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } protected void onBindView(View view) { // Clean listener before invoke SwitchPreference.onBindView ViewGroup viewGroup= (ViewGroup)view; clearListenerInViewGroup(viewGroup); super.onBindView(view); final Switch mySwitch = (Switch) view.findViewById(R.id.custom_switch_item); Boolean initVal = this.getPersistedBoolean(false); if (initVal) { mySwitch.setChecked(true); } this.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { //Do your things here, toggling the switch and so on return true; } }); } 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); } } } }
Надеюсь, это поможет вам. Я не смог найти никакого решения для своего случая, пока не понял это таким образом.
Идентификатор SwitchView должен быть @android:id/switch_widget
вместо того @+id/custom_switch_item
или любой другой пользовательский идентификатор.
В источнике SwitchPreference
class, мы можем найти код:
View switchView = view.findViewById(AndroidResources.ANDROID_R_SWITCH_WIDGET);
И в AndroidResources
:
static final int ANDROID_R_SWITCH_WIDGET = android.R.id.switch_widget;
так что только id = @android:id/switch_widget
можно найти правильно.
Вот демонстрация widgetLayout SwitchPreference:
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/switch_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />