Android implements gif image and text mixing, and android implements gif Image
We send emoticons during QQ chat, but these emoticons are not static. They are more dynamic and gif images. How can we display dynamic gif images on the android client.
Found such a method on github, Github address https://github.com/TracyZhangLei/android-gif-demo
Because I am, I cannot see the dynamic effect. You can download it for a moment.
First, let's take a look at the code of this open-source project. This open-source project uses the custom convertNormalStringToSpannableString method in the setText attribute of each chatAdapter by customizing an Adapter ------- ChatAdapter.
The Return Value of the convertNormalStringToSpannableString method is SpannableString.
First, let's take a look at what is SpannableString
TextView is usually used to display common text, but sometimes you need to set the style and event of some of the text. Android systemSpannableStringClass to process the specified text. That is to say, we need to use the SpannableString class to implement the text plus dynamic expressions.
private SpannableString convertNormalStringToSpannableString(String message , final TextView tv) { SpannableString value = SpannableString.valueOf(message); Matcher localMatcher = EMOTION_URL.matcher(value); while (localMatcher.find()) { String str2 = localMatcher.group(0); int k = localMatcher.start(); int m = localMatcher.end(); if (m - k < 8) { int face = fm.getFaceId(str2); if(-1!=face){//wrapping with weakReference WeakReference<AnimatedImageSpan> localImageSpanRef = new WeakReference<AnimatedImageSpan>(new AnimatedImageSpan(new AnimatedGifDrawable(cxt.getResources().openRawResource(face), new AnimatedGifDrawable.UpdateListener() { @Override public void update() {//update the textview tv.postInvalidate(); } }))); value.setSpan(localImageSpanRef.get(), k, m, Spanned.SPAN_INCLUSIVE_INCLUSIVE); } } } return value; }
First, convert the received message to the SpannableString class, and then check whether the input value conforms to the regular expression EMOTION_URL we wrote at the beginning.
private Pattern EMOTION_URL = Pattern.compile("\\[(\\S+?)\\]");
If yes, we can use group (0)
Appendix:GroupFor,Group(0) Refers to the entire string,Group(1)It refers to something in the first bracket,Group(2In the second bracket.
The difference between the subexpression and the start position is less than 8, that is, it meets our requirements. Call the getFaceId method in FaceManager
public int getFaceId(String faceStr){ if(mFaceMap.containsKey(faceStr)){ return mFaceMap.get(faceStr); } return -1; }
Find the expression we store with Map
If the expression exists, use a WeakReference to process the custom AnimatedImageSpan, so that the memory consumption of the AnimatedImageSpan is less, and use postInvalidate to refresh the interface in the UpdateListener. Finally, set the setSpan method of SpannableString. The three parameters are respectively the span to be put in, start position, end position, and flag.
Flag:
Spanned. SPAN_EXCLUSIVE_EXCLUSIVE is the flag that needs to be specified during setSpan. It is used to identify whether to apply the new characters before and after the text within the Span range. Spanned. SPAN_EXCLUSIVE_EXCLUSIVE (not included before and after), Spanned. SPAN_INCLUSIVE_EXCLUSIVE (included first, not included later), Spanned. SPAN_EXCLUSIVE_INCLUSIVE (not included earlier, not included later), Spanned. SPAN_INCLUSIVE_INCLUSIVE (both before and after ).
Finally, return the SpannableString to achieve dynamic text mixing.
The custom AnimatedImageSpan is as follows:
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()); } }); } @Override public Drawable getDrawable() { return ((AnimatedGifDrawable)mDrawable).getDrawable(); } @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; } @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(); }}
If you have any questions, join the QQ group (452379712) to interact with Jerry education Senior Engineer online.
Author: Jerry Education
Source: http://www.cnblogs.com/jerehedu/
The copyright of this article belongs to Yantai Jerry Education Technology Co., Ltd. and the blog Park. You are welcome to repost it. However, you must keep this statement without the author's consent and provide the original article connection on the article page, otherwise, you are entitled to pursue legal liability.