需求:根據給定的文字(代碼中用戶動態輸入,或接口固定返回等),展示標籤樣式,且只展示第一個字。如:經濟。則,標籤展示“經”
擴展功能:文字隨控件大小,對應變化,不需要額外設置。
樣式圖:
代碼:
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"
/>