TextView前加标签

Android TextView前自定义标签

一、效果图

二、代码实现

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Paint.FontMetricsInt
import android.graphics.drawable.Drawable
import android.text.style.ImageSpan

class CenterImageSpan : ImageSpan {

    constructor(context: Context, resourceId: Int) : super(context, resourceId) {
    }

    constructor(drawable: Drawable) : super(drawable) {
    }

    override fun getSize(
        paint: Paint,
        text: CharSequence?,
        start: Int,
        end: Int,
        fm: FontMetricsInt?
    ): Int {
        val d = drawable
        val rect = d.bounds
        if (fm != null) {
            val fmPaint = paint.fontMetricsInt
            val fontHeight = fmPaint.bottom - fmPaint.top
            val drHeight = rect.bottom - rect.top
            val top = drHeight / 2 - fontHeight / 4
            val bottom = drHeight / 2 + fontHeight / 4
            fm.ascent = -bottom
            fm.top = -bottom
            fm.bottom = top
            fm.descent = top
        }
        return rect.right
    }

    override fun draw(
        canvas: Canvas,
        text: CharSequence?,
        start: Int,
        end: Int,
        x: Float,
        top: Int,
        y: Int,
        bottom: Int,
        paint: Paint
    ) {
        val b = drawable
        canvas.save()
        var transY = 0
        transY = (bottom - top - b.bounds.bottom) / 2 + top
        canvas.translate(x, transY.toFloat())
        b.draw(canvas)
        canvas.restore()
    }

}

tag标签布局layout_tag_textview

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_tag"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/tab_background"
    android:paddingStart="4dp"
    android:paddingTop="2dp"
    android:paddingEnd="4dp"
    android:paddingBottom="2dp"
    android:text="标签"
    android:textColor="#ff0000" />

页面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:text="Hello World!" />

</RelativeLayout>

代码实现

        val mTextView = findViewById<TextView>(R.id.tv_text)

        val text = "# 这是文案这是文案这是文案这是文案这是文案这是文案这是文案这是文案这是文案这是文案这是文案"
        val spanBuilder = SpannableStringBuilder(text)
        //生成标签View
        val tagView = LayoutInflater.from(this).inflate(R.layout.layout_tag_textview, null)
        val tagTextView = tagView.findViewById<TextView>(R.id.tv_tag)
        //View转bitmap
        tagTextView.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        tagTextView.layout(0, 0, tagTextView.measuredWidth, tagTextView.measuredHeight)
        tagTextView.buildDrawingCache()
        val bitmap = tagTextView.drawingCache
        //bitmap转drawable
        val drawable = BitmapDrawable(this.resources, bitmap)
        drawable.setBounds(0, 0, tagTextView.width, tagTextView.height)
        spanBuilder.setSpan(
                CenterImageSpan(drawable),
                0,
                1,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        mTextView.text = spanBuilder

三、不同部分点击事件

 

class ClickableColorSpan(val color: Int, val action: (() -> Unit)?) : ClickableSpan() {

    override fun updateDrawState(ds: TextPaint) {
        super.updateDrawState(ds)
        ds.color = color
        ds.isUnderlineText = false;//是否显示下划线
    }

    override fun onClick(widget: View) {
        action?.invoke()
    }
}
        val name = "名字名字名字"
        val content = "内容内容内容内容内容内容"
        val spannableString = SpannableString(" ${name} ${content}")
        var index = 0

        val drawable = ContextCompat.getDrawable(this, R.drawable.circle_red)
        val height = resources?.getDimensionPixelOffset(R.dimen.calces_36px) ?: 0  //图片高
        val width = resources?.getDimensionPixelOffset(R.dimen.calces_90px) ?: 0  //图片宽度
        drawable?.setBounds(0, 0, width, height)
        if (drawable != null) {
            spannableString.setSpan(
                CenterImageSpan(drawable),
                0,
                1,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            index = 1
        }

        val spanName = ClickableColorSpan(Color.parseColor("#8CE4FA")) {
            Toast.makeText(this@MainActivity, "点击了名字", Toast.LENGTH_LONG).show()
        }
        spannableString.setSpan(
            spanName,
            index,
            index + name.length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        index += name.length + 1

        val spanContent = ClickableColorSpan(Color.parseColor("#FACE16")) {
            Toast.makeText(this@MainActivity, "点击了内容", Toast.LENGTH_LONG).show()
        }
        spannableString.setSpan(
            spanContent,
            index,
            spannableString.length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        mTvSpan?.text = spannableString
        mTvSpan?.movementMethod = LinkMovementMethod.getInstance();

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值