美文网首页Android UIandroid移动开发
Android 图文混排(一) TextView实现图文显示

Android 图文混排(一) TextView实现图文显示

作者: 晓峰残月 | 来源:发表于2016-01-21 20:54 被阅读21606次

总体思路如下:

在 TextView 中显示图片,可以使用Html.fromHtml(source, imageGetter, tagHandler)通过自定义imageGetter来异步加载图片,最后完成图文混排。

1、自定义imageGetter

public class UrlImageGetter implements ImageGetter {
    @Overridepublic Drawable getDrawable(String source) {
        return null;
    }
}

继承ImageGetter实现里面的getDrawable方法。
在getDrawable中的source就是 img标签里src的值也就是图片的路径。

我们使用universal-image-loader.jar来异步加载这些图片

ImageLoader.getInstance().loadImage(source, new SimpleImageLoadingListener() {
        @Overridepublic void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                
        }
});

2、因为图片是异步加载的,所以我们要先建立一个BitmapDrawable,当没有异步加载的时候用来getDrawable的返回

public class UrlDrawable extends BitmapDrawable {
    protected Bitmap bitmap;
    @Override
    public void draw(Canvas canvas) {
        // override the draw to facilitate refresh function later
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, 0, 0, getPaint());
        }
    }
}

在异步加载成功设置监听,成功的时候,我们把BitmapDrawable的bitmap赋上我们异步得到的Bitmap对象在重新绘制,就可以显示出图片,由于图片可能没有固定的尺寸,为了美观我们同意把图片的宽度设置成和手机屏幕的宽度一致
具体代码如下:

ImageLoader.getInstance().loadImage(source, new SimpleImageLoadingListener() {
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        // 计算缩放比例
        float scaleWidth = ((float) width)/loadedImage.getWidth();
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleWidth);
        loadedImage = Bitmap.createBitmap(loadedImage, 0, 0, loadedImage.getWidth(), loadedImage.getHeight(), matrix,                true);
        urlDrawable.bitmap = loadedImage;
        urlDrawable.setBounds(0, 0, loadedImage.getWidth(), loadedImage.getHeight());
        container.invalidate();
        container.setText(container.getText()); // 解决图文重叠
    }
});

效果图如下:

效果图

最后发上代码
HtmlTextView.java

public class HtmlTextView extends TextView {
    public static final String TAG = "HtmlTextView";
    public static final boolean DEBUG = false;

    public HtmlTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public HtmlTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HtmlTextView(Context context) {
        super(context);
    }

    /**
     * @param is
     * @return
     */
    static private String convertStreamToString(InputStream is) {
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");

        return s.hasNext() ? s.next() : "";
    }

    /**
     * Parses String containing HTML to Android's Spannable format and displays
     * it in this TextView.
     *
     * @param html String containing HTML, for example: "<b>Hello world!</b>"
     */
    public void setHtmlFromString(String html, boolean useLocalDrawables) {
        Html.ImageGetter imgGetter;

        if (useLocalDrawables) {
            imgGetter = new LocalImageGetter(getContext());
        } else {
            imgGetter = new UrlImageGetter(this, getContext());
        }

        // this uses Android's Html class for basic parsing, and HtmlTagHandler
        setText(Html.fromHtml(html, imgGetter, new HtmlTagHandler()));

        // make links work
        setMovementMethod(LinkMovementMethod.getInstance());
        text.setTextColor(getResources().getColor(android.R.color.secondary_text_dark_nodisable));
    }
}

UrlImageGetter.java

public class UrlImageGetter implements ImageGetter {
    Context c;
    TextView container;
    int width;

    /**
     *
     * @param t
     * @param c
     */
    public UrlImageGetter(TextView t, Context c) {
        this.c = c;
        this.container = t;
        width = c.getResources().getDisplayMetrics().widthPixels;
    }

    @Override
    public Drawable getDrawable(String source) {
        final UrlDrawable urlDrawable = new UrlDrawable();
        ImageLoader.getInstance().loadImage(source,
            new SimpleImageLoadingListener() {
                @Override
                public void onLoadingComplete(String imageUri, View view,
                    Bitmap loadedImage) {
                    // ??????
                    float scaleWidth = ((float) width) / loadedImage.getWidth();

                    // ???????matrix??
                    Matrix matrix = new Matrix();
                    matrix.postScale(scaleWidth, scaleWidth);
                    loadedImage = Bitmap.createBitmap(loadedImage, 0, 0,
                            loadedImage.getWidth(), loadedImage.getHeight(),
                            matrix, true);
                    urlDrawable.bitmap = loadedImage;
                    urlDrawable.setBounds(0, 0, loadedImage.getWidth(),
                        loadedImage.getHeight());
                    container.invalidate();
                    container.setText(container.getText()); // ??????
                }
            });

        return urlDrawable;
    }

    @SuppressWarnings("deprecation")
    public class UrlDrawable extends BitmapDrawable {
        protected Bitmap bitmap;

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

最后的设置文本

String html = "下面是图片了 " +"src='http://www.qqpk.cn/Article/UploadFiles/201411/20141116135722282.jpg'/>" +
        "这也是图片" +"src='http://h.hiphotos.baidu.com/image/pic/item/d000baa1cd11728b2027e428cafcc3cec3fd2cb5.jpg'/>" +
        "还有一张"+  "src='http://img.61gequ.com/allimg/2011-4/201142614314278502.jpg' />";

private HtmlTextView main;
@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    main = (HtmlTextView) this.findViewById(R.id.main_text);
    main.setHtmlFromString(html,false);
}

请在scr 前补上<img

简书markdown会把img标签转成图片,🈶️知道的望告知怎么破

如有什么不对或者不规范的地方请留言或私信我,非常感谢

传送门:
1、Android 图文混排(一) TextView实现图文显示
2、Android 图文混排(二) EditText实现图文显示
3、Android 图文混排(三)TextView图片点击

相关文章

网友评论

  • 763c80b191ff:请问,在给EditText设置了带图片的html之后,再使用getText方法,img标签会返回[obj],现在项目中要对已经存在的图文进行编辑,编辑完成之后我拿不到带url的img标签,所有的img标签都变成了unicode码,请问博主知道如何解决吗。或者有什么思路吗,不胜感激~
  • 584d37be39e3:楼主,布局文件代码可以贴出给我看看吗??我初学者
    晓峰残月:@沈沈沈_38a7 是的
    584d37be39e3:就一个textview吗??
  • 曹仁不会飞:谢谢楼主,解决了我的问题。:clap:
  • 50311c16c9ba:请问博主,如何让图片单独作为一行,排版问题比较严重,图片和文字是在一行的
    晓峰残月:@Seiren_chang 调整图片的宽度,或者换行
  • e82db463a73b:博主为什么我的效果出来了图片没有换行下去 而是都挤在一起了?
  • e4325050c02a:图片太多,会内存溢出的吧
  • 2015哈哈哈:感谢,学习了 :+1:
  • 5a1870f322a5:我加载了几张图片,往下拉时没问题,但是往回拉时就会出现OOM异常,UrlImageGetter这个类的loadedImage = Bitmap.createBitmap(loadedImage, 0, 0,
    loadedImage.getWidth(), loadedImage.getHeight(),
    matrix, true);楼主有什么建议可以解决这个问题麽?
    晓峰残月:@5a1870f322a5 图片太大了吧
  • 05f6c65f6b78:博主你好,为什么加载的结果多了很多空格与换行符,结果如下:
    “下面是图片


    第一张图片的位置
    这也是图



    第二张图片的位置
    还有一



    第三张图片的位置”
    晓峰残月:@有木有00 标签写的对么
  • 6bd6add036e3:博主看到回复一下!copy啦一下你的demo,为什么现在的是文字和图片标签文本数据。如下:
    下面是图片啦<img src =‘v ’/> 这个样子的
  • BelieveFrank:博主,图片加载不出来呀
  • 小渚:博主在 能麻烦加个QQ694113370 请教下问题吗
  • 菲利柯斯:博主你好 我用你的demo测试,为什么不会显示图片啊.只显示文字和图片的连接.
    be334e2b02d1:我的也是 只显示文字和图片的链接 博主 您知道是什么问题吗?
    菲利柯斯:@晓峰残月 初始化了,不走getdrawable方法
    晓峰残月: @菲利柯斯 图片异步加载的库初始化了么
  • 732974561e63:放在listview里面,往上滑的时候,上一个item一出现就会闪一下并且跳到上一个item的中间位置。不知道什么原因
    晓峰残月: @JAyden520 好像很少人会这么做吧,可以更新listview试下
    732974561e63:@晓峰残月 那么应该怎么去解决这个问题呢,有没有方案,请指教一下
    晓峰残月: @JAyden520 item的高度问题,这个图片是异步的,所以有图片的话高度会乱
  • 墨linwj:为什么我的图片没哟加载出来的呢,而且只打印出String
    ac0c777e9f80:@Jayden168 我的也是这样,你解决了吗?
  • 7e39e232e613:大神,多点几次就会出现OOM、、、
    晓峰残月:@想当大神 这个不太清楚,不好意思啊
    7e39e232e613:@晓峰残月 我只加载了一张图片,压缩到100KB了,点进来退出去来回10次左右 就出现OOM了
    晓峰残月:@想当大神 应该是图片过大引起的,可以做下图片处理就好了
  • 26ea56fbcccc:LocalImageGetter 楼主 这个类顺便也给贴上吧 :pray:
    晓峰残月:@Tom老兄 链接: http://pan.baidu.com/s/1bouOto7 密码: uufv
  • 809edae312b8:博主你好,怎么我显示不了图片的?
    晓峰残月:@809edae312b8 具体是什么样子的呢
  • 6e73b21d244f:感谢博主分享,为什么我只是换个异步框架就显示不了图片了
    晓峰残月:@6e73b21d244f 感谢支持,图片加载框架是不区分的,主要是加载图片完成之后回调做的事情
  • YANGReal:不错
    晓峰残月:@YANGReal 感谢支持
  • 25e8abc17b0d:感谢博主,学习了,不知道能否提供这个系列的完整代码呢?
    初学总是崩溃
    褐言:布局也贴出来吧 博主
    晓峰残月:@well8808 感谢支持
    晓峰残月:@well8808 链接: http://pan.baidu.com/s/1bouOto7 密码: uufv
  • 嘿张开心:学习啦
  • dcdced3567ee:博主你好,文中的HtmlTagHandler是怎么写的呢?
    ebb2347e9eba:@晓峰残月 为什么图片显示不出来啊!显示的是链接
    晓峰残月:@Da滴飞猪 链接: http://pan.baidu.com/s/1o7uzE5c 密码: mdhu
  • 皮球二二:博主你好,异步加载显示图片的流程是每收到一个异步完成就直接给textview再赋一遍string全值是吧
    晓峰残月: @r17171709 是的,不然会错乱

本文标题:Android 图文混排(一) TextView实现图文显示

本文链接:https://www.haomeiwen.com/subject/bowlkttx.html