標籤控件(簡單控件,筆記)

需求:根據給定的文字(代碼中用戶動態輸入,或接口固定返回等),展示標籤樣式,且只展示第一個字。如:經濟。則,標籤展示“經”

擴展功能:文字隨控件大小,對應變化,不需要額外設置。

樣式圖:
在這裏插入圖片描述
代碼:
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"
/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章