【问题标题】:Can't toggle switch in Custom SwitchPreference无法在自定义 SwitchPreference 中切换开关
【发布时间】:2015-04-26 09:34:36
【问题描述】:

我尝试在 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 中,我无法打开或关闭开关。我怎么能解决这个问题?谢谢!

【问题讨论】:

  • 您找到解决方案了吗?
  • 在您的代码中,arg0 指向触发侦听器的控件。代替 swit.setChecked,将 arg0 转换为正确的首选项类型,然后从那里调用 setChecked。下面提供了答案以获取更多详细信息。

标签: android switchpreference


【解决方案1】:

我正在开发在具有 API 15 的设备上运行的应用程序,因此必须解决此问题。该解决方案将为您的 SwitchPreference 提供两种不同的布局,而不是一种处理切换切换的布局。 Switch 必须是 clickable = false 否则您的 SwitchPreference 将无法处理任何点击。

首先是'on state'开关布局,其中按钮使用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;
            }
        });
    }

【讨论】:

    【解决方案2】:

    在 PreferenceFragmentCompat 中将 SwitchPreferenceCompat 与 androidX 一起使用,以下内容可按您的要求工作。

    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”可能超出了侦听器的范围。在我的示例中,它作为 Preference 首选项传入。

    【讨论】:

    • 调用 setOnPreferenceClickListener 时,isChecked 我的开关偏好已被切换
    • 你怎么称呼它,你用的是什么版本的安卓?我注意到不同版本之间的变化很大。
    • 我在 setOnPreferenceClickListener 之后正常调用它,切换回对我有用的 onCheckedChange 监听器
    【解决方案3】:

    SwitchPreference Listener with Custom Layout 的重复。

    SwitchView 的 id 应该是 @android:id/switch_widget 而不是 @+id/custom_switch_item 或任何其他自定义 id。

    在SwitchPreference类的源码中,我们可以找到代码:

    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 才能正确找到。

    这是一个关于 SwitchPreference 的 widgetLayout 的演示:

    <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" />
    

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 2020-03-21
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多