web-dev-qa-db-fra.com

Désactiver un ImageButton

Cela semble facile, mais je ne suis pas en mesure de désactiver une ImageButton. Il continue de recevoir des événements de clic et son apparence ne change pas comme le ferait un bouton standard.

Il y a quelques questions similaires sur SO, mais elles ne m'aident pas.

Même avec une mise en page très simple comme celle-ci:

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

Le bouton est toujours activé et je peux cliquer dessus.

Ce qui est étrange, c’est que si je change la ImageButton en une simple Button, alors cela fonctionnera comme prévu. Le bouton devient désactivé et impossible à cliquer. Je ne comprends pas. est-ce que quelqu'un a une idée?

23
Dalmas

ImageButton a une chaîne d'héritage différente, ce qui signifie qu'elle ne s'étend pas Button:

ImageButton <ImageView <View

Il continue à recevoir des événements de clic

Voici ce qui se passe lorsque vous définissez un écouteur de clic pour la variable View:

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

Donc, si vous définissez un écouteur, le Android:clickable="false" devient Android:clickable="true".

et son apparence ne change pas comme un bouton standard

Vous devez fournir une liste d'états pouvant être dessinée à la vue afin qu'elle puisse définir une image appropriée en fonction de Android:enabled. Avez-vous ce? Ou vous avez la seule image pour votre bouton?

EDIT: Vous pouvez trouver des informations sur StateListDrawable ici . Android:state_enabled est ce que vous devez utiliser dans la liste pour indiquer au système d'exploitation quelle image utiliser pour cet état.

EDIT2: Puisque vous avez vraiment besoin d'ajouter un auditeur, vous pouvez effectuer une vérification à l'intérieur de l'écouteur if (!isEnabled()) { return; } else { /* process the event */ }.

16
Vit Khudenko

Voici le code que j'utilise pour désactiver une ImageButton et la rendre grisée:

/**
 * 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;
}

Il suffit d'appeler setImageButtonEnabled(); Le seul inconvénient est que vous avez besoin de l'ID de ressource de l'image car il n'est pas possible de rétablir une icône transformée en une icône originale.

43
Oleg Vaskevich

Assurez-vous qu'il n'y a pas de vue avec le même identifiant dans votre hiérarchie de vues et que vous n'ajoutez aucun écouteur de clic à cette vue.

2
a.ch.

si vous souhaitez désactiver un bouton d'image, définissez la propriété "setEnabled" sur false avec l'événement click

Ex: imgButton.setEnabled(false);

2
Roman Marius

J'ai réussi à construire une solution inspirée de answer d'Oleg Vaskevich, mais sans qu'il soit nécessaire de transmettre l'ID de ressource pouvant être dessiné à setEnabled ().

Voici le code Kotlin, à l'intérieur du module utilitaire:

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

Il peut être utilisé comme ceci:

val button: ImageButton = findViewById(...)
// ...
button.setAndShowEnabled(false)

// launch async operation
GlobalScope.launch {
    // do work here

    // unblock button
    button.setAndShowEnabled(true)
}
0
Ivan Mikhnovich

Profitant de la réponse de Oleg Vaskevich . Peut être fait une réponse pour Kotlin.

Créez une fonction Extension Fonction pour ImageButton, de cette façon:

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

Et vous êtes un peu moins dépendant de fournir Context

0
Mário Henrique

Comme d'autres réponses l'ont dit, vous ne pouvez pas désactiver une ImageButton dans le XML de mise en page comme vous pouvez utiliser un Button, mais vous pouvez les désactiver de la même manière au moment de l'exécution:

En Java:

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

Dans les deux cas, le bouton est désactivé - aucun événement de clic n'accède à sa onClickListener.

Vous pouvez également modifier la couleur de l'icône de la variable ImageButton désactivée de la même manière que vous modifiez la couleur du texte sur une variable Button désactivée, en supposant que l'icône est teintable.

Dans le layout XML:

<Button
    ...
    Android:textColor="@drawable/button_color_selector" />


<ImageButton
    ...
    Android:tint="@drawable/button_color_selector" />

Maintenant, setEnable(boolean) sur Button ou ImageButton change la couleur du texte ou de l'icône en fonction des états de votre button_color_selector.xml

0
MarcS