2012-02-27 31 views
17

Necesito hacer una vista en miniatura con esquinas redondeadas y sombra interior. Usualmente estoy haciendo marcos ImageView con 9 parches, que me han sido útiles hasta ahora, pero esta vez el efecto que necesito requiere dibujar la sombra interna en la parte superior de la imagen (y no solo alrededor de ella). Esto me llevó a extender la clase ImageView y anular el método onDraw().ImageView con esquinas redondeadas y sombra interior

public class ThumbnailImageView extends ImageView { 

Después de muchos tutoriales (! Gracias stackoverflow), que terminó con el código para el método onDraw():

@Override 
protected void onDraw(Canvas canvas) { 
    if (mBitmap == null) { 
     return; 
    } 

    int radius = 4; 
    int padding = 2; 
    int bleed = 2; 
    RectF frame = new RectF(padding, padding, getWidth() - padding, getHeight() - padding); 

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(0xFF000000); 
    canvas.drawRoundRect(frame, radius, radius, mPaint); 

    Shader bitmapShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP); 
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    mPaint.setColor(0xFF000000); 
    mPaint.setMaskFilter(new BlurMaskFilter(bleed, Blur.INNER)); 
    mPaint.setShader(bitmapShader); 
    canvas.drawRoundRect(frame, radius, radius, mPaint); 
} 

Lo que estoy haciendo básicamente, se dibuja un rectángulo redondeado negro primero y luego dibujar un mapa de bits de esquinas redondeadas con bordes difuminados (con el BlurMaskFilter) encima. El resultado es lo que quiero: valor onDraw() result la mBitmap se inicializa en el constructor ImageView así:

mDrawable = getDrawable(); 
if (mDrawable != null) { 
    mBitmap = ((BitmapDrawable) mDrawable).getBitmap(); 
} 

El problema es que estoy preponderantes con onDraw() por completo (sin super.onDraw()) se llama , así que tengo que escalar previamente todas las imágenes al tamaño de miniatura deseado (por ejemplo, 96x96) o solo se dibuja la esquina superior izquierda de la imagen. Lo que yo quiero ser capaz de hacer es aprovechar toda la escala del marco está haciendo cuando le asigno los siguientes valores XML a la ThumbnailImageView:

android:id="@+id/thumb" 
android:layout_width="96dp" 
android:layout_height="wrap_content" 
android:adjustViewBounds="true" 
android:scaleType="fitCenter" 

Para hacer esto, pensé que de alguna manera debería llamar super.onDraw() al obtener los efectos que necesito al mismo tiempo. He logrado obtener el reborde redondeado agregando un trazado de recorte al lienzo, pero no puedo encontrar una manera de agregar la sombra interior. Esta es la nueva onDraw() Código:

@Override 
protected void onDraw(Canvas canvas) { 
    int radius = 4; 
    int padding = 4;   
    RectF frame = new RectF(padding, padding, getWidth() - padding, getHeight() - padding); 
    Path clipPath = new Path(); 
    clipPath.addRoundRect(frame, radius, radius, Path.Direction.CW); 
    canvas.clipPath(clipPath); 
    super.onDraw(canvas); 
    // add inner shadow 
} 

puedo ver dos alternativas:

1) comprobar la validez de la escala adecuada de mapa de bits de la ImageView. Pero, ¿dónde está el mejor lugar para hacerlo? En su constructor? En el método onDraw() donde el framework parece estar haciéndolo? ¿El marco de trabajo está cambiando el tamaño de cualquier mapa de bits o hay otra forma de dibujar una imagen a escala en el lienzo sin ser malo para el rendimiento?

2) Para agregar la capa de sombra interior además de lo que super.onDraw() está dibujando hasta ahora, pero me estoy quedando sin ideas sobre cómo hacerlo.

Cualquier ayuda sería apreciada.

Gracias!

Respuesta

11

Tome un vistazo a (de squareup) de material de Eric presentación de la Conferencia de AndoridOpen Oreilly el año pasado en su conferencia titulada Beautiful Android Tiene un montón de información que le ayudarán a cabo.

Ojalá tuvieran el video de su presentación en alguna parte. No pude encontrarlo. Lo siento mucho.

EDIT: Gracias a @mykola para la yt link

+1

1 para un enlace muy útil :) – Wesley

+1

aquí está el enlace al video http://www.youtube.com/watch?v=jF6Ad4GYjRU – mykola

+0

@mykola OMG. tu rockeas gracias por el yt link !!!! – petey