TextView加载html代码显示图片,并且支持图片放大功能

这篇博客介绍了如何在TextView中加载html代码并显示图片,同时实现了图片点击后放大功能。通过使用UniversalImageLoader库加载图片,自定义ImageGetter和TagHandler处理图片点击事件。在遇到图片超出屏幕滚动的问题时,博主建议使用ScrollView包裹TextView。对于图片放大功能,博主利用PopupWindow和ImageView的缩放特性,编写了MyTagHandler类,完成图片点击后的放大效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.加载简单的html代码
textview.setText(Html.from(text));
2.加载图片显示,用的是imageloader加载图片,用as的可以直接在build.gradle里面加上
compile ‘com.nostra13.universalimageloader:universal-image-loader:1.9.5’
不过这个需要在程序入口初始化一下,否则会报错

ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(this));

重写ImageGetter,加载图片

public class URLImageParser implements ImageGetter {
    TextView mTextView;

    public URLImageParser(TextView textView) {
        this.mTextView = textView;
    }

    @Override
    public Drawable getDrawable(String source) {
        LogUtils.i("图片地址source:"+source);
        final URLDrawable urlDrawable = new URLDrawable();
        ImageLoader.getInstance().loadImage(source, 
        new SimpleImageLoadingListener() {
            @Override
            public void onLoadingComplete(String imageUri, View view,                      Bitmap loadedImage) {
                urlDrawable.bitmap = loadedImage;
                urlDrawable.setBounds(0, 0, loadedImage.getWidth(), loadedImage.getHeight());
                mTextView.invalidate();
                mTextView.setText(mTextView.getText()); 
            }
        });
        return urlDrawable;
    }
}
public class URLDrawable extends BitmapDrawable {
    protected Bitmap bitmap;
    @Override
    public void draw(Canvas canvas) {
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, 0, 0, getPaint());
        }
    }
}

在代码中设置一下就能显示图片了

URLImageParser imageGetter = new URLImageParser(textview);
textview.setText(Html.fromHtml('要解析的字符串', imageGetter, null));

3.设置图片的可点击事件,使用到的是Html.fromHtml中的第三个参数TagHandler
还是要重写一下咯

public class MyTagHandler implements Html.TagHandler {

    private Context mContext;

    public MyTagHandler(Context context) {
        mContext = context.getApplicationContext();
    }

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
        // 处理标签<img>
        if (tag.toLowerCase(Locale.getDefault()).equals("img")) {
            // 获取长度
            int len = output.length();
            // 获取图片地址
            ImageSpan[] images = output.getSpans(len - 1, len, ImageSpan.class);
            String imgURL = images[0].getSource();
            // 使图片可点击并监听点击事件
            output.setSpan(new ClickableImage(mContext, imgURL), len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
    private class ClickableImage extends ClickableSpan {
        private String url;
        private Context context;
        public ClickableImage(Context context, String url) {
            this.context = context;
            this.url = url;
        }
        @Override
        public void onClick(View widget) {
            // 进行图片点击之后的处理
        }
    }
}

再设置一下就可以获得图片的点击事件啦

URLImageParser imageGetter = new URLImageParser(textview);
MyTagHandler tagHandler = new MyTagHandler(this);
//设置这个图片才能点击
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(returnHtml, imageGetter, tagHandler));

4.以上都是我在网上翻来翻去总结出来的啦,开始出现了加载两张图片超过一屏滑动有问题(其实是我太蠢了),哈哈,滑动嘛,在textview的外面套一个scrollview就可以了,如果不可以你也不能打我哦

5.找了很久发现都没有说好的点击图片放大呀,想了很久。。才想通。。不会是要我自己写放大图片的触发事件吧,虽然我很懒(忽略我的智商,假装是我懒),但是没有轮子还是要自己造轮子的嘛,那就造一个,以下图片放大纯属乱写,如果可以你不要夸我,不可以你也不要打我,有bug记得告诉我,啦啦啦。。。咳咳,开始写
还是在网上找的imageview图片缩放,我已经忘了作者是谁了。。反正不是我

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;

/**
 * 可以进行两指缩放,并且可以进行拖拉的ImageView最简单原生的实现
 *
 * @author Seal
 *         Created on 2014年5月15日 下午2:08:49
 * @note
 */
public class ScaleImageView extends ImageView {
    private float lastX, lastY;// 上一次记录的点
    private float lastDistance;//上一次两点间的距离

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

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = event.getX();
                lastY = event.getY();

                break;
            case MotionEvent.ACTION_MOVE:
                if (event.getPointerCount() == 2) {//两点触摸
                    final float disX = Math.abs(event.getX(0) - event.getX(1));//第一个点的偏移量
                    final float disY = Math.abs(event.getY(0) - event.getY(1));//第二个点的偏移量
                    final float dis = (float) Math.sqrt(disX * disX + disY * disY);//记录两点间的距离
                    if (lastDistance == 0) {
                        lastDistance = dis;//记录第一次
                    } else {
                        float scale = dis / lastDistance;
                        lastDistance = dis;//替换上一次
                        scaleImage(scale);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                lastX = 0;//恢复初始化状态
                lastY = 0;
                lastDistance = 0;
                break;
            default:
                break;
        }

        super.onTouchEvent(event);
        return true;
    }

    /**
     * 进行缩放
     *
     * @param scale
     */
    private void scaleImage(float scale) {
        final int width = getWidth();
        final int newWidth = (int) (width * scale);
        final int height = getHeight();
        final int newHeight = (int) (height * scale);
        LayoutParams params = getLayoutParams();
        params.height = newHeight;
        params.width = newWidth;
        setLayoutParams(params);
    }

}

没错现在缩放的控件已经有了那要怎么点击放大呢!!!我用了popupwindow
所以我重新写了一下MyTagHandler

/**
 * Created by ytt on 2016/12/9.
 */
public class MyTagHandler implements Html.TagHandler {

    private Context mContext;
    private PopupWindow popupWindow;
    //需要放大的图片
    private ScaleImageView tecent_chat_image;
    //加载中的进度条
    private ProgressBar image_scale_progress;
    public MyTagHandler(Context context) {
        mContext = context.getApplicationContext();
        View popView = LayoutInflater.from(context).inflate(R.layout.image_scale, null);
        tecent_chat_image = (ScaleImageView) popView.findViewById(R.id.image_scale_image);
        image_scale_progress= (ProgressBar) popView.findViewById(R.id.image_scale_progress);

        popView.findViewById(R.id.image_scale_rll).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(popupWindow!=null && popupWindow.isShowing()){
                    popupWindow.dismiss();
                }
            }
        });
        popupWindow = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);// 设置允许在外点击消失
        ColorDrawable dw = new ColorDrawable(0x50000000);
        popupWindow.setBackgroundDrawable(dw);
    }

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
        Log.i("ytp", "opening:" + opening);
        // 处理标签<img>
        if (tag.toLowerCase(Locale.getDefault()).equals("img")) {
            // 获取长度
            int len = output.length();
            // 获取图片地址
            ImageSpan[] images = output.getSpans(len - 1, len, ImageSpan.class);
            String imgURL = images[0].getSource();

            Log.i("ytp", "imgURL:" + imgURL);
            // 使图片可点击并监听点击事件
            output.setSpan(new ClickableImage(mContext, imgURL), len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
    private class ClickableImage extends ClickableSpan {
        private String url;
        private Context context;
        public ClickableImage(Context context, String url) {
            this.context = context;
            this.url = url;
        }
        @Override
        public void onClick(View widget) {
            // 进行图片点击之后的处理
            Log.i("ytp", "点击了图片:url:" + url);
            image_scale_progress.setVisibility(View.VISIBLE);
            popupWindow.showAtLocation(widget, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
            ImageLoader.getInstance().loadImage(url, new ImageLoadingListener(){
                @Override
                public void onLoadingStarted(String imageUri, View view) {
                }

                @Override
                public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                }

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    tecent_chat_image.setImageBitmap(loadedImage);
                    image_scale_progress.setVisibility(View.GONE);
                }

                @Override
                public void onLoadingCancelled(String imageUri, View view) {
                }
            });
        }
    }
}

还有一个popview R.layout.image_scale

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/image_scale_rll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#66000000"
    android:clickable="true">

    <cn.wangxiao.utils.ScaleImageView
        android:id="@+id/image_scale_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <ProgressBar
        android:id="@+id/image_scale_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@android:style/Widget.Holo.ProgressBar.Small"
        android:layout_centerInParent="true"/>
</RelativeLayout>

设置一下

URLImageParser imageGetter = new URLImageParser(textview);
MyTagHandler tagHandler = new MyTagHandler(this);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(returnHtml, imageGetter, tagHandler));

6.大功告成,噢耶,不知道有没有人看,反正我就乱写写,给自己么么哒,给看的你也么么哒~~毕竟我还在加班

不知道要写原创还是写转载,选择困难症,怎么办~~~原创?转载? 转载+原创?额,那我就脸皮厚一点选个原创?嗯!好的!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值