Android textView展示html图片,实现图文混排,点击查看大图片

Android textView展示html图片,实现图文混排,点击查看大图片
最近要展示html在textView上,实现图文混排,并且图片可以点击放大,所以去研究了一下,效果图如下: 


我们知道textView的setText(Html.fromHtml(html))可以直接展示html的内容,但是如果html的标签包含imgd的话,直接用这个方法图片会展示不出来,然后我们看fromHtml的另一个构造方法的源码:

public static Spanned fromHtml(String source, ImageGetter imageGetter,
                               TagHandler tagHandler) {
    Parser parser = new Parser();
    try {
        parser.setProperty(Parser.schemaProperty, HtmlParser.schema);
    } catch (org.xml.sax.SAXNotRecognizedException e) {
        // Should not happen.
        throw new RuntimeException(e);
    } catch (org.xml.sax.SAXNotSupportedException e) {
        // Should not happen.
        throw new RuntimeException(e);
    }

    HtmlToSpannedConverter converter =
            new HtmlToSpannedConverter(source, imageGetter, tagHandler,
                    parser);
    return converter.convert();
}
 

通过上面的代码我们知道要想展示图片,我们可以重写imageGetter,下面是我重写imageGetter:

public class MImageGetter implements ImageGetter{
    Context c;
    TextView container;

    public MImageGetter(TextView text,Context c) {
        this.c = c;
        this.container = text;
    }
 public Drawable getDrawable(String source) {
     final LevelListDrawable drawable = new LevelListDrawable();
     Glide.with(c).load(source).asBitmap().into(new SimpleTarget<Bitmap>() {
         @Override
         public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
             if(resource != null) {
                 BitmapDrawable bitmapDrawable = new BitmapDrawable(resource);
                 drawable.addLevel(1, 1, bitmapDrawable);
                 drawable.setBounds(0, 0, resource.getWidth(),resource.getHeight());
                 drawable.setLevel(1);
                 container.invalidate();
                 container.setText(container.getText());
             }
         }
     });


     return drawable;
 }

}

加载图片的时候我用的是glide异步加载,其他原理一样。现在图片已经可以正常展示出来了,接下来要获取它的点击事件,这就首先需要设置textView的setMovementMethod方法,然后重写LinkMovementMethod获取到点击事件:

/**
 * 重写LinkMovementMethod类,获取图片的点击事件
 */
public class LinkMovementMethodExt extends LinkMovementMethod {
    private static LinkMovementMethod sInstance;
    private  Handler handler = null;
    private  Class spanClass = null;

    public static  MovementMethod getInstance(Handler _handler,Class _spanClass) {
        if (sInstance == null) {
            sInstance = new LinkMovementMethodExt();
            ((LinkMovementMethodExt)sInstance).handler = _handler;
            ((LinkMovementMethodExt)sInstance).spanClass = _spanClass;
        }

        return sInstance;
    }

    int x1;
    int x2;
    int y1;
    int y2;

     @Override
        public boolean onTouchEvent(TextView widget, Spannable buffer,
                                    MotionEvent event) {
            int action = event.getAction();

            if (event.getAction() == MotionEvent.ACTION_DOWN){
                x1 = (int) event.getX();
                y1 = (int) event.getY();
            }

            if (event.getAction() == MotionEvent.ACTION_UP) {
                x2 = (int) event.getX();
                y2 = (int) event.getY();

            if (Math.abs(x1 - x2) < 10 && Math.abs(y1 - y2) < 10) {

                x2 -= widget.getTotalPaddingLeft();
                y2 -= widget.getTotalPaddingTop();

                x2 += widget.getScrollX();
                y2 += widget.getScrollY();

                Layout layout = widget.getLayout();
                int line = layout.getLineForVertical(y2);
                int off = layout.getOffsetForHorizontal(line, x2);
                /**
                 * get you interest span
                 */
                Object[] spans = buffer.getSpans(off, off, spanClass);
                if (spans.length != 0) {

                    Selection.setSelection(buffer,
                            buffer.getSpanStart(spans[0]),
                            buffer.getSpanEnd(spans[0]));
                    MessageSpan obj = new MessageSpan();
                    obj.setObj(spans);
                    obj.setView(widget);
                    Message message = handler.obtainMessage();
                    message.obj = obj;
                    message.what = 200;
                    message.sendToTarget();
                    return true;
                }
            }
            }             
            return super.onTouchEvent(widget, buffer, event);                        
        }

     public boolean canSelectArbitrarily() {
            return true;
        }

    public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
            KeyEvent event) {
        return false;
    }
}

这样,我们就可以在mainactivity里面根据需要处理了:

public class MainActivity extends AppCompatActivity {

private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tv = (TextView) findViewById(R.id.tv);
    ScrollView sv = (ScrollView) findViewById(R.id.sv);

    final String html = "下面是第一张图片了 " + "<img src='https://ss3.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/image/h%3D200/sign=1870ec20a96eddc439e7b3fb09dab6a2/dbb44aed2e738bd4a59870f4a58b87d6267ff9be.jpg'/>" +
            "这也是第二张图片" + "<img src='https://ss1.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/image/h%3D200/sign=9d3833093f292df588c3ab158c305ce2/d788d43f8794a4c274c8110d0bf41bd5ad6e3928.jpg'/>" +
            "最后一张" + "<img src = 'http://f.hiphotos.baidu.com/image/h%3D200/sign=3d746172a4efce1bf52bcfca9f50f3e8/bba1cd11728b47101489df48c0cec3fdfd03238b.jpg'/>";

    tv.setText(Html.fromHtml(html, new MImageGetter(tv, getApplicationContext()), null));
    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            int what = msg.what;
            if (what == 200) {
                MessageSpan ms = (MessageSpan) msg.obj;
                Object[] spans = (Object[]) ms.getObj();
                final ArrayList<String> list = new ArrayList<>();
                for (Object span : spans) {
                    if (span instanceof ImageSpan) {
                        Log.i("picUrl==", ((ImageSpan) span).getSource());
                        list.add(((ImageSpan) span).getSource());
                        Intent intent = new Intent(getApplicationContext(), ImageGalleryActivity.class);
                        intent.putStringArrayListExtra("images", list);
                        startActivity(intent);
                    }
                }
            }
        }
    };
    tv.setMovementMethod(LinkMovementMethodExt.getInstance(handler, ImageSpan.class));
}
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 中,可以使用 SpannableString 类来实现文本的样式设置和图文混排。下面是一个简单的示例代码: ```java TextView textView = findViewById(R.id.textView); // 创建一个 SpannableString SpannableString spannableString = new SpannableString("这是一段带图片的文字"); // 加载图片资源 Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher_background); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); // 创建一个 ImageSpan ImageSpan imageSpan = new ImageSpan(drawable); // 设置图片的位置和大小 spannableString.setSpan(imageSpan, 5, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); // 设置文字的颜色和大小 ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.RED); RelativeSizeSpan sizeSpan = new RelativeSizeSpan(1.5f); spannableString.setSpan(colorSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); spannableString.setSpan(sizeSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); // 将 SpannableString 设置到 TextViewtextView.setText(spannableString); ``` 上述代码中,我们首先创建了一个 `SpannableString` 对象,然后通过 `getResources().getDrawable()` 方法加载一张图片,创建一个 `ImageSpan` 对象,并将其设置到 `SpannableString` 中。接着,我们通过 `ForegroundColorSpan` 和 `RelativeSizeSpan` 类来设置文字的颜色和大小,并将它们设置到 `SpannableString` 中。最后,我们将 `SpannableString` 设置到 `TextView` 中显示出来。 需要注意的是,`setSpan()` 方法的第二个参数和第三个参数分别表示样式的起始位置和结束位置,它们的单位是字符的索引值。在上述示例中,我们将图片设置到了第 6 个字符的位置,因此第二个参数为 5,第三个参数为 6。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值