2010-07-15 25 views
10

Me estoy poniendo en práctica emoticonos usando el siguiente código:ImageSpan se corta/mal alineada

  builder.setSpan(new ImageSpan(mContext, resId, ImageSpan.ALIGN_BASELINE), 
         start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

El resultado (constructor) se establece como texto a un TextView. Funciona bien si el tramo está rodeado de texto, es decir, cuando el inicio> 0 y el final < longitud - 1, pero la imagen se corta (se desplaza hacia arriba) si no hay texto a su alrededor. ¿Cómo arreglo eso?

Muchas gracias.

+0

Para el registro, después de tratar de resolver esto por muchas horas, por desgracia, creo que esto es un error de Android y Don No veo una solución "real". Terminé agregando un espacio después de mi smiley como la respuesta de @plowman. Quiero mencionar que la aplicación Hangouts de Google tiene el mismo problema. Agregue un solo emoticono en la entrada del mensaje, luego agregue un espacio: el emoticón se mueve por unos pocos píxeles ... – BoD

Respuesta

3

Bueno, ya que no hay sugerencias, voy a utilizar la siguiente solución, mientras tanto: si no hay ningún texto - el uso de la bandera ALIGN_BOTTOM, de lo contrario usar ALIGN_BASELINE ...

+0

¿Todavía no hay mejores respuestas? – Gohan

4

También me encontré con este problema y no pudo encontrar una solución adecuada. La solución que utilicé se ve así:

if(message.length() == 1){ 
//This is a hack to get past an android bug that misaligns ImageSpan's when they are all alone. 
    message += " "; 
} 
builder = new SpannableStringBuilder(message); 
0

Intente establecer el límite del dibujante. Por ejemplo:

 BitmapDrawable bmd = new BitmapDrawable(bm); 
     int width = bmd.getIntrinsicWidth(); 
     int height = bmd.getIntrinsicHeight(); 
     bmd.setBounds(
       0, 
       0, 
       (int)width, 
       (int)height); 

     ImageSpan img = new ImageSpan(bmd); 
     SpannableString spannableString = new SpannableString(
      someString); 
     spannableString.setSpan(
      img, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
+0

Esto no me cambió nada. De hecho, mirando la fuente de ImageSpan, parece que la llamada a seBounds ya está hecha cuando se usa una identificación de recurso, por lo tanto, parece normal que esto no solucione el problema. – BoD

7

Siguiendo a su solución, aquí es mi costumbre DynamicDrawableSpan que utilizo en lugar de ImageSpan. El método draw() (copiado de DynamicDrawableSpan y modificado) garantiza que haya texto antes de alinearse con la línea base.

class StickerSpan extends DynamicDrawableSpan { 
    Drawable mDrawable; 

    public StickerSpan(Context context, Bitmap bitmap) { 
     super(DynamicDrawableSpan.ALIGN_BASELINE); 
     setBitmap(context, bitmap); 
    } 

    public void setBitmap(Context context, Bitmap bitmap) { 
     mDrawable = new BitmapDrawable(context.getResources(), bitmap); 
     int width = mDrawable.getIntrinsicWidth(); 
     int height = mDrawable.getIntrinsicHeight(); 
     mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); 
    } 

    @Override 
    public Drawable getDrawable() { 
     return mDrawable; 
    } 

    @Override 
    public void draw(Canvas canvas, CharSequence text, 
        int start, int end, float x, 
        int top, int y, int bottom, Paint paint) { 
     Drawable b = mDrawable; 
     canvas.save(); 

     int transY = bottom - b.getBounds().bottom; 
     if (mVerticalAlignment == ALIGN_BASELINE) { 
      int textLength = text.length(); 
      for (int i = 0; i < textLength; i++) { 
       if (Character.isLetterOrDigit(text.charAt(i))) { 
        transY -= paint.getFontMetricsInt().descent; 
        break; 
       } 
      } 
     } 

     canvas.translate(x, transY); 
     b.draw(canvas); 
     canvas.restore(); 
    } 
} 
0

Para mí, simplemente no había establecido los límites del drawable antes de pasarlo a ImageSpan.

Puede configurar los "límites intrínsecos" de la dibujable haciendo algo como:

Drawable drawable = // what you use to create/get your drawable 
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 
ImageSpan span = new ImageSpan(drawable); 
+0

Esto no solo es incorrecto (debe ser 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()) pero incluso después de la reparación, esto no resuelve el problema, al menos para mí. – BoD

+0

Ah su derecho sobre el orden de los params. Se corrigió el error tipográfico. Esto sí resolvió el corte del texto en mi caso. Creo que hay algunos casos en que el texto puede ser cortado. Es posible que algunas respuestas aquí no funcionen en todos los casos, pero es posible que pueda ayudar a alguien, por lo que lo mantengo como posible respuesta. – cottonBallPaws

Cuestiones relacionadas