Android TextView显示网络图片

前言:程序猿真的是有个通病啊,电梯上就在研究电梯的逻辑代码,走路看到红绿灯也会去研究算法,今天心情不错,于是就发了一个说说,发现某q空间中显示了我发的说说,但是我发的笑脸跟哭脸表情由于网络慢,很久才加载出来,于是我惊讶了,原来表情发的时候存在本地,等发完显示确实网络上拿的,而且还支持gif,好吧,不得不说某q真是牛逼!!

网上textView显示网络图片的例子一大堆啊,但是都不靠谱,于是我弄出了一个靠谱点的思路。

简单介绍下思路吧:
主要就是利用text.setText(Html.fromHtml(“html”));把后台返回的html显示在textview中,后台返回的html可能是这样的:

 String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";

那么如果img中包含的是一个网络的图片链接,我们的源码中有处理吗??我们接下来看看Html.fromHtml源码:

 @Deprecated
    public static Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler) {
        return fromHtml(source, FROM_HTML_MODE_LEGACY, imageGetter, tagHandler);
    }

接着往下看:

  public static Spanned fromHtml(String source, int flags, ImageGetter imageGetter,
            TagHandler tagHandler) {
      .......省略代码

        HtmlToSpannedConverter converter =
                new HtmlToSpannedConverter(source, imageGetter, tagHandler, parser, flags);
        return converter.convert();
    }

然后重点看一下HtmlToSpannedConverter类,在这个类中我们又看到了这么一个方法:

 private void handleStartTag(String tag, Attributes attributes) {
        if (tag.equalsIgnoreCase("br")) {
            // We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>
            // so we can safely emit the linebreaks when we handle the close tag.
        } else if (tag.equalsIgnoreCase("p")) {
            startBlockElement(mSpannableStringBuilder, attributes, getMarginParagraph());
            startCssStyle(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("ul")) {
            startBlockElement(mSpannableStringBuilder, attributes, getMarginList());
        } else if (tag.equalsIgnoreCase("li")) {
            startLi(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("div")) {
            startBlockElement(mSpannableStringBuilder, attributes, getMarginDiv());
        } else if (tag.equalsIgnoreCase("span")) {
            startCssStyle(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("strong")) {
            start(mSpannableStringBuilder, new Bold());
        } else if (tag.equalsIgnoreCase("b")) {
            start(mSpannableStringBuilder, new Bold());
        } else if (tag.equalsIgnoreCase("em")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("cite")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("dfn")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("i")) {
            start(mSpannableStringBuilder, new Italic());
        } else if (tag.equalsIgnoreCase("big")) {
            start(mSpannableStringBuilder, new Big());
        } else if (tag.equalsIgnoreCase("small")) {
            start(mSpannableStringBuilder, new Small());
        } else if (tag.equalsIgnoreCase("font")) {
            startFont(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("blockquote")) {
            startBlockquote(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("tt")) {
            start(mSpannableStringBuilder, new Monospace());
        } else if (tag.equalsIgnoreCase("a")) {
            startA(mSpannableStringBuilder, attributes);
        } else if (tag.equalsIgnoreCase("u")) {
            start(mSpannableStringBuilder, new Underline());
        } else if (tag.equalsIgnoreCase("del")) {
            start(mSpannableStringBuilder, new Strikethrough());
        } else if (tag.equalsIgnoreCase("s")) {
            start(mSpannableStringBuilder, new Strikethrough());
        } else if (tag.equalsIgnoreCase("strike")) {
            start(mSpannableStringBuilder, new Strikethrough());
        } else if (tag.equalsIgnoreCase("sup")) {
            start(mSpannableStringBuilder, new Super());
        } else if (tag.equalsIgnoreCase("sub")) {
            start(mSpannableStringBuilder, new Sub());
        } else if (tag.length() == 2 &&
                Character.toLowerCase(tag.charAt(0)) == 'h' &&
                tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
            startHeading(mSpannableStringBuilder, attributes, tag.charAt(1) - '1');
        } else if (tag.equalsIgnoreCase("img")) {
            startImg(mSpannableStringBuilder, attributes, mImageGetter);
        } else if (mTagHandler != null) {
            mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
        }
    }

重点看一下这个判断:

else if (tag.equalsIgnoreCase("img")) {
            startImg(mSpannableStringBuilder, attributes, mImageGetter);
        } 

我们看看startImg方法:

  private static void startImg(Editable text, Attributes attributes, Html.ImageGetter img) {
        String src = attributes.getValue("", "src");
        Drawable d = null;

        if (img != null) {
            d = img.getDrawable(src);
        }

        if (d == null) {
            d = Resources.getSystem().
                    getDrawable(com.android.internal.R.drawable.unknown_image);
            d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        }

        int len = text.length();
        text.append("\uFFFC");

        text.setSpan(new ImageSpan(d, src), len, text.length(),
                     Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

看到这里了如果做过TextView的富文本的童鞋有没有一点熟悉了呢?直接创建了一个ImageSpan,然后传入了一个Drawable,那么这个Drawable是哪里来的呢?
是通过 Html.ImageGetter的getDrawable方法获取的!! 那么这个mImageGetter对象有没有初始化呢? 我们在代码中找找:

是在fromHtml方法中传进去的,也就是说,如果我们不传ImageGetter对象的话,当获取到img标签时,如果ImageGetter为null,那么会走下面判断:

  if (img != null) {
            d = img.getDrawable(src);
        }

        if (d == null) {
            d = Resources.getSystem().
                    getDrawable(com.android.internal.R.drawable.unknown_image);
            d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        }

而unknown_image就是android系统默认给的一张占位图。

有了前面的了解了,然后我们就开动了,首先得创建一个ImageGetter对象在Html.fromHtml中传给TextView.然后当判断html中有img标签的时候,我们就去网络加载图片,加载完毕后再次赋给TextView.

由于代码简单,我就直接上代码了:

 public TextView text;
    private static class MyHandler extends Handler {
            private WeakReference<PropertyAnimActivity4_evaluator>activityWeakReference;
            public MyHandler(PropertyAnimActivity4_evaluator activity){
                activityWeakReference=new WeakReference<PropertyAnimActivity4_evaluator>(activity);
            }
            @Override
            public void handleMessage(Message msg) {
                final Drawable drawable= (Drawable) msg.obj;
                PropertyAnimActivity4_evaluator activity=activityWeakReference.get();
                if(activity!=null){
                    String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";
                    Spanned spanned = Html.fromHtml(html, new Html.ImageGetter() {
                        @Override
                        public Drawable getDrawable(String source) {
                            return drawable;
                        }
                    }, null);
                    activity.text.setText(spanned);
                }
            }
        }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_property_anim_activity4_evaluator);
        bt_anim_view= (Button) findViewById(R.id.bt_anim_view);
        text= (TextView) findViewById(R.id.text);
        String html="dfdfdf<img src=\"http://j1.s2.dpfile.com/pc/5e356bd48d39f4f7f1e37261c29841f5%28700x700%29/thumb.jpg\"/>fdfdfd";
        Spanned spanned = Html.fromHtml(html, new Html.ImageGetter() {
            @Override
            public Drawable getDrawable(String source) {
                AsyncTask<String, Float, Drawable> task = new AsyncTask<String, Float, Drawable>() {
                    @Override
                    protected Drawable doInBackground(String... params) {
                        try {
                            URL url=new URL(params[0]);
                            URLConnection con = url.openConnection();
                            con.setConnectTimeout(50000);
                            Drawable d = Drawable.createFromStream(con.getInputStream(), "");
                            d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
                            return d;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                    @Override
                    protected void onPostExecute(Drawable drawable) {
                        Message msg=Message.obtain();
                        msg.obj=drawable;
                        new MyHandler(PropertyAnimActivity4_evaluator.this).sendMessage(msg);
                    }
                }.execute(source);
                BitmapDrawable bitmapDrawable = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
                bitmapDrawable.setBounds(0,0,bitmapDrawable.getIntrinsicWidth(),bitmapDrawable.getIntrinsicHeight());
                return bitmapDrawable;
            }
        }, null);
        text.setText(spanned);

    }

如果是像某Q一样,放在ListView中,并且显示的是gif图片,又咋搞呢????? 小伙伴们如果有好的思路,或者做过类型的,一起探讨一下哈!!!拜谢啦~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值