【Android】android开发之文字拼接图片,图文混排

前言

需求:给一个字符串拼接上一个"全国"标签,需要一直跟在文字后面。

ui图:

想法:

采用spannable的方法给文字后面添加图片。

正文

1.写一个xml当"全国"标签view。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/common_shape_frame_global_gold"
        android:gravity="center"
        android:text="@string/entire_country"
        android:textColor="@color/common_gold_e1c078"
        android:textSize="10sp"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="5dp">
    </TextView>
</LinearLayout>
//shape样式

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <corners
        android:radius="3dp"
        />

    <stroke
        android:width="1dp"
        android:color="@color/common_gold"
        />
</shape>

 

ps:为什么要套一个LinearLayout呢?因为在spannable中添加绘制图片,不好修改其中标签的位置,故套一层ViewGroup,再在里面修改margin从而控制位置。

2.将view转换成drawable.

将view转成drawable的工具方法。

//工具类

/**
     * 将view转换成Drawable
     * @param view
     * @return
     */
    public static Drawable convertViewToDrawable(View view) {
        int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        view.measure(spec, spec);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        c.translate(-view.getScrollX(), -view.getScrollY());
        view.draw(c);
        view.setDrawingCacheEnabled(true);
        Bitmap cacheBmp = view.getDrawingCache();
        Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
        view.destroyDrawingCache();
        BitmapDrawable drawable = new BitmapDrawable(Application.getResources(), viewBmp);
        cacheBmp.recycle();
        return drawable;
    }

3.使用ImageSpan塞入drawable.

                String centerName="你需要显示的内容";
                centerName += F.getInstance().getString(R.string.entire_country);//加上全国两个字,后面会被替换成图片
                View globalView = LayoutInflater.from(F.getInstance().getContext()).inflate(R.layout.view_treament_center_golbal, null);
                String finalCenterName = centerName;
                Drawable drawable = ViewUtils.convertViewToDrawable(globalView);
                SpannableStringBuilder spannableString = new SpannableStringBuilder(finalCenterName);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getMinimumHeight());//必须设置,代表drawable在canvas的draw位置
                ImageSpan imageSpan = new ImageSpan(drawable);
                spannableString.setSpan(imageSpan, spannableString.length() - 2, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                holder.mTvCenterName.setText(spannableString);

这一段代码需要理解下:

1.使用LayoutInflater加载刚刚写的xml,"全国"view

View globalView = LayoutInflater.from(F.getInstance()
                                        .getContext())
                                     .inflate(R.layout.view_treament_center_golbal, null);

2.使用刚刚的工具将view转换成drawable,也可以叫你的ui给你切个图。

3.设置drawable绘制位置

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

 

Drawable的setBounds方法有四个参数,setBounds(int left, int top, int right, int bottom),这个四参数指的是drawable将在被绘制在canvas的哪个矩形区域内。

例如

@Override
    protected void onDraw(Canvas canvas) {
        drawable.setBounds(100, 100, 500, 500);
        drawable.draw(canvas);
    }

上面的代码会将drawable绘制在canvas内部(100,100,500,500)表示的矩形区内(这个矩形区域的坐标是以canvas左上角为坐标原点的)

 

4.通过给SpanString设置ImageSpan增加图片。

spannableString.setSpan(imageSpan, spannableString.length() - 2, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            
setSpan方法:
 参数1:增加的样式内容;
 参数2:替换的开始位置;
 参数3:替换的结束位置;
 参数4:含尾不含头

参数4的枚举:

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含start和end所在的端点                 (a,b)
 Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点       (a,b]
 Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含start,但不包含end所在的端点          [a,b)
 Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含start和end所在的端点                       [a,b]

实现效果:

 

相关链接

文字高亮

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值