Wie man animiertes Emoticon in TextView oder EditText in Android hinzufügt

Als die Frage verwende ich ImageSpan, um ein Bild in TextView hinzuzufügen. Aber es kann nicht animieren.
Ich versuche, AnimationDrawable zu erweitern, um in ImageSpan hinzuzufügen. Aber es funktioniert nicht

public class EmoticonDrawalbe extends AnimationDrawable { private Bitmap bitmap; private GifDecode decode; private int gifCount; public EmoticonDrawalbe(Context context, String source) { decode = new GifDecode(); decode.read(context, source); gifCount = decode.getFrameCount(); if (gifCount <= 0) { return; } for (int i = 0; i < gifCount; i++) { bitmap = decode.getFrame(i); addFrame(new BitmapDrawable(bitmap), decode.getDelay(i)); } setOneShot(false); } @Override public void draw(Canvas canvas) { super.draw(canvas); start(); } } 

  • Zeigen gif in android
  • Verwenden Sie GIF-Bild in ImageSpan mit einem EditText
  • Wie kann ich .gif-Datei in imageview anzeigen?
  • Set android Animation Liste programmgesteuert
  • Wie man ein animiertes GIF aus JPEGs in Android (Entwicklung)
  • Erhalten Sie den ersten Rahmen eines GIF-Bildes, ohne alle anderen Frames herunterzuladen
  • Hinzufügen von Gif-Bild in einem ImageView in Android
  • Wie kann man GIF in der reaktionsaktiven Android-Anzeige anzeigen?
  • 2 Solutions collect form web for “Wie man animiertes Emoticon in TextView oder EditText in Android hinzufügt”

    Ich würde versuchen, entweder:

    • Split das animierte Bild (vermutlich eine. GIF-Datei?) In separate Frames und kombiniere diese in eine AnimationDrawable , die Sie dann an den ImageSpan-Konstruktor übergeben.
    • Subclass ImageSpan und überschreiben Sie die onDraw() Methode, um Ihre eigene Logik hinzuzufügen, um die verschiedenen Frames basierend auf irgendeiner Art von Timer zu zeichnen. Es gibt eine API-Demo, die veranschaulicht, wie man die Filmklasse benutzt, um ein animiertes Gif zu laden, das vielleicht einen Blick wert ist.

    Big Edit: Alright, sorry für nicht immer früher, aber ich musste beiseite legen einige Zeit, um dies selbst zu untersuchen. Ich habe ein Spiel damit gespielt, da ich wohl eine Lösung für mich selbst für eines meiner zukünftigen Projekte brauche. Leider habe ich in ähnliche Probleme mit der Verwendung eines AnimationDrawable , die durch den Caching-Mechanismus, dass DynamicDrawableSpan (eine indirekte Superklasse von ImageSpan ) verursacht wird verursacht werden scheint.

    Ein weiteres Problem für mich ist, dass es nicht scheint, ein einfacher wat zu sein, um eine Drawable oder ImageSpan ungültig zu machen. Drawable hat tatsächlich invalidateDrawable(Drawable) und invalidateDrawable(Drawable) invalidateSelf() Methoden, aber die erste hatte keine Wirkung in meinem Fall, während die letztere nur funktioniert, wenn einige magische Drawable.Callback angehängt ist. Ich konnte keine anständige Dokumentation finden, wie man das benutzt …

    Also ging ich einen Schritt weiter nach oben den Logikbaum, um das Problem zu lösen. Ich muss im Voraus eine Warnung hinzufügen, dass dies höchstwahrscheinlich keine optimale Lösung ist, aber jetzt ist es die einzige, die ich in der Lage war, an die Arbeit zu kommen. Sie werden wahrscheinlich nicht in Probleme gehen, wenn Sie meine Lösung sporadisch verwenden, aber ich würde vermeiden, den ganzen Bildschirm mit Emoticons mit allen Mitteln zu füllen. Ich bin nicht sicher, was passieren würde, aber dann wieder, ich vermutlich nicht einmal wissen wollen.

    Ohne weiteres ist hier der Code. Ich habe einige Kommentare hinzugefügt, um es selbsterklärend zu machen. Es ist ziemlich wahrscheinlich eine andere Gif Decodierung Klasse / libary verwendet, aber es sollte mit etwa jeder da draußen arbeiten.

    AnimatedGifDrawable.java

     public class AnimatedGifDrawable extends AnimationDrawable { private int mCurrentIndex = 0; private UpdateListener mListener; public AnimatedGifDrawable(InputStream source, UpdateListener listener) { mListener = listener; GifDecoder decoder = new GifDecoder(); decoder.read(source); // Iterate through the gif frames, add each as animation frame for (int i = 0; i < decoder.getFrameCount(); i++) { Bitmap bitmap = decoder.getFrame(i); BitmapDrawable drawable = new BitmapDrawable(bitmap); // Explicitly set the bounds in order for the frames to display drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); addFrame(drawable, decoder.getDelay(i)); if (i == 0) { // Also set the bounds for this container drawable setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); } } } /** * Naive method to proceed to next frame. Also notifies listener. */ public void nextFrame() { mCurrentIndex = (mCurrentIndex + 1) % getNumberOfFrames(); if (mListener != null) mListener.update(); } /** * Return display duration for current frame */ public int getFrameDuration() { return getDuration(mCurrentIndex); } /** * Return drawable for current frame */ public Drawable getDrawable() { return getFrame(mCurrentIndex); } /** * Interface to notify listener to update/redraw * Can't figure out how to invalidate the drawable (or span in which it sits) itself to force redraw */ public interface UpdateListener { void update(); } } 

    AnimatedImageSpan.java

     public class AnimatedImageSpan extends DynamicDrawableSpan { private Drawable mDrawable; public AnimatedImageSpan(Drawable d) { super(); mDrawable = d; // Use handler for 'ticks' to proceed to next frame final Handler mHandler = new Handler(); mHandler.post(new Runnable() { public void run() { ((AnimatedGifDrawable)mDrawable).nextFrame(); // Set next with a delay depending on the duration for this frame mHandler.postDelayed(this, ((AnimatedGifDrawable)mDrawable).getFrameDuration()); } }); } /* * Return current frame from animated drawable. Also acts as replacement for super.getCachedDrawable(), * since we can't cache the 'image' of an animated image. */ @Override public Drawable getDrawable() { return ((AnimatedGifDrawable)mDrawable).getDrawable(); } /* * Copy-paste of super.getSize(...) but use getDrawable() to get the image/frame to calculate the size, * in stead of the cached drawable. */ @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { Drawable d = getDrawable(); Rect rect = d.getBounds(); if (fm != null) { fm.ascent = -rect.bottom; fm.descent = 0; fm.top = fm.ascent; fm.bottom = 0; } return rect.right; } /* * Copy-paste of super.draw(...) but use getDrawable() to get the image/frame to draw, in stead of * the cached drawable. */ @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { Drawable b = getDrawable(); canvas.save(); int transY = bottom - b.getBounds().bottom; if (mVerticalAlignment == ALIGN_BASELINE) { transY -= paint.getFontMetricsInt().descent; } canvas.translate(x, transY); b.draw(canvas); canvas.restore(); } } 

    Verwendung:

     final TextView gifTextView = (TextView) findViewById(R.id.gif_textview); SpannableStringBuilder sb = new SpannableStringBuilder(); sb.append("Text followed by animated gif: "); String dummyText = "dummy"; sb.append(dummyText); sb.setSpan(new AnimatedImageSpan(new AnimatedGifDrawable(getAssets().open("agif.gif"), new AnimatedGifDrawable.UpdateListener() { @Override public void update() { gifTextView.postInvalidate(); } })), sb.length() - dummyText.length(), sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); gifTextView.setText(sb); 

    Wie Sie sehen können, habe ich einen Handler benutzt, um die "Zecken" zur Verfügung zu stellen, um zum nächsten Rahmen vorzurücken. Der Vorteil davon ist, dass es nur ein Update auslöst, wenn ein neuer Rahmen gerendert werden soll. Die eigentliche Neuzeichnung erfolgt durch die Ungültigkeit der TextView, die die AnimatedImageSpan enthält. Zur gleichen Zeit der Nachteil ist, dass, wenn Sie eine Reihe von animierten Gifs in der gleichen TextView (oder mehrere für diese Angelegenheit), die Ansichten können wie verrückt aktualisiert werden … Verwenden Sie es mit Bedacht. 🙂

    Sie können ObjectAnimator verwenden, um die Zeichenkette in der ImageSpan zu beleben

    http://developer.android.com/reference/android/animation/ObjectAnimator.html

    Das Android ist ein Google Android Fan-Website, Alles über Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.