SwitchPreference Listener with Custom Layout

谁说胖子不能爱 提交于 2019-12-06 07:44:49

I ran into the same issue, my solution is similar to the followings:

  1. In your custom switch layout, add following code. This "uncovers" the preference, and makes the whole block clickable. That's why the listener is not triggered at all.

    android:clickable="false" android:focusable="false"

  2. Extend "SwitchPreference", and in "onBindView" class, get states from SharedPreferences, and handle switch states change there.

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

Hopefully this can help you. I was not able to find any solution for my case until I figured it out this way.

Solution – based on @RickCase answer, but works with both Switch and SwitchCompat.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!