一种简单的实现标签标题的混排方式

本文介绍了一种在Android应用中实现图文混排的有效方法,包括使用WebView加载HTML、自定义drawable属性及Spannable技术等,特别关注了图片居中的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在很多情况下,尤其是电商类网站,都会有促销活动或者其他一类的活动,在UI设计上通常会出现以下设计:这里写图片描述
以及以下设计:
这里写图片描述
针对第一种情况,标题和标签在一行且标题只有一行的情况下,我们可以使用两个控件,一个imageView(simpleDrawView),一个textView,并设置他们的位置关系即可。(或者drawableLeft)
但是大多数情况下并非是这样的,而是和图2一样,这样设置两个控件就不合适了,以及设置textView的drawableLeft,都是不合适的,在多行文本的情况下会和UI设计图有很大的出入。

解决方案

在百度或者google上,输入安卓图文混排,会出现很多的解决方案,无外乎三种

  1. webview加载html(或者textView加载html)
    需要注意的是,并不是所有的 HTML 标签在 TextView 中都是支持的,且官方文档并没有明确的说明支持 HTML 标签列表,通过查看 Android 源代码,可以得到简单的支持列表。
<br>,< p>,< div align=>,< strong>, <b>, <em>, <cite>, <dfn>, <i>, <big>, <small>, <font size=>, <font color=>, <blockquote>, <tt>, <a href=>,
<u>, <sup>, <sub>, <h1>,<h2>,<h3>,<h4>,<h5>,<h6>, <img src=>, <strike>

fromHtml方法

fromHtml(String source, ImageGetter imageGetter,TagHandler tagHandler)

继承ImageGetter

继承于 ImageGetter,重写 getDrawable (String source) 方法。通过异步操作,读取本地/网络资源,获得drawable对象。

继承TagHandler

继承于 TagHandler,重写了 handleTag()方法。为了支持更多的标签,例如为了支持<ul><ol><dd>和<li>标签,这四个标签是在 formHtml()方法中本身是不支持。

如果开发者认为安卓 TagHandler 提供的默认标签解析已经够用,直接在 fromHtml()方法中第三个参数的地方填写 null 既可。

最后,通过 formHtml()方法将 HTML 内容转化为可供显示的 SpannableString,将 SpannableString 通过 setText 方法放入 TextView 中,就可以显示图文并茂的内容了。

  1. drawable属性
    即textview的drawableft等设置图片方法
    缺陷就是多行文本下,实现不了这种UI
    这里写图片描述

  2. Spannable使用
    使用html或者自定义有点大马拉小车的感觉,drawable属性又不能实现效果,所以Spannable就派上用场了
    setText(CharSequence text)中接收的是CharSequence。而SpannableString和SpannableStringBuilder是其实现类,是可以直接赋值的。并且两者的setSpan()方法可以设置一些格式对象(例如字体大小、下划线、替换为图片等),这就可以实现富文本了。

Spannable实现子类:SpannableString,SpannableStringBuilder(可变,类似于StringBuilder)。

Spannable中定义了抽象方法:setSpan(Object what, int start, int end, int flags)和removeSpan(Object what)。这两个方法实现了对字符串的灵活编辑。
在这里我们用到的就是imageSpan。
继承imageSpan实现自己的居中方案,因为谷歌并没有提供居中方案.

/**
 * Created on 2017/6/13.
 * <p>
 * 实现图文混排图片文字居中方案
 */

public class CenterImageSpan extends ImageSpan {

    public CenterImageSpan(Context context, int resourceId) {
        super(context, resourceId);
    }

    public CenterImageSpan(Context context, Bitmap bitmap){
        super(context,bitmap);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        Drawable b = getDrawable();
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;
        canvas.save();
        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }
}

使用方法就是,加载本地图片

SpannableStringBuilder ssb = new SpannableStringBuilder(" " + " " + " "+entity.title);//两个空格是占位符,随后图片会将其替代,另一个空格是间距
ImageSpan imageSpan = new CenterImageSpan(context, R.drawable.jingdong_jingxuan_logo);
ssb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
title.setText(ssb);

加载网络图片也是一样的,无非是在下载回调中获取到bitmap,如下:

JDImageUtils.displayImage(url, simpleDraweeView, new JDImageLoadingListener() {
                @Override
                public void onLoadingStarted(String s, View view) {

                }

                @Override
                public void onLoadingFailed(String s, View view, JDFailReason jdFailReason) {
                    simpleDraweeView.setVisibility(View.GONE);
                    titleView.setText(title);
                }

                @Override
                public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(" " + " " + title);
                    CenterImageSpan imageSpan = new CenterImageSpan(context, scaleBitmap(bitmap, width, height));
                    spannableStringBuilder.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    titleView.setText(spannableStringBuilder);
                    simpleDraweeView.setVisibility(View.GONE);
                }

                @Override
                public void onLoadingCancelled(String s, View view) {

                }
            });
        }
 public static Bitmap scaleBitmap(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
                true);
        return  newbm;
    }

这个算是这种布局最合理的实现方式了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值