TextView展示Html内可点击图片

在使用Html.fromHtml(String source)时如果源字符中包含图片里并不会展示出来,需要我们另作处理,本文并参照LinkMovementMethod增加图片点击事件,切图如下微笑:


代码如下,如有不对之处欢迎指正微笑

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;
import android.widget.Toast;

import com.chiigu.demo.util.ImageLinkMovementMethod;

import java.net.URL;

public class MainActivity extends AppCompatActivity {
    private TextView tv_show;
    private String imageSourceUrl;
    private Drawable drawable;
    private String html;

    private final Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    showHtml(tv_show);
                    break;
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main1);
        tv_show = (TextView) findViewById(R.id.tv_show);
        html = "<html><head><title>TextView使用HTML</title></head><body><p><strong>强调</strong></p><p><em>斜体</em></p>"
                + "<p><a href=\"http://www.dreamdu.com/xhtml/\">超链接HTML入门</a>学习HTML!</p><p>" +
                "下面是网络图片</p><img src=\"http://www.uimaker.com/uploads/allimg/120416/1_120416091247_1.jpg\"/>图片描述</body></html>";
        tv_show.setText(Html.fromHtml(html, new Html.ImageGetter() {//展示文本 获取资源url
            public Drawable getDrawable(String source) {
                imageSourceUrl = source;//此处针对一个图片来定 如果有多个图片引用 可以在此处将source存入一个List列表
                return null;
            }
        }, null));
        tv_show.setMovementMethod(LinkMovementMethod.getInstance());

        new Thread() {//开始线程 获取图片
            @Override
            public void run() {
                super.run();
                URL url;
                try {
                    url = new URL(imageSourceUrl);
                    drawable = Drawable.createFromStream(url.openStream(), "");  //获取网路图片
                    handler.sendEmptyMessage(0);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void showHtml(final TextView textView) {
        if (drawable == null) return;
        textView.setText(Html.fromHtml(html, new Html.ImageGetter() {//图片资源获取成功将其展示出来
            public Drawable getDrawable(String source) {
                int width = drawable.getIntrinsicWidth();
                int height = drawable.getIntrinsicHeight();

                //此段可依情况而定是否需要加上 目标是为了将小于控件宽度的图片比例放大至适配控件
                int widgetWidth = textView.getMeasuredWidth() - textView.getTotalPaddingLeft() - textView.getTotalPaddingRight();
                if (width < widgetWidth) {
                    height = widgetWidth * height / width;
                    width = widgetWidth;
                }

                drawable.setBounds(0, 0, width, height);
                return drawable;
            }
        }, null));
        ImageLinkMovementMethod imageLink = new ImageLinkMovementMethod();//给图片设置点击事件
        imageLink.setOnImageClickListen(new ImageLinkMovementMethod.OnImageClickListen() {
            @Override
            public void click(String source) {
                Toast.makeText(Main1Activity.this, "点击了:" + source, Toast.LENGTH_LONG).show();
            }
        });
        tv_show.setMovementMethod(imageLink);
    }

}

相关的图片点击事件的代码如下:

import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * 参照LinkMovementMethod的源码onTouchEvent方法生成,目的为的是图片能够响应点击事件
 */
public class ImageLinkMovementMethod extends LinkMovementMethod {

    private int downX;
    private int downY;

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer,
                                MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) event.getX();
                downY = (int) event.getY();
                break;
            case MotionEvent.ACTION_UP:
                int upX = (int) event.getX();
                int upY = (int) event.getY();
                if (Math.abs(upX - downX) < 10 && Math.abs(upY - downY) < 10) {
                    upX -= widget.getTotalPaddingLeft();
                    upY -= widget.getTotalPaddingTop();

                    upX += widget.getScrollX();
                    upY += widget.getScrollY();

                    Layout layout = widget.getLayout();
                    int line = layout.getLineForVertical(upY);
                    int off = layout.getOffsetForHorizontal(line, upX);

                    ImageSpan[] link = buffer.getSpans(off, off, ImageSpan.class);
                    if (link.length != 0) {
                        Selection.setSelection(buffer,
                                buffer.getSpanStart(link[0]),
                                buffer.getSpanEnd(link[0]));
                        if(listen!=null)
                            listen.click(link[0].getSource());
                        return true;
                    } else {
                        Selection.removeSelection(buffer);
                    }
                }
                break;
        }
        return super.onTouchEvent(widget, buffer, event);
    }

    private OnImageClickListen listen;

    public void setOnImageClickListen(OnImageClickListen listen){
        this.listen=listen;
    }

    public interface OnImageClickListen{
        void click(String source);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值