Tengo un GridView para mostrar algunos de los objetos, y visualmente cada uno de los objetos tendrán un icono de imagen y una etiqueta de texto. También quiero que el icono de la imagen para tener un poco de «push y pop» efecto cuando se hace clic, es decir, cuando se pulsa, la imagen se moverá una distancia pequeña en la parte inferior derecha de la dirección, y cuando se libera de regresar a su posición original.

Los objetos (y sus iconos de imagen) son de algunos dinámica de fuentes. Mi intuición es crear un StateListDrawable para cada elemento, la cual se tienen dos estados: o no presionado. Para GridView punto de vista, me gustaría utilizar un Botón, que puede alojar una Imagen y una etiqueta, que perfectamente satisface mi requerimiento.

He definido una clase de elemento para envolver el objeto original:

public class GridItem<T> {

    public static final int ICON_OFFSET = 4;

    private StateListDrawable mIcon;
    private String mLabel;
    private T mObject;

    public Drawable getIcon() {
        return mIcon;
    }

    public void setIcon(Drawable d) {
        if (null == d) {
            mIcon = null;
        }else if(d instanceof StateListDrawable) {
            mIcon = (StateListDrawable) d;
        } else {
            InsetDrawable d1 = new InsetDrawable(d, 0, 0, ICON_OFFSET, ICON_OFFSET);
            InsetDrawable d2 = new InsetDrawable(d, ICON_OFFSET, ICON_OFFSET, 0, 0);
            mIcon = new StateListDrawable();
            mIcon.addState(new int[] { android.R.attr.state_pressed }, d2);
            mIcon.addState(StateSet.WILD_CARD, d1);
            //This won't help either: mIcon.addState(new int[]{}, d1);
        }
    }

    public String getLabel() {
        return mLabel;
    }

    public void setLabel(String l) {
        mLabel = l;
    }

    public T getObject() {
        return mObject;
    }

    public void setObject(T o) {
        mObject = o;
    }

}

Ahora el problema es que, cuando me toque un elemento de cuadrícula, el icono de «mueve» como yo me lo esperaba, pero no va a restaurar su posición original cuando mi dedo se levanta dejando el elemento.

Mi pregunta es: cómo crear mediante programación un StateListDrawable equivalente a una inflada de un recurso XML como

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@drawable/image_pressed" />  
    <item android:drawable="@drawable/image_normal" />
</selector>

?

  • por desgracia, el problema parece estar conectado con el uso de InsetDrawable, ¿has probado a usar BitmapDrawable lugar? ¿Recuadro dibujables declarado como xml de trabajo ok? Sé que no es una solución, pero tal vez nos diagnosticar el problema…
  • Sí @wjeshak que están a la derecha. He modificado el GridItem.setIcon() método de la creación de dos BitmapDrawables otros, a continuación, InsetDrawables, entonces puedo ver los estados de cambio normalmente
InformationsquelleAutor Yuan | 2011-06-28

3 Comentarios

  1. 40

    si su dibujables son solo mapas de bits, podría hacer mediante programación, por ahora debe ayudar, sin embargo, me pregunto ¿cuál es el problema con InsetDrawable de uso aquí, básicamente, el uso de preparados BitmapDrawables que se dibujan en forma programada, sería necesario modificar el método para aceptar los mapas de bits b

            Bitmap bc1 = Bitmap.createBitmap(b.getWidth() + ICON_OFFSET, b.getHeight() + ICON_OFFSET, Bitmap.Config.ARGB_8888);
            Canvas c1 = new Canvas(bc1);
            c1.drawBitmap(b, 0, 0, null);
            Bitmap bc2 = Bitmap.createBitmap(b.getWidth() + ICON_OFFSET, b.getHeight() + ICON_OFFSET, Bitmap.Config.ARGB_8888);
            Canvas c2 = new Canvas(bc2);
            c2.drawBitmap(b, ICON_OFFSET, ICON_OFFSET, null);
    
            mIcon = new StateListDrawable();
            mIcon.addState(new int[] { android.R.attr.state_pressed },  new BitmapDrawable(bc2));
            mIcon.addState(StateSet.WILD_CARD, new BitmapDrawable(bc1));
    • Hola @wjeshak, prefiero Drawable como la Entrada/Salida de las interfaces. He utilizado el Drawable.setBounds() y Drawable.draw(Canvas) métodos para agregar «padding» a los bordes de los mapas de bits, y el problema resuelto. Usted me indicó la dirección correcta:) Gracias!
  2. 13

    Puedo ver la respuesta ya está aceptado. Estoy compartiendo si desea asignar dinámicamente los colores de los botones de los usuarios normales, así como el estado presionado. a continuación, puedes llamar a esta función :

    public static StateListDrawable convertColorIntoBitmap(String pressedColor, String normalColor){
    
    
            /*Creating bitmap for color which will be used at pressed state*/
            Rect rectPressed = new Rect(0, 0, 1, 1);
    
            Bitmap imagePressed = Bitmap.createBitmap(rectPressed.width(), rectPressed.height(), Config.ARGB_8888);
            Canvas canvas = new Canvas(imagePressed);       
            int colorPressed = Color.parseColor(pressedColor);
            Paint paintPressed = new Paint();
            paintPressed.setColor(colorPressed);
            canvas.drawRect(rectPressed, paintPressed);
            RectF bounds = new RectF();
            bounds.round(rectPressed);
    
            /*Creating bitmap for color which will be used at normal state*/
            Rect rectNormal = new Rect(0, 0, 1, 1);     
            Bitmap imageNormal = Bitmap.createBitmap(rectNormal.width(), rectNormal.height(), Config.ARGB_8888);
            Canvas canvasNormal = new Canvas(imageNormal);
            int colorNormal = Color.parseColor(normalColor);
            Paint paintNormal = new Paint();
            paintNormal.setColor(colorNormal);
            canvasNormal.drawRect(rectNormal, paintNormal);
    
    
            /*Now assigning states to StateListDrawable*/
            StateListDrawable stateListDrawable= new StateListDrawable();
            stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new BitmapDrawable(imagePressed));
            stateListDrawable.addState(StateSet.WILD_CARD, new BitmapDrawable(imageNormal));
    
            return stateListDrawable;
    
        }

    Ahora todo lo que necesita es establecer como su textview o fondo de botón como el siguiente :

     if(android.os.Build.VERSION.SDK_INT>=16){
            yourbutton.setBackground(convertColorIntoBitmap("#CEF6CE00","#4C9D32"));        
    
                }else{
    
    yourbutton.setBackgroundDrawable(convertColorIntoBitmap("#CEF6CE00","#4C9D32"));
        }

    Aquí puedes ver todo lo que usted necesita para pasar los colores de forma dinámica y hemos terminado. espero que esto ayude a alguien 🙂 se puede encontrar la esencia demasiado aquí 🙂

    • buenas…..bien hecho…:)
    • Gracias @rashi.
    • Eso es un montón de código. Usted podría utilizar ColorDrawable() en lugar de BitmapDrawable y evitar las tres primeras estrofas de ese código.
  3. 3

    He visto las respuestas anteriores, sino que vino para arriba con una mucho más corta y mejor solución utilizando ColorDrawable.

    /**
         * Get {@link StateListDrawable} given the {@code normalColor} and {@code pressedColor}
         * for dynamic button coloring
         *
         * @param normalColor  The color in normal state.
         * @param pressedColor The color in pressed state.
         * @return
         */
        public static StateListDrawable getStateListDrawable(int normalColor, int pressedColor) {
            StateListDrawable stateListDrawable = new StateListDrawable();
            stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(pressedColor));
            stateListDrawable.addState(StateSet.WILD_CARD, new ColorDrawable(normalColor));
            return stateListDrawable;
        }

    Este acepta resuelto colores enteros, y utiliza ColorDrawable para agregarlos en un StateListDrawable.

    Una vez que tienes la imagen, se puede utilizar simplemente como este,

    if (android.os.Build.VERSION.SDK_INT >= 16) {
                mButton.setBackground(Utils.getStateListDrawable(ResourceUtils.getColor(R.color.white),
                        ResourceUtils.getColor(R.color.pomegranate)));
            } else {
                mButton.setBackgroundDrawable(Utils.getStateListDrawable(ResourceUtils.getColor(R.color.white),
                        ResourceUtils.getColor(R.color.pomegranate)));
            }

Dejar respuesta

Please enter your comment!
Please enter your name here