【问题标题】:Disable an ImageButton禁用 ImageButton
【发布时间】:2011-11-19 18:24:38
【问题描述】:

这看起来很简单,但我无法禁用ImageButton。它继续接收点击事件,并且它的外观不会像标准按钮那样发生变化。

SO上有一些similar questions,但它们对我没有帮助。

即使是这样一个非常简单的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <ImageButton
        android:id="@+id/btn_call"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:clickable="false"
        android:enabled="false"
        android:src="@android:drawable/sym_action_call" />

</LinearLayout>

该按钮仍处于启用状态,我可以单击它。

奇怪的是,如果我将ImageButton 更改为简单的Button,那么它会按预期工作。该按钮变为禁用且不可点击。我不明白。有人有想法吗?

【问题讨论】:

    标签: android imagebutton


    【解决方案1】:

    这是我用来禁用ImageButton 并使其看起来灰显的代码:

    /**
     * Sets the specified image buttonto the given state, while modifying or
     * "graying-out" the icon as well
     * 
     * @param enabled The state of the menu item
     * @param item The menu item to modify
     * @param iconResId The icon ID
     */
    public static void setImageButtonEnabled(Context ctxt, boolean enabled, ImageButton item,
            int iconResId) {
        item.setEnabled(enabled);
        Drawable originalIcon = ctxt.getResources().getDrawable(iconResId);
        Drawable icon = enabled ? originalIcon : convertDrawableToGrayScale(originalIcon);
        item.setImageDrawable(icon);
    }
    
    /**
     * Mutates and applies a filter that converts the given drawable to a Gray
     * image. This method may be used to simulate the color of disable icons in
     * Honeycomb's ActionBar.
     * 
     * @return a mutated version of the given drawable with a color filter
     *         applied.
     */
    public static Drawable convertDrawableToGrayScale(Drawable drawable) {
        if (drawable == null) {
            return null;
        }
        Drawable res = drawable.mutate();
        res.setColorFilter(Color.GRAY, Mode.SRC_IN);
        return res;
    }
    

    只需拨打setImageButtonEnabled();唯一的缺点是您需要在此处输入图像的资源 ID,因为无法将转换后的图标恢复为原始图标。

    【讨论】:

      【解决方案2】:

      ImageButton 具有不同的继承链,这意味着它不会扩展 Button

      ImageButtonImageViewView

      它继续接收点击事件

      当您为 View 设置点击侦听器时会发生以下情况:

      public void setOnClickListener(OnClickListener l) {
          if (!isClickable()) {
              setClickable(true);
          }
          mOnClickListener = l;
      }
      

      因此,如果您设置监听器,android:clickable="false" 将更改为 android:clickable="true"

      它的外观不会像标准按钮那样改变

      您应该为视图提供一个可绘制的状态列表,以便它可以根据android:enabled 设置适当的图像。你有这个吗?或者您的按钮只有一个图片?

      编辑:您可以在 StateListDrawable here 上找到信息。 android:state_enabled 是您需要在列表中使用的内容,以便告诉操作系统该状态使用什么图像。

      EDIT2:由于您确实需要添加一个侦听器,您可以在侦听器if (!isEnabled()) { return; } else { /* process the event */ } 内部进行检查。

      【讨论】:

      • 对我不起作用。帮助我的是通过代码设置禁用状态: ImageButton mBtnDelayCall = (ImageButton)v.findViewById(R.id.btnCallDelay); mBtnDelayCall.setEnabled(false);
      【解决方案3】:

      如果要禁用图像按钮,请在单击事件时将属性“setEnabled”设置为 false

      例如:imgButton.setEnabled(false);

      【讨论】:

      • android:enabled="false" 不起作用,但使用 setEnabled() 在代码中设置属性有效。
      【解决方案4】:

      确保您的视图层次结构中没有具有相同 ID 的视图,并且您没有向该视图添加任何点击侦听器。

      【讨论】:

        【解决方案5】:

        利用Oleg Vaskevich 的回答。可以为 Kotlin 做一个答案。

        为 ImageButton 创建一个Extension Function,这样:

        /**
         * Sets the specified image buttonto the given state, while modifying or
         * "graying-out" the icon as well
         *
         * @param enabled The state of the menu item
         * @param iconResId The icon ID
         */
        fun ImageButton.setButtonEnabled(enabled: Boolean, iconResId: Int) {
            isEnabled = enabled
            val originalIcon = context.resources.getDrawable(iconResId)
            val icon = if (enabled) originalIcon else convertDrawableToGrayScale(originalIcon)
            setImageDrawable(icon)
        }
        

        而且您对提供上下文

        的依赖有所减少

        【讨论】:

          【解决方案6】:

          我设法构建了一个受 Oleg Vaskevich 的 answer 启发的解决方案,但无需将可绘制资源 ID 传递给 setEnabled()。

          这是 Kotlin 代码,在实用程序模块内:

          fun Drawable.deepCopy(): Drawable =
              constantState?.newDrawable()?.mutate() ?:
                  throw RuntimeException("Called on null Drawable!")
          
          fun Drawable.toGrayscale(): Drawable =
                  deepCopy().apply { setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN) }
          
          fun ImageButton.setAndShowEnabled(enabled: Boolean) {
              if (enabled == isEnabled)
                  return
          
              isEnabled = enabled
          
              if (enabled) {
                  setImageDrawable(tag as Drawable)
              }
              else {
                  if (tag == null)
                      tag = drawable
          
                  setImageDrawable(drawable.toGrayscale())
              }
          }
          

          可以这样使用:

          val button: ImageButton = findViewById(...)
          // ...
          button.setAndShowEnabled(false)
          
          // launch async operation
          GlobalScope.launch {
              // do work here
          
              // unblock button
              button.setAndShowEnabled(true)
          }
          

          【讨论】:

            【解决方案7】:

            正如其他答案所说,您不能像 Button 那样在布局 XML 中禁用 ImageButton,但您可以在运行时以相同的方式禁用两者:

            在 Java 中:

            button.setEnabled(false);     // setEnabled(boolean) on TextView
            imgButton.setEnabled(false);  // setEnabled(boolean) on View
            

            在这两种情况下,按钮都被禁用——没有点击事件到达它的onClickListener

            您还可以更改已禁用 ImageButton 的图标颜色,就像更改已禁用 Button 上的文本颜色一样,假设图标是可着色的。

            在布局 XML 中:

            <Button
                ...
                android:textColor="@drawable/button_color_selector" />
            
            
            <ImageButton
                ...
                android:tint="@drawable/button_color_selector" />
            

            现在ButtonImageButton 上的setEnable(boolean) 根据button_color_selector.xml 中的状态更改文本或图标颜色

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多