700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android ImageSpan的图文居中对齐

Android ImageSpan的图文居中对齐

时间:2022-05-14 14:54:28

相关推荐

Android ImageSpan的图文居中对齐

ImageSpan类为TextView提供了图文混排的形式,在ImageSpan的构造函数中提供了一个参数int verticalAlignment,表示垂直对齐方式,有两个参数ALIGN_BASELINE、ALIGN_BOTTOM 分别为顶部、底部对齐,但是没有居中对齐的参数(其实会找到这篇文章的人应该知道这点了。。)

下面说说我的实现思路及方法

1.根据构造函数verticalAlignment参数找到影响对齐方式的代码

public ImageSpan(Context context, int resourceId, int verticalAlignment) {super(verticalAlignment);mContext = context;mResourceId = resourceId;}

查看源码可知对齐参数是在ImageSpan的父类DynamicDrawableSpan中设置的

2.查看DynamicDrawableSpan类源码找出对齐方式的代码,在源码中能看到两个方法getSize与draw

3.getSize方法,返回一个Int含义为图片的宽度,但是我们看源码发现里面干的事情不仅是返回宽度还设置了文字的ascent、descent的位置

public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {Drawable d = getCachedDrawable();Rect rect = d.getBounds();if (fm != null) {fm.ascent = -rect.bottom; fm.descent = 0; fm.top = fm.ascent;fm.bottom = 0;}return rect.right;}

4.draw方法,根据对齐参数绘制图片。所以第一步就是修改draw方法来实现居中

public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {Drawable b = getCachedDrawable();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();}

5.修改draw方法

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 = 0;//获得将要显示的文本高度-图片高度除2等居中位置+top(换行情况)transY = ((bottom-top) - b.getBounds().bottom)/2+top;//偏移画布后开始绘制canvas.translate(x, transY);b.draw(canvas);canvas.restore();}

6.这时候如果运行调试的话会发现完全没效果。。为啥呢,别急还有一个重要方法没修改,那就是getSize方法,我们还需要修过getSize方法中对文字ascent、descent等参数的设置才行

public int getSize(Paint paint, CharSequence text, int start, int end,FontMetricsInt fm) {Drawable d = getDrawable();Rect rect = d.getBounds();if (fm != null) {FontMetricsInt fmPaint=paint.getFontMetricsInt();//获得文字、图片高度int fontHeight = fmPaint.bottom - fmPaint.top;int drHeight=rect.bottom-rect.top;//对于这段算法LZ表示也不解,正常逻辑应该同draw中的计算一样但是显示的结果不居中,经过几次调试之后才发现这么算才会居中int top= drHeight/2 - fontHeight/4;int bottom=drHeight/2 + fontHeight/4;fm.ascent=-bottom;fm.top=-bottom;fm.bottom=top;fm.descent=top;}return rect.right;}

7.到这就完成了图文居中的功能,效果图

下面上完整源码,谢谢支持

import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.FontMetricsInt;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.text.SpannableString;import android.text.Spanned;import android.text.style.ImageSpan;import android.widget.TextView;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView textView=new TextView(this);setContentView(textView);SpannableString showString = new SpannableString("1234533333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333336");MyIm imageSpan=new MyIm(this, R.drawable.ic_launcher);MyIm imageSpan2=new MyIm(this, R.drawable.ic_launcher);MyIm imageSpan21=new MyIm(this, R.drawable.ic_launcher);showString.setSpan(imageSpan, 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);showString.setSpan(imageSpan2, 27, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);showString.setSpan(imageSpan21, 77, 78, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);textView.setText(showString);}public class MyIm extends ImageSpan{public MyIm(Context arg0,int arg1) {super(arg0, arg1);}public int getSize(Paint paint, CharSequence text, int start, int end,FontMetricsInt fm) {Drawable d = getDrawable();Rect rect = d.getBounds();if (fm != null) {FontMetricsInt fmPaint=paint.getFontMetricsInt();int fontHeight = fmPaint.bottom - fmPaint.top;int drHeight=rect.bottom-rect.top;int top= drHeight/2 - fontHeight/4;int bottom=drHeight/2 + fontHeight/4;fm.ascent=-bottom;fm.top=-bottom;fm.bottom=top;fm.descent=top;}return rect.right;}@Overridepublic 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 = 0;transY = ((bottom-top) - b.getBounds().bottom)/2+top;canvas.translate(x, transY);b.draw(canvas);canvas.restore();}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。