Android使用TextView加载Html实现点击图片放大

具体实现

AndroidTextView 中加载HTML标记时,我们可以使用 <img> 标记来显示图片,然后通过重写 onTouchEvent 方法来实现图片的放大效果。下面是一个示例代码,该代码在点击图片时会弹出一个对话框显示原图,用户可以选择是否放大图片。

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
public class MyTextView extends AppCompatTextView {
private static final int LONG_CLICK_TIME_THRESHOLD = 400;
private long mStartClickTime = 0;

public MyTextView(Context context) {
super(context);
}

public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
CharSequence text = getText();
if (text instanceof Spanned) {
Spanned spanned = (Spanned) text;
int action = event.getAction();

if (action == MotionEvent.ACTION_DOWN) {
mStartClickTime = System.currentTimeMillis();
} else if (action == MotionEvent.ACTION_UP) {
long clickDuration = System.currentTimeMillis() - mStartClickTime;

if (clickDuration < LONG_CLICK_TIME_THRESHOLD) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
x += getScrollX();
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);

ClickableSpan[] link = spanned.getSpans(offset, offset, ClickableSpan.class);
ImageSpan[] images = spanned.getSpans(offset, offset, ImageSpan.class);

if (link.length != 0) {
link[0].onClick(this);
return true;
} else if (images.length != 0) {
Drawable drawable = images[0].getDrawable();
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else if (drawable instanceof GifDrawable) {
bitmap = ((GifDrawable) drawable).getFirstFrame();
}
if (bitmap != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("图片预览");
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_image_preview, null);
ImageView imageView = view.findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);
builder.setView(view);
builder.setPositiveButton("放大", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 进行图片放大操作
}
});
builder.setNegativeButton("关闭", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
return true;
}
}
}
}
}
return super.onTouchEvent(event);
}
}

// 使用方式
String html = "这是一张图片: <img src='file:///android_asset/sample.png'>";

MyTextView textView = findViewById(R.id.text_view);
textView.setText(Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable = null;
try {
InputStream inputStream = getAssets().open(source);
drawable = Drawable.createFromStream(inputStream, null);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
} catch (IOException e) {
e.printStackTrace();
}
return drawable;
}
}, null));
textView.setMovementMethod( LinkMovementMethod.getInstance());

在这个示例代码中,我们继承了 AppCompatTextView 并重写了 onTouchEvent 方法。在该方法中,我们使用类似于之前的方式获取点击位置,并查找到该位置对应的 ImageSpan 对象。然后我们根据该对象的 Drawable 对象生成一个 Bitmap 对象,并将其显示在一个自定义的对话框中。在对话框中,用户可以选择放大图片,也可以直接关闭对话框。

需要注意的是,当我们使用 <img> 标记来显示图片时,我们需要在第二个参数中传入一个 ImageGetter 对象,该对象用于将图片加载到 Drawable 中并返回。在本例中,我们通过从 Assets 中读取文件的方式来生成 Drawable 对象,并将其绑定到相应的 ImageSpan中。那么在触发点击事件时,我们只需要找到该位置的 ImageSpan 并获取其 Drawable 对象就能够得到原始的 Bitmap 对象了。

本文内容来自 : ChatGPT

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

0%