Android点滴---TextView,RadioButton 设置 HTML文本,加载网络图片


现在在做一个题库类的项目,由于有些数学符号或者化学符号之类的没办法直接在前端显示,所以就使用了图文混排;

后台返回的数据直接是HTML格式的数据。


所以就开始去研究控件如何去显示HTML


先贴上参考的文章,感谢分享!


1、这种只适合加载本地图片,或者兼容版本在4.0以下

Android中Textview显示带html文本二-------【Textview显示本地图片】


上面这种方式,只要在百度上搜一下 Android TextView 设置 HTML 数据,就会找出来很多类似的,但是感觉这为大神写的最好!


如果HTML数据中,只有文本的话,使用下面的写法就Ok了,

        //如果 HTML数据中没有图片,仅仅是文本的话,直接这样设置就好了
        String html = "<p>这个就是测试</p><span>数据</span><img src=\"http://as114.com/pic/logo.png\" />";
        
        TextView mTvHello = (TextView) this.findViewById(R.id.tv_hello);
        mTvHello.setText(Html.fromHtml(html));


如果HTML数据中包含本地图片路径,你可以参考上面链接里,这位大神些的两种方式就可以了

        //主要是多了这个加载图片的参数
        Html.ImageGetter imageGetter = new Html.ImageGetter() {

            @Override
            public Drawable getDrawable(String source) {
                
                //实现方式可以参考上面的帖子,根据自己的需求来实现
                return null;
            }
        };

        //Html。fromHtml时  加上上面的参数
        mTvHello.setText(Html.fromHtml(html,imageGetter,null));


其实如果你的项目只兼容到 4.0以下,并且不怕卡的话,上面的帖子里也有实现方式(但是这种需求估计现在没有!技术分享

说一下原因,4.0以下是可以再主线程请求网络的,但是4.0以后是不可以在主线程请求网络,

        url = new URL(source);
        drawable = Drawable.createFromStream(url.openStream(), "");

上面这种写法就要在主线程加载图片, 虽然4.0以下可以使用,但是如果图片大的话,估计就直接卡死了,所以还是不要用了!

如果是本地图片的话,可以使用帖子中的两种图片方式,根据自己的需求来实现就OK了;


2、异步加载HTML中的图片  参考文章(stackoverflow 上的,有时候可以能访问不了,自己找办法……)

Android HTML ImageGetter as AsyncTask


上面的帖子完美解决了问题!

贴出代码,省的某些朋友不能访问帖子,看不了代码


import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

/**
 * Created by Administrator on 2015/4/30.
 */
public class URLDrawable extends BitmapDrawable{
    // the drawable that you need to set, you could set the initial drawing
    // with the loading image if you need to
    protected Drawable drawable;

    @Override
    public void draw(Canvas canvas) {
        // override the draw to facilitate refresh function later
        if(drawable != null) {
            drawable.draw(canvas);
        }
    }
}

package com.jddl.tvhtmldemo;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.text.Html;
import android.view.View;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;

/**
 * Created by Administrator on 2015/4/30.
 */
public class URLImageParser implements Html.ImageGetter {
    Context c;
    View container;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * Construct the URLImageParser which will execute AsyncTask and refresh the container
     *
     * @param t
     * @param c
     */
    public URLImageParser(View t, Context c) {
        this.c = c;
        this.container = t;
    }

    public Drawable getDrawable(String source) {
        URLDrawable urlDrawable = new URLDrawable();

        // get the actual source
        ImageGetterAsyncTask asyncTask =
                new ImageGetterAsyncTask(urlDrawable);

        asyncTask.execute(source);

        // return reference to URLDrawable where I will change with actual image from
        // the src tag
        return urlDrawable;
    }

    public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
        URLDrawable urlDrawable;

        public ImageGetterAsyncTask(URLDrawable d) {
            this.urlDrawable = d;
        }

        @Override
        protected Drawable doInBackground(String... params) {
            String source = params[0];
            return fetchDrawable(source);
        }

        @Override
        protected void onPostExecute(Drawable result) {
            // set the correct bound according to the result from HTTP call
            urlDrawable.setBounds(0, 0, result.getIntrinsicWidth(), result.getIntrinsicHeight());

            // change the reference of the current drawable to the result
            // from the HTTP call
            urlDrawable.drawable = result;

            // redraw the image by invalidating the container
            URLImageParser.this.container.invalidate();
        }

        /**
         * Get the Drawable from URL
         *
         * @param urlString
         * @return
         */
        public Drawable fetchDrawable(String urlString) {
            try {
                InputStream is = fetch(urlString);
                Drawable drawable = Drawable.createFromStream(is, "src");
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            } catch (Exception e) {
                return null;
            }
        }

        private InputStream fetch(String urlString) throws MalformedURLException, IOException {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet request = new HttpGet(urlString);
            HttpResponse response = httpClient.execute(request);
            return response.getEntity().getContent();
        }
    }

    public URLImageParser() {
        super();
    }
}



由于我的项目中有选择题,和单选题,所以我用到了 TextView , RadioButton  和  CheckBox 三种控件,

下面是使用时的代码

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView mTvHello = (TextView) this.findViewById(R.id.tv_hello);

        String html = "<p>这个就是测试</p><span>数据</span><img src=\"http://as114.com/pic/logo.png\" />";

        mTvHello.setMovementMethod(ScrollingMovementMethod.getInstance());
        URLImageParser urlImgGetter = new URLImageParser(mTvHello, this);
        mTvHello.setText(Html.fromHtml(html, urlImgGetter, null));

        RadioButton mRbHtml = (RadioButton) this.findViewById(R.id.rb_html);
        URLImageParser urlImgGetterRb = new URLImageParser(mRbHtml, this);
        mRbHtml.setText(Html.fromHtml(html, urlImgGetterRb, null));

        CheckBox mCbHtml = (CheckBox) this.findViewById(R.id.cb_html);
        URLImageParser urlImgGetterCb = new URLImageParser(mCbHtml, this);
        mRbHtml.setText(Html.fromHtml(html, urlImgGetterCb, null));
    }
}

简单说一下我的理解(小弟 从事Android 不长,如有理解错误还请大家多多指教!技术分享


URLImageParser 类实现了 Html.ImageGetter 接口, 写法和别的没什么区别,

在getDrawable先返回一个urlDrawable,是一个空的图片


然后使用,异步加载图片,加载完成后在刷新图片和View

思路貌似很简单,但是之前没想着怎么实现!

再次感谢分享!


因为大多数都是写的TextView 使用的方法,

但是我想: 因为RadioButton 和 Checkbox 都是 TextView  的子类,所以应该也可以使用!

最终测试证明的想法是可行的,贴上 运行照片


技术分享


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。