如何允许单击禁用的首选项(或模仿禁用的首选项功能)? [英] How to allow clicking on disabled preferences (or mimic disabled preferences functionality)?

查看:278
本文介绍了如何允许单击禁用的首选项(或模仿禁用的首选项功能)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些应用程序功能需要权限.如果未授予许可,则我们需要将其偏好设置为半".禁用(如果选中或不打钩,则不会更改),并显示一条文本,说明该文本不能使用,因为授予的权限不足,因此它只能部分被禁用(该文本将保持黑色,警告显示为红色) .看起来不会像普通的残疾人偏好.

Some app features require permissions. If a permission is not granted, we need the preference of it to be "semi" disabled (and not change if it's ticked or not), with a text telling that it cannot be used because there aren't enough granted permissions, so that it only partially looks disabled (the text will stay black, with the warning being red). It won't look like a normal disabled preference.

但是,就像普通的禁用首选项一样,当处于此状态时,所有依赖于该首选项的首选项都将被禁用且不可点击.

Like a normal disabled preference, though, when it's in this state, all preferences that depend on it will be disabled and un-clickable.

但是,与正常的禁用首选项不同,单击此类首选项后,它将转到授予所需权限的屏幕.

However, unlike a normal disabled preference, Upon clicking such a preference, it will go to a screen of granting the required permissions.

有多种方法可以处理对首选项的单击,但我发现没有一种方法可以处理对禁用的首选项的单击.

There are various ways to handle clicking on preferences, but none that I've found to handle clicking on a disabled preference.

由于其他各种首选项都依赖于这种首选项(以便根据是否启用/禁用它们来启用/禁用),因此我需要在需要时使其变为禁用状态,但允许单击它.

Since various other preferences depend on such a preference (so that they get enabled/disabled based on whether it's enabled/disabled), I need to let it become disabled when needed, yet allow to click on it.

我尝试了多种方法来处理点击:

I tried various ways to handle clicking:

  • onPreferenceTreeClick在PreferenceFragment内
  • 关于首选项本身的
  • setOnPreferenceClickListener
  • 尝试覆盖首选项的performClick,但由于它已隐藏,因此被认为是不好的事情
  • 覆盖偏好设置的onClick.
  • 在首选项的onCreateView或onBindView中,在创建的视图上使用setOnClickListener.
  • 包装首选项的onCreateView的视图,并在该视图或包装该首选项的新视图上使用setOnClickListener.
  • onPreferenceTreeClick inside the PreferenceFragment
  • setOnPreferenceClickListener on the preference itself
  • trying to override performClick of preference, but it's considered a bad thing because it's hidden
  • override onClick of preference.
  • in onCreateView or onBindView of the preference, use setOnClickListener on the view that's created.
  • wrap the view of onCreateView of the preference, and use setOnClickListener on the view or on the new view that wraps it.

禁用首选项时,所有这些都不会被呼叫,而您尝试单击该首选项.

All of those do not get called when the preference is disabled, and you try to click on the preference.

  1. 是否可以禁用首选项,但仍然可以处理对它的点击?

  1. Is it possible to disable a preference yet still handle clicks on it?

或者,是否可以扩展首选项依赖项的功能?要使其他首选项依赖于此首选项,而不仅仅是基于是否已启用?意味着只有在启用此功能并且它不在这种半启用状态的情况下才启用它们?

Alternatively, is it possible extend the functionality of the dependencies of the preferences ? To make other preferences to be dependent on this preference, but not just based on whether it's enabled or not ? Meaning they are enabled only if this one is enabled AND it's not in this semi-enabled state?

当前,仅CheckboxPreference在应用程序上用作需要此新状态的应用程序,因此很容易使它的复选框看起来处于禁用状态,而让首选项本身保持启用状态(我只是使用 view.findViewById(android.R.id.checkbox))

Currently, only CheckboxPreference is used on the app as the one that needs this new state, so it's easy to just make its checkbox look disabled, yet let the preference itself stay enabled (I just store the CheckBox view by using view.findViewById(android.R.id.checkbox) inside onCreateView method)

推荐答案

好的,我已经找到了解决方法:

OK, I've found a workaround for this:

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

}

具有这样的首选项,当我在其上调用setAlwaysAllowClickingEnabled(true)时,将导致该首选项被真正禁用,但是当您单击它时,它将调用回调.

Having such a preference like that, when I called setAlwaysAllowClickingEnabled(true) on it, will cause the preference to really be disabled, yet when you click on it, it will call the callback.

在我们的情况下,我们希望使复选框保持禁用状态,但启用标题和摘要TextView,但是您可以根据需要进行操作.更新了代码.

In our case, we wanted to let the checkbox stay disabled, yet enable the title and summary TextViews, but you can do as you wish, depending on your requirements. Updated the code.

这篇关于如何允许单击禁用的首选项(或模仿禁用的首选项功能)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆