禁用ImageButton

时间:2011-11-19 18:24:39

标签: android imagebutton

这看起来很简单,但我无法禁用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,那么它会按预期工作。该按钮变为禁用且无法点击。我不明白。有没有人有想法?

7 个答案:

答案 0 :(得分:43)

以下是我用来禁用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,因为无法将变换后的图标恢复为原始图标。

答案 1 :(得分:16)

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

ImageButton&lt; ImageView&lt; View

  

它继续接收点击事件

以下是为View设置点击监听器时发生的情况:

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

因此,如果您将android:clickable="false"设置为android:clickable="true"更改为<{1}}。

  

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

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

例如:imgButton.setEnabled(false);

答案 4 :(得分:0)

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

而且您对提供上下文

的依赖程度较低

答案 5 :(得分:0)

我设法建立了一个由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)
}

答案 6 :(得分:0)

正如其他答案所言,您不能像ImageButton一样禁用布局XML中的Button,但是可以在运行时以相同的方式禁用这两种方法:

在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" />

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