标签控件(简单控件,笔记)

Posted 夜尽天明89

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了标签控件(简单控件,笔记)相关的知识,希望对你有一定的参考价值。

需求:根据给定的文字(代码中用户动态输入,或接口固定返回等),展示标签样式,且只展示第一个字。如:经济。则,标签展示“经”

扩展功能:文字随控件大小,对应变化,不需要额外设置。

样式图:

代码:
1、res -> values -> styles 中

    <!--标签View的自定义属性-->
    <declare-styleable name="LabelTextView">
        <!--标签内要展示的文字-->
        <attr name="labelText" format="string"/>
        <!--标签的背景颜色-->
        <attr name="labelBgColor" format="color"/>
        <!--标签中的文字的颜色-->
        <attr name="labelTextColor" format="color"/>
        <!--标签的大小,单位:dp。因为宽=高,所以,指定一个就行-->
        <attr name="labelSize" format="integer"/>
    </declare-styleable>

2、标签布局源码:LabelTextView

package com.demo.customtextdemo

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.text.TextPaint
import android.util.AttributeSet
import android.view.View

/**
 * 标签文字View,用于展示文字标签,且标签只展示一个字。
 * 如:标签文字为:经济,则标签View中的文字为"经"
 *
 * 用法:
 * 布局中使用:
 * <com.demo.customtextdemo.LabelTextView
 *      android:id="@+id/myLabelView"
 *      android:layout_width="wrap_content"
 *      android:layout_height="wrap_content"
 *      app:labelBgColor="@color/labelBg"
 *      app:labelSize="30"
 *      android:layout_marginTop="30dp"
 * />
 * 界面中:myLabelView?.setTextAndColor("经济")
 * 
 * 注:labelSize,是真正影响控件大小的值
 *
 */
class LabelTextView : View 

    private var mContext: Context? = null

    private var mPaint: Paint? = null
    private var mTextPaint: TextPaint? = null

    private var labelText: String = ""
    private var labelBgColor: Int = 0
    private var labelTextColor: Int = 0
    private var labelSize: Int = 0//单位:dp
    //控件的大小,宽=高
    private var viewSize: Float = 0f
    //要展示的文字
    private var showText: String = ""

    private var textOffset: Float = 0f

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) 
        mContext = context

        val ta = context?.obtainStyledAttributes(attrs, R.styleable.LabelTextView)
        labelText = ta?.getString(R.styleable.LabelTextView_labelText) ?: ""
        labelBgColor = ta?.getColor(R.styleable.LabelTextView_labelBgColor, 0) ?: 0
        labelTextColor = ta?.getColor(R.styleable.LabelTextView_labelTextColor, 0) ?: 0
        labelSize = ta?.getInteger(R.styleable.LabelTextView_labelSize, 0) ?: 0

        ta?.recycle()

        init()
    

    private fun init() 

        if (mContext == null || labelText.isEmpty() || labelBgColor == 0 || labelTextColor == 0 || labelSize == 0) 
            //关键数据不足,无法绘制
            viewSize = 0f
         else 
            viewSize = UiUtils.dp2px(mContext!!, labelSize.toFloat()).toFloat()
        

        if (viewSize != 0f) 

            //背景画笔
            if (mPaint == null) 
                mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
            
            mPaint?.style = Paint.Style.FILL
            mPaint?.color = labelBgColor
            mPaint?.strokeWidth = 20.toFloat()

            //字体画笔
            if (mTextPaint == null) 
                mTextPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
            

            mTextPaint?.textSize = viewSize / 2f
            mTextPaint?.color = labelTextColor
            mTextPaint?.textAlign = Paint.Align.CENTER

            //文字的上坡度和下坡度。用于计算偏移量
            var ascent = mTextPaint?.ascent() ?: 0f
            var descent = mTextPaint?.descent() ?: 0f

            //偏移量,用于辅助文字在竖直方向居中
            textOffset = (ascent + descent) / 2

            if (labelText.isEmpty().not()) 
                showText = labelText.substring(0, 1)
            

        

    

    //设置文字和颜色
    fun setTextAndColor(text: String = "", size: Int = 0, bgColor: Int = 0, tvColor: Int = 0) 

        if (size != 0) 
            labelSize = size
        

        if (bgColor != 0) 
            labelBgColor = bgColor
        
        if (tvColor != 0) 
            labelTextColor = tvColor
        

        if (text.isEmpty().not()) 
            labelText = text
        

        //重新设置数据
        init()

        //重绘
        invalidate()

    

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(viewSize.toInt(), viewSize.toInt())
    

    override fun onDraw(canvas: Canvas?) 
        super.onDraw(canvas)

        if (viewSize != 0f && showText.isEmpty().not() && mPaint != null && mTextPaint != null) 

            canvas?.drawCircle(viewSize / 2, viewSize / 2, viewSize / 2, mPaint!!)
            canvas?.drawText(showText, viewSize / 2, viewSize / 2 - textOffset, mTextPaint!!)

        

    


3、使用:
(1)布局中不指定内容,代码中动态设置:

<com.demo.customtextdemo.LabelTextView
	android:id="@+id/myLabelView"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	app:labelBgColor="@color/labelBg"
	app:labelSize="30"
/>

myLabelView?.setTextAndColor("经济", tvColor = ContextCompat.getColor(this, R.color.white))

(2)布局中全部设置:写布局代码的时候,就需要明确知道标签内容

<com.demo.customtextdemo.LabelTextView
	android:id="@+id/myLabelView_6"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	app:labelBgColor="#000000"
	app:labelSize="80"
	app:labelText="我们"
	app:labelTextColor="#ff0000"
/>

以上是关于标签控件(简单控件,笔记)的主要内容,如果未能解决你的问题,请参考以下文章

LVGL v8学习笔记 | 10 - Tabview控件的使用方法

MiniUI学习笔记1-全局方法

Ext.Net学习笔记19:Ext.Net FormPanel 简单用法

webform简单控件和复合控件

调用ocx ActiveX控件详解(做一个简单的ocx控件)

有可选择的标签控件吗?