关于Android使用TextView加载Html实现图片居中显示

前言

Android原生 TextView 中加载 HTML 图片时,默认情况下图片会按照其原来的大小显示,并且会与文字共存,而不会像网页中一样默认居中显示。如果需要在 TextView 中将图片居中显示, 可以使用以下几种方式

实现方案

第一种 使用自定义 ImageGetter

可以通过自定义ImageGetter 来实现图片居中显示。ImageGetter接口定义了获取 Drawable的方法,我们可以在这个方法中对图片进行处理,使其能够居中显示。以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class CenteredImageSpan implements LineHeightSpan, Html.ImageGetter {

private Context mContext;
private Drawable mDrawable;

public CenteredImageSpan(Context context, Drawable drawable) {
mContext = context;
mDrawable = drawable;
}

@Override
public int getLeadingMargin(boolean first) {
return mDrawable.getIntrinsicWidth() / 2;
}

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

int transY = bottom - mDrawable.getBounds().bottom;

canvas.translate(x + getLeadingMargin(true), transY / 2);
mDrawable.draw(canvas);

canvas.restore();
}

@Override
public Drawable getDrawable(String source) {
if (mDrawable == null) {
// 获取图片
Bitmap bitmap = BitmapFactory.decodeFile(source);
mDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
}
return mDrawable;
}
}

该示例代码主要通过实现 ImageGetter 接口和 LineHeightSpan 接口来实现图片的居中显示。通过实现 DrawablegetDrawable()方法,我们可以在这里获取图片,并在 draw()方法中实现图片的绘制。而由于图片的高度是不确定的,我们需要通过实现 LineHeightSpan 接口来控制行间距,以使得图片垂直居中。

使用上述代码,可以在 HTML 代码中添加以下标签,来调用自定义的 CenteredImageSpan 类:

1
<img src="file:///android_asset/1.jpg" width="200" align="middle">

第二种 使用 Html.TagHandlerCSS 样式

可以通过自定义Html.TagHandlerCSS 样式来实现图片居中显示。以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class CenterImageTagHandler implements Html.TagHandler {

private final TextView mTextView;

public CenterImageTagHandler(TextView textView) {
mTextView = textView;
}

@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("img")) {
if (opening) {
// 处理图片标签
ImageSpanCenter span = new ImageSpanCenter(mTextView.getContext(), null);
output.setSpan(span, output.length(), output.length(), Spannable.SPAN_MARK_MARK);
} else {
// 处理结束标签
Object[] obj = output.getSpans(0, output.length(), Object.class);
if (obj != null && obj.length > 0) {
Object span = obj[obj.length - 1];
int start = output.getSpanStart(span);
int end = output.length();
output.removeSpan(span);
if (start != end) {
// 设置图片的对齐方式为居中
span = new ImageSpanCenter(mTextView.getContext(), ((ImageSpan) span).getDrawable());
output.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
}

private static class ImageSpanCenter extends ImageSpan {

ImageSpanCenter(Context context, Drawable drawable) {
super(drawable);
}

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

canvas.save();

// 获取 TextView 的宽度
float textWidth = paint.measureText(text, start, end);
Layout layout = ((TextView) ((Spanned) text).getSpans(0, ((Spanned) text).length(), Object.class)[0]).getLayout();
float viewWidth = layout.getWidth();

float transX = (viewWidth - textWidth) / 2 - drawable.getIntrinsicWidth() / 2;

canvas.translate(x + transX, (top + bottom) / 2 - drawable.getIntrinsicHeight() / 2);
drawable.draw(canvas);

canvas.restore();
}
}
}

该示例代码主要通过实现 Html.TagHandler接口和自定义 ImageSpan 类来实现图片的居中显示。通过实现 TagHandlerhandleTag() 方法,我们可以在这里处理 img 标签,并在对应的位置插入一个ImageSpan 对象。而ImageSpan 可以通过重写 draw() 方法来实现图片的绘制。通过测量 TextView和文本的宽度,并使用 translate()方法来实现图片的水平居中和垂直居中。

使用上述代码,可以在 HTML 代码中添加以下标签和样式,来调用自定义的 CenterImageTagHandler 类:

1
<img src="file:///android_asset/1.jpg" width="200" style="display:block;margin:0 auto;">

第三种 给img标签包一层div然后添加居中样式

这种方式最为简单, 具体html代码如下:

1
<div style="text-align:center"><img src="图片地址" /></div>

以上几种方式都可以实现图片居中显示,只是实现方法不同,选择哪种方式主要是根据实际情况灵活选择。

本文内容来自 : ChatGPT

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%