Не удается переключить переключатель в Custom SwitchPreference
Я пытаюсь получить пользовательские настройки переключателя в Android. Вот мой код
switch_widget.xml
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/customswitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="false"
/>
preference xml file :
<com.tnavitech.utils.CustomSwitch
android:title="Hide app icon"
android:key="hideicon"
android:defaultValue="false"
android:disableDependentsState="true"
android:widgetLayout="@layout/switch_widget"
/>
Затем я расширяю "SwitchPreference" и в классе "onBindView" и обрабатываю состояния переключателей в OnPreferenceChangeListener:
public class CustomSwitch extends SwitchPreference {
Switch swit;
public CustomCheckbox(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onBindView(final View rootView) {
ViewGroup viewGroup= (ViewGroup)rootView;
super.onBindView(rootView);
if(swit==null){
swit = (Switch) rootView.findViewById(R.id.customswitch);
}
this.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference arg0, Object arg1) {
if (arg1 instanceof Boolean) {
Boolean enabled = (Boolean) arg1;
if(enabled){
swit.setChecked(true); /// cant toggle switch here
Toast.makeText(getContext(), "on", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "off", Toast.LENGTH_SHORT).show();
swit.setSelected(false); ///cant toggle switch here
}
}
return true;
}
});
}
В setOnPreferenceChangeListener я не могу включить или выключить swith. Как я мог решить это? Спасибо!
1 ответ
Дубликат прослушивателя SwitchPreference с настраиваемым макетом.
Идентификатор 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" />
Я работаю над приложением, работающим на устройстве с API 15, поэтому пришлось исправить эту проблему. Решение состоит в том, чтобы иметь две разные компоновки для вашей SwitchPreference вместо одной, которая обрабатывает переключение переключателей. Switch должен быть clickable = false, иначе ваш SwitchPreference не будет обрабатывать никаких кликов.
Во-первых, это раскладка переключателя "в состоянии", где кнопка использует drawable, который представляет кнопку ON:
<?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="48dp"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textIsSelectable="false"
android:textSize="0sp"
android:button="@drawable/ico_toggle_on" //HERE IS DIFFERENCE BETWEEN THESE LAYOUTS
android:thumb="@android:color/transparent"
android:track="@android:color/transparent"
android:clickable="false"
android:focusable="false"
android:gravity="center_vertical" />
Второй макет для выключенного состояния:
<?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="48dp"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textIsSelectable="false"
android:textSize="0sp"
android:button="@drawable/ico_toggle_off" //HERE IS DIFFERENCE BETWEEN THESE LAYOUTS
android:thumb="@android:color/transparent"
android:track="@android:color/transparent"
android:clickable="false"
android:focusable="false"
android:gravity="center_vertical" />
И, наконец, в вашем наборе Activity или Fragment на SwitchPreference OnPreferenceChangeListener, чтобы переключить эти два макета следующим образом:
final SwitchPreference expertSettingsPref = (SwitchPreference) findPreference("expert_settings");
if (expertSettingsPref != null) {
expertSettingsPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.setWidgetLayoutResource((Boolean)newValue ? R.layout.custom_switch_preference_on : R.layout.custom_switch_preference_off);
return true;
}
});
}
Используя SwitchPreferenceCompat с androidX в PreferenceFragmentCompat, по вашему запросу работает следующее.
public class SettingsPageFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
final SwitchPreferenceCompat switchPreference = (SwitchPreferenceCompat) findPreference("switch");
if(switchPreference != null){
switchPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// get the incoming value
boolean isOn = (Boolean) newValue;
// get the incoming control
SwitchPreferenceCompat switchPreference = (SwitchPreferenceCompat) preference;
// set the incoming value to the incoming control
switchPreference.setChecked(isOn);
// do whatever else you wanted to when this event fires
}
});
}
}
Я подозреваю, что причина того, что ваш код не работает, заключается в том, что "Swit" может быть вне зоны действия слушателя. В моем примере это передается как предпочтение.