Android HTML.fromHtml解析图片标签

在之前Html类支持的HTML标签文章中了解到当解析到<img>标签时就会回调getDrawable()方法,并需要返回一个Drawable对象;当前我们需要定义类并实现ImageGetter接口以及在getDrawable()方法中做相应的处理,下面我们则来看看具体该如何处理:

/**
 * ImageGetter接口的使用
 * @author yezhou
 */
public class ImgLabelActivity extends Activity {

    private static final String TAG = "ImgLabelActivity";
    /**本地图片*/
    private TextView mTvOne;
    /**项目资源图片*/
    private TextView mTvTwo;
    /**网络图片*/
    private TextView mTvThree;
    /**网络图片name*/
    private String picName = "networkPic.jpg";
    /**网络图片Getter*/
    private NetworkImageGetter mImageGetter;
    /**网络图片路径*/
    private String htmlThree = "网络图片测试:" + "<img src='http://www.yezhou.me/images/zhanghanyun.png'>";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_img_label);

        mTvOne = (TextView) this.findViewById(R.id.tv_img_label_one);
        String htmlOne = "本地图片测试:" + "<img src='/mnt/sdcard/imgLabel.jpg'>";
        mTvOne.setText(Html.fromHtml(htmlOne, new LocalImageGetter(), null));

        mTvTwo = (TextView) this.findViewById(R.id.tv_img_label_two);
        String htmlTwo = "项目图片测试:" + "<img src=\"" + R.drawable.imagepro+"\">";
        mTvTwo.setText(Html.fromHtml(htmlTwo, new ProImageGetter(), null));

        mTvThree = (TextView) this.findViewById(R.id.tv_img_label_three);
        mImageGetter = new NetworkImageGetter();
        mTvThree.setText(Html.fromHtml(htmlThree, mImageGetter, null));
    }

    /**
     * 本地图片
     * @author yezhou
     */
    private final class LocalImageGetter implements Html.ImageGetter {
        @Override
        public Drawable getDrawable(String source) {
            // 获取本地图片
            Drawable drawable = Drawable.createFromPath(source);
            // 必须设为图片的边际,不然TextView显示不出图片
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            // 将其返回
            return drawable;
        }
    }

    /**
     * 项目资源图片
     * @author yezhou
     */
    private final class ProImageGetter implements Html.ImageGetter {
        @Override
        public Drawable getDrawable(String source) {
            // 获取到资源id
            int id = Integer.parseInt(source);
            Drawable drawable = getResources().getDrawable(id);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            return drawable;
        }
    }

    /**
     * 网络图片
     * @author yezhou 
     */
    private final class NetworkImageGetter implements Html.ImageGetter {
        @Override
        public Drawable getDrawable(String source) {
            Drawable drawable = null;
            // 封装路径  
            File file = new File(Environment.getExternalStorageDirectory(), picName);
            // 判断是否以http开头
            if(source.startsWith("http")) {
                // 判断路径是否存在
                if(file.exists()) {
                    // 存在即获取drawable
                    drawable = Drawable.createFromPath(file.getAbsolutePath());
                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                } else {
                    // 不存在即开启异步任务加载网络图片
                    AsyncLoadNetworkPic networkPic = new AsyncLoadNetworkPic();
                    networkPic.execute(source);
                }
            }
            return drawable;
        }
    }

    /**
     * 加载网络图片异步类
     * @author yezhou
     */
    private final class AsyncLoadNetworkPic extends AsyncTask<String, Integer, Void> {
        @Override
        protected Void doInBackground(String... params) {
            // 加载网络图片
            loadNetPic(params);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // 当执行完成后再次为其设置一次  
            mTvThree.setText(Html.fromHtml(htmlThree, mImageGetter, null));
        }

        /**加载网络图片*/
        private void loadNetPic(String... params) {
            String path = params[0];
            File file = new File(Environment.getExternalStorageDirectory(), picName);
            InputStream in = null;
            FileOutputStream out = null;
            try {
                URL url = new URL(path);
                HttpURLConnection connUrl = (HttpURLConnection) url.openConnection();
                connUrl.setConnectTimeout(5000);
                connUrl.setRequestMethod("GET");
                if(connUrl.getResponseCode() == 200) {
                    in = connUrl.getInputStream();
                    out = new FileOutputStream(file);
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = in.read(buffer))!= -1) {
                        out.write(buffer, 0, len);
                    }
                } else {
                    Log.i(TAG, connUrl.getResponseCode() + "");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

需要注意的是:

  • 在获取到drawable时需要为其设置边界,如没有设置的话TextView就不能显示该drawable;
  • 在加载网络图片时需要开启子线程去访问网络并将图片存储到本地,之后再次为其设置一次读取本地的图片;

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/18/android-html-fromhtml-parse-image-tag/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android HTML.fromHtml解析图片标签
在之前Html类支持的HTML标签文章中了解到当解析到<img>标签时就会回调getDrawable()方法,并需要返回一个Drawable对象;当前我们需要定义类并实现ImageG……
<<上一篇
下一篇>>
文章目录
关闭
目 录