Android 中使用 SpannableStringBuilder 实现图文混排的源码 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
maiziedu
V2EX    Android

Android 中使用 SpannableStringBuilder 实现图文混排的源码

  •  
  •   maiziedu 2015-11-24 15:28:37 +08:00 12067 次点击
    这是一个创建于 3692 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 android 开发中,我们常常需要对文字和图片进行一些排版,以提升客户体验度。要让图文混排更加友好,这个功能怎么实现呢?不妨可以尝试 android SpannableStringBuilder 来实现图文混排,而如果想要更多其他的效果话,也可以进行修改调整实现。

    废话不多说,直接上代码,大家自己琢磨研究吧:

    private void toggleEllipsize(final TextView tv,final String desc){

    if(desc == null){

    return;

    }

    tv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override

    public void onGlobalLayout() {

    boolean isEllipsized = (tv.getTag()==null||tv.getTag().equals(false))?false:(Boolean)tv.getTag();

    if(isEllipsized){

    tv.setTag(false);

    tv.setText(desc);

    }else{

    tv.setTag(true);

    int paddingLeft = tv.getPaddingLeft();

    int paddingRight = tv.getPaddingRight();

    TextPaint paint = tv.getPaint();

    float moreText = tv.getTextSize()*3;

    float availableTextWidth = (tv.getWidth()-paddingLeft-paddingRight)*2-moreText;

    CharSequence ellipsizeStr = TextUtils.ellipsize(desc,paint,availableTextWidth,TextUtils.TruncateAt.END);

    if(ellipsizeStr.length()<desc.length()){
    /*String html = "<img src='game_info_lookmore'/>";
    CharSequence charSequence = Html.fromHtml(html, new ImageGetter() {

    @Override public Drawable getDrawable(String source) { Drawable drawable = getResources().getDrawable( getResourceId(source)); drawable.setBounds( 0, 0, drawable.getIntrinsicWidth() - DensityUtil.dip2px(GridGameInfoActivity.this, 3), drawable.getIntrinsicHeight() - DensityUtil.dip2px(GridGameInfoActivity.this, 1)); return drawable; } 

    }, null);
    ellipsizeStr = ellipsizeStr.toString() + charSequence.toString();*/

    CharSequence temp = ellipsizeStr+".";

    SpannableStringBuilder ssb = new SpannableStringBuilder(temp);

    Drawable dd = getResources().getDrawable(R.drawable.game_info_lookmore);

    dd.setBounds(0, 0, dd.getIntrinsicWidth(), dd.getIntrinsicHeight());

    ImageSpan is = new ImageSpan(dd, ImageSpan.ALIGN_BASELINE);

    ssb.setSpan(is, temp.length()-1, temp.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

    // int yellow = getResources().getColor(R.color.red);

    // ssb.setSpan(new ForegroundColorSpan(yellow),ssb.length()-2,ssb.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    tv.setText(ssb);

    tv.setMovementMethod(LinkMovementMethod.getInstance());

    }else{

    tv.setText(desc);

    }

    }

    if(Build.VERSION.SDK_INT>=16){

    tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);

    }else{

    tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);

    }

    }

    });

    }
    Android spannableStringBuilder 更多用法整理:

    spannableStringBuilder 用法详解:
    SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:.");

    //用颜色标记文本
    ss.setSpan(new ForegroundColorSpan(Color.RED), 0, 2,

    //setSpan 时需要指定的 flag,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括).
    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //用超链接标记文本
    ss.setSpan(new URLSpan("tel:4155551212"), 2, 5,

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //用样式标记文本(斜体)
    ss.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 7,

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //用删除线标记文本
    ss.setSpan(new StrikethroughSpan(), 7, 10,

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //用下划线标记文本
    ss.setSpan(new UnderlineSpan(), 10, 16,

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //用颜色标记
    ss.setSpan(new ForegroundColorSpan(Color.GREEN), 10, 13,

    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    //获取 Drawable 资源
    Drawable d = getResources().getDrawable(R.drawable.icon);

    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    //创建 ImageSpan
    ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
    //用 ImageSpan 替换文本
    ss.setSpan(span, 18, 19, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

    txtInfo.setText(ss);
    txtInfo.setMovementMethod(LinkMovementMethod.getInstance()); //实现文本的滚动

    通常用于显示文字,但有时候也需要在文字中夹杂一些图片,比如 QQ 中就可以使用表情图片,又比如需要的文字高亮显示等等,如何在 android 开发中也做到这样呢?

    记得 android 中有个 android.text 包,这里提供了对文本的强大的处理功能。

    添加图片主要用 SpannableString 和 ImageSpan 类:

    Drawable drawable = getResources().getDrawable(id);

    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

    //需要处理的文本,[smile]是需要被替代的文本

    SpannableString spannable = new SpannableString(getText().toString()+"[smile]");

    //要让图片替代指定的文字就要用 ImageSpan

    ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);

    //开始替换,注意第 2 和第 3 个参数表示从哪里开始替换到哪里替换结束( start 和 end )

    //最后一个参数类似数学中的集合,[5,12)表示从 5 到 12 ,包括 5 但不包括 12
    spannable.setSpan(span, getText().length(),getText().length()+"[smile]".length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

    setText(spannable);

    将需要的文字高亮显示:

    public void highlight(int start,int end){

    SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());//用于可变字符串

    ForegroundColorSpan span=new ForegroundColorSpan(Color.RED);

    spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    setText(spannable);

    }

    加下划线:

    public void underline(int start,int end){

    SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());

    CharacterStyle span=new UnderlineSpan();

    spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    setText(spannable);

    }

    组合运用:

    SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());

    CharacterStyle span_1=new StyleSpan(android.graphics.Typeface.ITALIC);

    CharacterStyle span_2=new ForegroundColorSpan(Color.RED);

    spannable.setSpan(span_1, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    spannable.setSpan(span_2, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    setText(spannable);

    案例:带有\n 换行符的字符串都可以用此方法显示 2 种颜色
    /**
    * 带有\n 换行符的字符串都可以用此方法显示 2 种颜色
    * @param text
    * @param color1
    * @param color2
    * @return
    */

    public SpannableStringBuilder highlight(String text,int color1,int color2,int fontSize){

    SpannableStringBuilder spannable=new SpannableStringBuilder(text);//用于可变字符串

    CharacterStyle span_0=null,span_1=null,span_2;

    int end=text.indexOf("\n");

    if(end==-1){//如果没有换行符就使用第一种颜色显示

    span_0=new ForegroundColorSpan(color1);

    spannable.setSpan(span_0, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    }else{

    span_0=new ForegroundColorSpan(color1);

    span_1=new ForegroundColorSpan(color2);

    spannable.setSpan(span_0, 0, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    spannable.setSpan(span_1, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    span_2=new AbsoluteSizeSpan(fontSize);//字体大小

    spannable.setSpan(span_2, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    }

    return spannable;

    }

    以上就是使用 android SpannableStringBuilder 实现图文混排的源码,单看代码,可能很难看出其具体展现出来的是什么,大家可以将上面源码,放在自己本地运行,观看效果,也可以根据自己的需要调整修改,实现不同的效果。

    相关文章:《 android 布局属性详解》 http://www.maiziedu.com/group/article/8961/
    文章来源: DevStore

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     871 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 19:41 PVG 03:41 LAX 11:41 JFK 14:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86