Android LowClickInEnabled(true)将导致首选项真正被禁用,但当您单击它时,它将调用回调

Android LowClickInEnabled(true)将导致首选项真正被禁用,但当您单击它时,它将调用回调,android,android-preferences,Android,Android Preferences,在我们的例子中,我们想让复选框保持禁用状态,同时启用标题和摘要文本视图,但您可以根据自己的需求随心所欲。更新了代码。“是否可以禁用首选项,但仍能处理对其的单击?”--可能不会。我的猜测是,它们将底层小部件标记为已禁用,并且您无法接收已禁用小部件的单击事件(因为它们已禁用)。就我个人而言,我会对依赖权限的首选项使用单独的首选项屏幕,您可以控制用户如何进入这些屏幕的UI。@Commonware事实上,在问了这个问题后,我很快就找到了一个解决方法,但我仍然希望它能很好地工作。请检查我下面的答案。 cl

在我们的例子中,我们想让复选框保持禁用状态,同时启用标题和摘要文本视图,但您可以根据自己的需求随心所欲。更新了代码。

“是否可以禁用首选项,但仍能处理对其的单击?”--可能不会。我的猜测是,它们将底层小部件标记为已禁用,并且您无法接收已禁用小部件的单击事件(因为它们已禁用)。就我个人而言,我会对依赖权限的首选项使用单独的首选项屏幕,您可以控制用户如何进入这些屏幕的UI。@Commonware事实上,在问了这个问题后,我很快就找到了一个解决方法,但我仍然希望它能很好地工作。请检查我下面的答案。
class CheckboxPreferenceEx : android.preference.CheckBoxPreference {
    var alwaysAllowClickingEnabled: Boolean = false
    private val onPreferenceViewClickListener: View.OnClickListener

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)

    init {
        onPreferenceViewClickListener = View.OnClickListener {
            if (onPreferenceChangeListener != null && !isEnabled)
                if (onPreferenceChangeListener.onPreferenceChange(this@CheckboxPreferenceEx, !isChecked))
                    isChecked = !isChecked
            if (this@CheckboxPreferenceEx.isEnabled)
                this@CheckboxPreferenceEx.onClick()
        }
    }

    override fun onCreateView(parent: ViewGroup): View {
        val view = super.onCreateView(parent)
        setPreferenceTitleTextViewToHaveMultipleLines(view)
        //mTitleTextView = (TextView) view.findViewById(android.R.id.title);
        //mSummaryTextView = (TextView) view.findViewById(android.R.id.summary);
        return view
    }

    override fun onBindView(view: View) {
        super.onBindView(view)
        view.setOnClickListener(onPreferenceViewClickListener)
        val dependency = dependency
        if (!TextUtils.isEmpty(dependency) && !isEnabled) {
            //if the reason this preference is disabled is because of dependency, act as normal
            val dependencyPreference = preferenceManager.findPreference(dependency)
            if (!dependencyPreference!!.isEnabled || dependencyPreference is TwoStatePreference && !dependencyPreference.isChecked)
                return
        }
        if (alwaysAllowClickingEnabled) {
            //we chose to enable all except for the checkbox, which will still look disabled
            view.isEnabled = true
            setEnabledToViewAndItsDescendants(view, true)
        }
    }

    companion object {

        fun setPreferenceTitleTextViewToHaveMultipleLines(v: View) {
            if (v is TextView && v.getId() == android.R.id.title) {
                v.setSingleLine(false)
                return
            }
            if (v is ViewGroup) {
                for (i in 0 until v.childCount) {
                    val child = v.getChildAt(i)
                    setPreferenceTitleTextViewToHaveMultipleLines(child)
                }
            }
        }

        fun setEnabledToViewAndItsDescendants(v: View?, enabled: Boolean) {
            if (v == null)
                return
            v.isEnabled = enabled
            if (v is ViewGroup) {
                val viewGroups = ArrayList<ViewGroup>()
                viewGroups.add(v)
                while (!viewGroups.isEmpty()) {
                    val viewGroup = viewGroups.removeAt(0)
                    val childCount = viewGroup.childCount
                    for (i in 0 until childCount) {
                        val childView = viewGroup.getChildAt(i)
                        childView.isEnabled = enabled
                        if (childView is ViewGroup)
                            viewGroups.add(childView)
                    }
                }
            }
        }
    }

}