前几天在做一个Gradle用户指南的应用程序,使用的是TextView来加载HTML内容(至于为什么不用WebView,我也没有认真使用并比较过,也许以后会换吧),其中遇见了一些纠结的问题,所幸主要的问题都一一解决了。

下面说一下遇见的几个问题及我的解决方法。

TextView异步加载HTML中的图片及图文重叠

在TextView中加载HTML图片,需要实现Html.ImageGetter接口,然后在public Drawable getDrawable(String source)中去获取图片。图片获取我是直接使用了ImageLoader,一来加载图片省事,二来带缓存功能,正是我想要的。但是getDrawable方法是在主线程中调用的,且要求返回Drawable对象用于显示,而我们是不能在主线程中进行网络访问的,所以需要异步加载。ImageLoader本身已经有异步加载的功能,所以我们需要将它与getDrawable方法结合起来。这里用的方法与百度上常见到的方法略有不同,因为百度上的方法在我这里会有BUG,在第二次进入时图片经常加载不出来。

首先,写一个类继承BitmapDrawable,代码如下:

package com.githang.gradledoc.chapter;

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

/**
 * User: Geek_Soledad(msdx.android@qq.com)
 * Date: 2014-11-30
 * Time: 00:09
 * FIXME
 */
public class URLDrawable extends BitmapDrawable {
    protected Bitmap bitmap;

    @Override
    public void draw(Canvas canvas) {
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, 0, 0, getPaint());
        }
    }
}

这个类用于在getDrawable中返回的对象。

然后写一个类实现Html.ImageGetter接口,代码如下:

    public class URLImageParser implements Html.ImageGetter {
        TextView mTextView;

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

        @Override
        public Drawable getDrawable(String source) {
            final URLDrawable urlDrawable = new URLDrawable();
            Log.d("ChapterActivity", Consts.BASE_URL + source);
            ImageLoader.getInstance().loadImage(Consts.BASE_URL + 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;
        }
    }

这里的mTextView是我们要加载图片的TextView对象。这里我暂未对图片做自适应屏幕的适配,做的比较简单,只是把加载后的图片设置到之前返回的URLDrawable对象中的urlDrawable去,然后调用mTextView.invalidate()方法更新界面。

但是这样写完之后,还有一个问题。尽管我们对urlDrawable调用了setBounds设置它的边框,但是还是会出现图片重叠的问题。需要重新设置一下mTextView的内容,如上面代码中的:

mTextView.setText(mTextView.getText());

设置HTML到TextView的代码如下:

mDocView.setText(Html.fromHtml(doc, new URLImageParser(mDocView), null));

显示的代码格式全乱

TextView虽然可以显示html,但许多标签并不能支持。比如用于显示代码的<pre>,<code>这些标签。原本以为TagHandler可以解决这个问题,但是我在看了网上对TagHandler的用法介绍之后,发现这种用法并不能处理我遇见的这个问题,因为它只能处理解析到的标签之前的内容,无法处理标签之后的内容。好在我在设置HTML的内容到TextView之前是有用jsoup进行一些处理的,于是决定用jsoup进行处理。
处理方法很简单,对<pre>里的标签,把换行符替换成<br/>,把空格替换成&nbsp;,代码如下:
    /**
     * 处理代码显示问题.
     *
     * @param chapter 章节内容的html元素。
     */
    private void handlerPreTag(Element chapter) {
        Elements preElems = chapter.select("pre");
        for (Element elem : preElems) {
            elem.html(elem.html().replaceAll("\n", "<br/>").replaceAll(" ", " "));
        }
    }

最后上两张解决这个问题后的效果图:



本文原创,转载请注明出处:http://blog.csdn.net/maosidiaoxian/article/details/41673425

Android开发技巧——TextView加载HTML的图片及代码显示问题的更多相关文章

  1. Android开发之高效加载Bitmap

    一.概述 在Android开发中,我们经常与Bitmap打交道,而对Bitmap的不恰当的操作经常会导致OOM(Out of Memory).这篇文章我们会介绍如何高效地在Android开发中使用Bi ...

  2. Android开发问题积累 <加载在线Gif><WebView无法加载网页图片>

    在线Gif加载 解决办法 Glide完美解决 Glide.with(context).load(pic).placeholder(R.drawable.loading).into(imageView) ...

  3. Android 开发 上拉加载更多功能实现

    实现思维 开始之前先废话几句,Android系统没有提供上拉加载的控件,只提供了下拉刷新的SwipeRefreshLayout控件.这个控件我们就不废话,无法实现上拉刷新的功能.现在我们说说上拉加载更 ...

  4. android开发--使用webView加载tel协议不会打开拨号盘解决

    在加载url之前进行判断,url是否是tel协议开头,然后进行加载,即可打开拨号盘 mWebView.setWebViewClient(new WebViewClient() { @Override ...

  5. Android开发技巧——ViewPager加View情况封装PagerAdapter的实现类

    ViewPager是Android的support库中的一个控件. ViewPager + Fragment的使用,已经有FragmentAdapter的实现可以帮助我们快速进行开发了: ViewPa ...

  6. Android开发中如何加载API源码帮助开发

    在eclipse中添加android源码既可以帮助我们的开发,又能使我们边开发边学习. android环境的搭建:http://blog.csdn.net/dawanganban/article/de ...

  7. Android开发技巧一--weight属性实现视图的居中(半)显示

    面试时,一位面试官问到:“如果我想讲按钮居中显示,并且占据其父视图宽度的一半,应该怎么做到呢?”即实现这种效果: 我们使用weightSum属性和layout_weight属性实现这一要求: < ...

  8. Android中的Glide加载图片

    注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...

  9. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

随机推荐

  1. shell编程--流程控制for,do-while,if-then,break,continue,case等

    2.5 流程控制 2.5.1 if语法 1.语法格式 if condition then     statements [elif condition     then statements. ..] ...

  2. linux中probe函数中传递的参数来源(上)

    点击打开链接 上一篇中,我们追踪了probe函数在何时调用,知道了满足什么条件会调用probe函数,但probe函数中传递的参数我们并不知道在何时定义,到底是谁定义的,反正不是我们在驱动中定义的(当然 ...

  3. Ubuntu和ROS一起愉快玩耍

    Ubuntu和ROS重要的两个中文网址: Ubuntu:http://cn.ubuntu.com/ROS:http://wiki.ros.org/cn Robots and drones on Ubu ...

  4. ORACLE EBS 表空间控制

    --1G=1024MB --1M=1024KB --1K=1024Bytes --1M=11048576Bytes --1G=1024*11048576Bytes=11313741824Bytes S ...

  5. [Django]bulk_create 探究

    使用django orm大批量插入的时候我们可以不使用for循环对一个一个的save而是使用 bulk_create来批量插入,可是使用了这个方法还需要在自己添加一个事务吗? 还是django本身对这 ...

  6. Socket实现单客户端与服务器对话功能

    单客户端,顾名思义,就是客户端只有一个用户去访问服务器,然后服务器根据该客户请求返回信息,先看下效果图: 服务端(左)和客户端(右): 注意,我是用了两个eclipse,一个只放服务端文件,一个只放客 ...

  7. introduction of velocity

    一.velocity 简介 基于java 的模板引擎,apache 旗下的开源软件项目. 目的在于隔离 表示层和业务逻辑层,当然现在做的不仅仅是这些. 二.应用场景 web 应用程序:创建html页面 ...

  8. Erlang 集群互连测试

    Erlang 集群互连测试Erlang节点相同cookie全互联成为一个集群(cluster).如果2个集群不同cookie, 然后其中有节点连接到对方集群的节点,这2个集群会合并成一个集群吗?连接到 ...

  9. Java Socket输入流如何检测到EOF

    对于InputStream的 read(b, off, len) 方法 public int read(byte[] b, int off, int len) throws IOException,J ...

  10. iOS让软键盘消失的简单方法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一些文本输入控件等待输入时会弹出软键盘,我们可以设置这些控件的 ...