2010-07-15 15 views
10

I emoticons bin der Umsetzung mit dem folgenden Code:ImageSpan abgeschnitten/falsch ausgerichtet

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

Das Ergebnis (Builder) als Text in einem Textview eingestellt ist. Es funktioniert gut, wenn die Spannweite von Text umgeben ist, d. H. Wenn der Start> 0 und das Ende < Länge - 1, aber das Bild abgeschnitten (nach oben verschoben), wenn es keinen Text um es ist. Wie repariere ich das?

Vielen Dank.

+0

Für die Aufzeichnung nach für den Versuch, dies viele Stunden zu lösen, leider glaube ich dies ein Android-Bug ist und ich don Ich sehe keine "echte" Lösung. Am Ende fügte ich einen Platz nach meinem Smiley hinzu, wie die Antwort von @plowman. Ich möchte erwähnen, dass die Hangouts App von Google das gleiche Problem hat! Fügen Sie ein einzelnes Smiley in der Nachrichteneingabe hinzu, fügen Sie dann ein Leerzeichen hinzu: der Smiley bewegt sich um ein paar Pixel ... – BoD

Antwort

3

Nun, da es keine Vorschläge sind, werde ich die folgende Lösung in der Zwischenzeit verwenden: wenn kein Text ist - Verwendung ALIGN_BOTTOM Flagge, sonst ALIGN_BASELINE verwenden ...

+0

Noch keine besseren Antworten? – Gohan

4

ich auch in dieser Ausgabe lief und konnte keine richtige Lösung finden. Die Abhilfe verwendete ich wie folgt aussieht:

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

versuchen, die Grenze des ziehbar gesetzt. Zum Beispiel:

 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

Das änderte nichts für mich. Wenn man sich die Quelle von ImageSpan anschaut, sieht es so aus, als sei der Aufruf von seBounds bereits erfolgt, wenn eine Ressourcen-ID verwendet wird. Daher scheint es normal zu sein, dass das Problem dadurch nicht behoben wird. – BoD

7

auf Ihre Lösung Folgen, hier ist meine Gewohnheit DynamicDrawableSpan ich anstelle von ImageSpan verwenden. Die Methode draw() (kopiert aus DynamicDrawableSpan und modifiziert) stellt sicher, dass vor dem Abgleich mit der Baseline Text vorhanden ist.

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

Für mich hatte ich gerade nicht die Grenzen des Zeichens festgelegt, bevor ich es an den ImageSpan übergeben.

Sie können die „inneren Grenzen“ des ziehbar gesetzt durch, etwas zu tun:

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

Dies ist nicht nur falsch (es sollte 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()) sein, aber selbst nach der Behebung, löst dies nicht das Problem, zumindest für mich. – BoD

+0

Ah hast du recht über die Reihenfolge der Params. Der Tippfehler wurde korrigiert. Dadurch wurde in meinem Fall der Text abgeschnitten. Ich vermute, es gibt ein paar Fälle, in denen Text abgeschnitten werden kann. Einige Antworten hier funktionieren möglicherweise nicht für jeden Fall, aber es ist möglich, dass es jemandem helfen kann, damit ich es als mögliche Antwort behalte. – cottonBallPaws