Подтвердить что ты не робот

Отключить ImageButton

Это выглядит просто, но я не могу отключить ImageButton. Он продолжает получать события щелчка, и его внешний вид не изменяется, как стандартная кнопка.

Есть несколько похожих вопросов на SO, но они мне не помогают.

Даже с очень простым расположением:

<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, тогда он работает так, как ожидалось. Кнопка становится отключенной и непривлекательной. Я не понимаю. У кого-нибудь есть идея?

4b9b3361

Ответ 1

ImageButton имеет другую цепочку наследования, то есть не расширяет Button:

ImageButton < ImageView < View

Он продолжает получать события клика

Вот что происходит, когда вы устанавливаете прослушиватель щелчков для View:

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

Поэтому, если вы установите слушателя, android:clickable="false" изменится на android:clickable="true".

и его внешний вид не меняется, как стандартная кнопка

Вы должны предоставить список отображаемых состояний для представления, чтобы оно могло установить соответствующее изображение на основе android:enabled. У тебя есть это? Или у вас есть единственное изображение для вашей кнопки?

РЕДАКТИРОВАТЬ: Вы можете найти информацию о StateListDrawable здесь. android:state_enabled - это то, что вам нужно использовать в списке, чтобы указать ОС, какой образ использовать для этого состояния.

РЕДАКТИРОВАТЬ 2: Поскольку вам действительно нужно добавить слушателя, вы можете проверить внутри слушателя, if (!isEnabled()) { return; } else {/* process the event */} if (!isEnabled()) { return; } else {/* process the event */}.

Ответ 2

Вот код, который я использую, чтобы отключить 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 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(); единственный недостаток - вам нужен идентификатор ресурса изображения здесь, потому что невозможно вернуть преобразованный значок обратно в оригинал.

Ответ 3

Удостоверьтесь, что в иерархии представлений нет одного и того же идентификатора, и вы не добавляете к нему никакого просмотра.

Ответ 4

если вы хотите отключить кнопку изображения, в событии клика, установите для свойства "setEnabled" значение false

Пример: imgButton.setEnabled(false);

Ответ 5

Воспользовавшись ответом Олега Васкевича. Можно сделать ответ для Котлина.

Создайте функцию расширения для 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 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

Мне удалось создать решение, вдохновленное ответом Олега Васкевича, но без необходимости передавать 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

Как уже говорили другие ответы, вы не можете отключить 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