android TextView 实现图文混排和超链接点击打开浏览器功能

业务场景:  在微信聊天窗口中需要显示文字图片和超链接时。

问题所在:  一般TextView只能显示

解决方案

                1、普通方式只能显示文本内容。

                2、 Html.fromHtml(html)只能显示html和超链接,图片不能显示。

                3、 Html.fromHtml+ImageGetter+URLSpan。(即能实现html,又能实现超链接和图片的显示)

实现过程

  需要以下三个类:

  1、从网络获取图片的类:NetImageGetter

package utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.os.AsyncTask;
import android.text.Html;
import android.widget.TextView;

/**
 * des:textView用于加载远端图片
 * 
 * @author Administrator
 * 
 */
public class NetImageGetter implements Html.ImageGetter {
    private Context context;
    private TextView contentTextView;
    private int width=0;
    
    public NetImageGetter(Context context,TextView contentTextView,int width)
    {
        this.context=context;
        this.contentTextView=contentTextView;
        this.width=width;
    }

    @Override
    public Drawable getDrawable(String source) {
        LevelListDrawable d = new LevelListDrawable();
        d.setBounds(0, 0, 300, 200);
        new LoadImage().execute(source, d);
        return d;
    }

    /**
     * 异步下载图片类
     * 
     * @author Ruffian
     * @date 2016年1月15日
     * 
     */
    class LoadImage extends AsyncTask {

        private LevelListDrawable mDrawable;

        @Override
        protected Bitmap doInBackground(Object... params) {
            String source = (String) params[0];
            mDrawable = (LevelListDrawable) params[1];
            try {
                InputStream is = new URL(source).openStream();
                return BitmapFactory.decodeStream(is);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 图片下载完成后执行
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null) {
                BitmapDrawable d = new BitmapDrawable(bitmap);
                mDrawable.addLevel(1, 1, d);
                mDrawable = getDrawableAdapter(context, mDrawable,
                        bitmap.getWidth(), bitmap.getHeight());
                // mDrawable.setBounds(0, 0, bitmap.getWidth(),
                // bitmap.getHeight());
                mDrawable.setLevel(1);
                contentTextView.invalidate();
                CharSequence t = contentTextView.getText();
                contentTextView.setText(t);
            }
        }

        public LevelListDrawable getDrawableAdapter(Context context,
                LevelListDrawable drawable, int oldWidth, int oldHeight) {
            LevelListDrawable newDrawable = drawable;
            long newHeight = 0;// 未知数
            int newWidth = width;// 默认屏幕宽
            newHeight = (newWidth * oldHeight) / oldWidth;
            newDrawable.setBounds(0, 0, newWidth, (int) newHeight);
            return newDrawable;
        }
    }

}

 

2、给TextView内html加入超链接点击事件的类:MyURLSpan

/**
     * 加入超链接处理
     * @author Administrator
     *
     */
    private static class MyURLSpan extends ClickableSpan {
        private String mUrl;
        private Context mContext;

        MyURLSpan(String url, Context context) {
            mContext = context;
            mUrl = url;
        }

        @Override
        public void onClick(View widget) {
            Intent intent = new Intent();
            intent.setAction("android.intent.action.VIEW");
            Uri content_url = Uri.parse(mUrl);
            intent.setData(content_url);
            intent.setClassName("com.android.browser",
                    "com.android.browser.BrowserActivity");
            this.mContext.startActivity(intent);
        }
    }

 

3、实现显示带图片和超链接的html到TextView中的类:

package utils;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;

public class TextViewUtil {

    /**
     * des:设置html到textview中
     * 
     * @param contentView
     * @param html
     * @param width
     *            图片显示区域宽度,根据不同情况显示不同大小
     */
    public static void setHtmlToTextView(Context context, TextView contentView,
            String html, int width) {
        NetImageGetter netImageGetter = new NetImageGetter(context,
                contentView, width);
        Spanned text = Html.fromHtml(html, netImageGetter, null);
        contentView.setMovementMethod(LinkMovementMethod.getInstance());
        contentView.setText(text);

        CharSequence charSequence = contentView.getText();
        if (charSequence instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) contentView.getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            for (URLSpan url : urls) {
                MyURLSpan myURLSpan = new MyURLSpan(url.getURL(), context);
                style.setSpan(myURLSpan, sp.getSpanStart(url),
                        sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
            }
            contentView.setText(style);
        }
    }

    /**
     * 加入超链接处理
     * @author Administrator
     *
     */
    private static class MyURLSpan extends ClickableSpan {
        private String mUrl;
        private Context mContext;

        MyURLSpan(String url, Context context) {
            mContext = context;
            mUrl = url;
        }

        @Override
        public void onClick(View widget) {
            Intent intent = new Intent();
            intent.setAction("android.intent.action.VIEW");
            Uri content_url = Uri.parse(mUrl);
            intent.setData(content_url);
            intent.setClassName("com.android.browser",
                    "com.android.browser.BrowserActivity");
            this.mContext.startActivity(intent);
        }
    }

}
 

你可能感兴趣的:(java,android)