【问题标题】:Is there a clickable state for a StateListDrawable?StateListDrawable 是否有可点击状态?
【发布时间】:2014-11-14 08:55:48
【问题描述】:

我正在构建一个可以选择点击的自定义视图。我想设置一个指示可点击状态的背景。通常,我会使用 XML Drawable 来实现类似这样的功能:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white" android:state_enabled="false"/>
    <item android:drawable="@drawable/background_white_grey_spinner_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/background_white_grey_spinner_normal"/>
</selector>

不幸的是,它看起来没有 android:state_clickableandroid:state_pressable 属性。考虑到android:state_long_pressable,这似乎是一个奇怪的疏忽。我错过了什么吗?

【问题讨论】:

  • 这是在布局中完成的:android:clickable="true|false"。不在drawable本身。供参考:developer.android.com/reference/android/view/…
  • @Funkystein:是的,我会在布局中设置视图是否可点击,但我想使用背景来指示视图是否可点击。
  • 您可以使用state_enabled 在启用或禁用时设置不同的背景颜色。其中启用意味着可点击,间接
  • 是的,好像没有。也许他们认为state_enabled 已经传达了这一点。不过,您当然可以自己实现自定义状态;它相对简单。 This (off-site) page 有一个很好的、简单的例子。顺便说一句,您提到的state_long_pressable 本身就是一种自定义状态,因为它不是核心系统状态之一,而是为早已弃用的KeyboardView 单独创建的状态。

标签: android android-layout android-custom-view android-drawable


【解决方案1】:

您应该组合单个项目的状态:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" android:state_enabled="false"/>
<item android:drawable="@drawable/background_white_grey_spinner_pressed" android:state_enabled="true" android:state_pressed="true"/>
<item android:drawable="@drawable/background_white_grey_spinner_normal" android:state_enabled="true" android:state_pressed="false"/>

【讨论】:

    【解决方案2】:

    当我们想在视图可点击时将任何可绘制对象设置为视图时,使用状态“启用”本身。所以“state_enabled”是用来传达一个特定的视图是可点击的。

    但我们也可以为特定视图创建自定义可绘制状态并使用它来定义 stateListDrawable

    请检查以下步骤为视图创建自定义可绘制状态:

    1. 在 res/values 中创建 attrs.xml 并在其中添加以下代码:

      <resources>
          <declare-styleable name="food">
              <attr name="state_clickable" format="boolean" />
          </declare-styleable>
      </resources>
      
    2. 创建一个支持自定义可绘制状态的自定义视图。在下面添加一个示例自定义视图类。 我们将不得不重写 onCreateDrawableState 方法并将现有的可绘制状态与新的状态合并。

       class CustomButton @JvmOverloads constructor(
       context: Context,
       attrs: AttributeSet? = null
       ) : MaterialButton(context, attrs) {
      
       private val STATE_CLICKABLE = intArrayOf(R.attr.state_clickable)
      
      
       override fun onCreateDrawableState(extraSpace: Int): IntArray {
           val drawableStates: IntArray = super.onCreateDrawableState(extraSpace + 1)
           if (this.isClickable) {
               mergeDrawableStates(drawableStates, STATE_CLICKABLE);
               }
               return drawableStates
           }
       }
      
    3. 现在我们可以在 stateListDrawable 中使用 state_clickable。参考如下:

    在 res/drawables/button_bg.xml 中创建一个 stateListDrawable

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res/yourAppPackage">
    <item
        app:state_clickable="true"
        android:drawable="@drawable/item_clickable" />
    <item
        app:state_clickable="false"
        android:drawable="@drawable/item_non_clickable" />
    </selector>
    

    这个drawable现在可以用作自定义视图的背景

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-29
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2018-07-03
      相关资源
      最近更新 更多