web-dev-qa-db-fra.com

ImageButton Android avec interface utilisateur désactivée

J'ai un ImageButton qui est désactivé (non cliquable ou défini comme désactivé). Je veux donner à l’utilisateur une impression d’interface utilisateur qu’elle est désactivée sans utiliser aucune autre image.

Y a-t-il un moyen de faire ça?

37
user484155

@Oleg Vaskevich a donné une solution différente au problème ici: Désactiver un ImageButton

Sa solution vous permet d’aveugler une ImageButton sans créer d’images supplémentaires ni utiliser un <selector>.

/**
 * Sets the image button to the given state and grays-out the icon.
 * 
 * @param ctxt The context
 * @param enabled The state of the button
 * @param item The button item to modify
 * @param iconResId The button's 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;
}
33
tronman

En élaborant sur la réponse @tronman, vous pouvez également composer une fonction qui va griser les objets dessinables chargés dynamiquement (c’est-à-dire qui ne provient pas d’une ressource, par exemple chargé à partir de fichiers svg bruts et converti à la volée en BitmapDrawables).

/**
 * 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 originalIcon The drawable
 */
public static void setImageButtonEnabled(Context ctxt, boolean enabled, ImageButton item, Drawable originalIcon) {
    item.setEnabled(enabled);

    Drawable res = originalIcon.mutate();
    if (enabled)
        res.setColorFilter(null);
    else
        res.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);
}

Si vous avez également un dessin non transparent sur l’arrière-plan (défini avec Android: background), reportez-vous aux sélecteurs Android: Comment créer un sélecteur dessiné pour modifier également l’arrière-plan.

6
southerton

J'ai préféré remplacer la méthode setEnabled() dans ImageButton pour modifier la propriété alpha de l'image en conséquence. Ainsi, lorsque le bouton est désactivé, l'image est partiellement transparente et semble plus handicapée.

public class CustomImageButton extends ImageButton {
    //...

    @Override
    public void setEnabled(boolean enabled) {
        if(this.isEnabled() != enabled) {
            this.setImageAlpha(enabled ? 0xFF : 0x3F);
        }
        super.setEnabled(enabled);
    }
}
3
SnoopDougg

Vous pouvez le définir sur non cliquable et également définir l'alpha pour montrer ce sentiment que vous mentionnez.

3
Android Beginner
public static void setImageButtonEnabled(@NonNull final ImageView imageView,
                                         final boolean enabled) {
    imageView.setEnabled(enabled);
    imageView.setAlpha(enabled ? 1.0f : 0.3f);

    final Drawable originalIcon = imageView.getDrawable();
    final Drawable icon = enabled ? originalIcon : convertDrawableToGrayScale(originalIcon);
    imageView.setImageDrawable(icon);
}

private static Drawable convertDrawableToGrayScale(@NonNull Drawable drawable) {
    final ColorMatrix matrix = new ColorMatrix();
    matrix.setSaturation(0);
    final ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);

    final Drawable mutated = drawable.mutate();
    mutated.setColorFilter(filter);

    return mutated;
}

Si vous utilisez Kotlin, vous pouvez créer une fonction d'extension pour qu'elle soit plus élégante:

fun ImageView.setImageButtonEnabled(enabled: Boolean){
   //Above implementation here
}

et appelez-le en utilisant:

yourImageView.setImageButtonEnabled(true/false)
0
Tiago