首页 > 解决方案 > 如何正确自定义 SwitchPreferenceCompat 使其表现得像 Wi-Fi 设置首选项

问题描述

我想知道,如何正确自定义SwitchPreferenceCompat,使其表现得像 Wi-Fi 设置首选项。

在此处输入图像描述

有3个要求来实现

  1. 能够区分非切换区域(右侧)和切换区域(左侧)之间的点击事件
  2. 能够有正确的选择器行为。意思是,当触摸开关本身时,不应突出显示非开关区域。反之亦然。
  3. 在切换区域和非切换区域之间有一个分隔 UI。

到目前为止,我只能通过使用以下自定义代码来实现要求 1。

在此处输入图像描述

能够区分非切换区域(右侧)和切换区域(左侧)之间的点击事件

import android.content.Context;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.preference.SwitchPreferenceCompat;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;

public class CustomSwitchPreferenceCompat extends SwitchPreferenceCompat {
    public CustomSwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public CustomSwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomSwitchPreferenceCompat(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSwitchPreferenceCompat(Context context) {
        super(context);
    }

    /**
     * Recursively go through view tree until we find an android.widget.Switch
     * @param view Root view to start searching
     * @return A Switch class or null
     */
    private SwitchCompat findSwitchWidget(View view){
        if (view instanceof  SwitchCompat){
            return (SwitchCompat)view;
        }
        if (view instanceof ViewGroup){
            ViewGroup viewGroup = (ViewGroup)view;
            for (int i = 0; i < viewGroup.getChildCount();i++){
                View child = viewGroup.getChildAt(i);
                if (child instanceof ViewGroup){
                    SwitchCompat result = findSwitchWidget(child);
                    if (result!=null) return result;
                }
                if (child instanceof SwitchCompat){
                    return (SwitchCompat)child;
                }
            }
        }
        return null;
    }

    //Get a handle on the 2 parts of the switch preference and assign handlers to them
    @Override
    public void onBindViewHolder (PreferenceViewHolder holder){
        super.onBindViewHolder(holder);

        final SwitchCompat switchView = findSwitchWidget(holder.itemView);
        if (switchView!=null){
            switchView.setClickable(true);

            switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    android.util.Log.i("CHEOK", "Switch area : Being switch " + isChecked);
                }
            });
        }

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                android.util.Log.i("CHEOK", "Non-switch area : Being clicked");
            }
        });
    }
}

但是,我无法弄清楚,我怎样才能拥有正确的选择器行为,以及介于两者之间的分隔符 UI?

有什么建议,或者我可以使用的现成库吗?

标签: android

解决方案


添加一个 ViewGroup 并将其定义id@android:id/widget_frame. 首选项视图将搜索此 id 并将内容插入其中。

在布局中添加代码片段:

<LinearLayout android:id="@android:id/widget_frame"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:gravity="center_vertical"
              android:orientation="vertical" />


推荐阅读