Изменение размера текста в DynamicLayout в Android
На самом деле, я абстрагирую функции от существующего пользовательского представления, которое не является естественным текстовым представлением. Чтобы заставить его работать как текстовое представление, я использую DynamicLayout.
Мои задачи ниже:
- Холст не будет рисовать текст, за исключением того, что текст не пуст
- Когда используется текст-заполнитель и рисуется холст, новый текст, если он длиннее старого текста (текст-заполнитель), усекается.
class CustomTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : CustomShimmerView(context, attrs, defStyleAttr) {
var text = "Custom"
var paint: TextPaint = TextPaint()
var layout:DynamicLayout?=null
init {
paint.isAntiAlias = true
paint.textSize = 34 * resources.displayMetrics.density
val width = paint.measureText(text)
layout = DynamicLayout(text, paint,
width.toInt(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, false)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.AlexaTextView, 0, 0)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun dispatchDraw(canvas: Canvas?) {
if (isLoading && text == "Custom") {
super.dispatchDraw(canvas)
}
else{
canvas?.save()
canvas?.translate(paddingLeft.toFloat(), paddingTop.toFloat())
layout?.draw(canvas)
canvas?.restore()
background = null
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val width: Int = setWidthMeasurement(widthMeasureSpec)
val height: Int = setHeightMeasurement(heightMeasureSpec)
setMeasuredDimension(width, height)
}
private fun setWidthMeasurement(widthMeasureSpec: Int): Int {
var width: Int
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthRequirement = MeasureSpec.getSize(widthMeasureSpec)
if (widthMode == MeasureSpec.EXACTLY) {
width = widthRequirement
} else {
width = layout?.width?.plus(paddingLeft)?.plus(paddingRight) ?: 0
if (widthMode == MeasureSpec.AT_MOST) {
if (width > widthRequirement) {
width = widthRequirement
layout = DynamicLayout(
text,
paint,
width,
Layout.Alignment.ALIGN_NORMAL,
1.0f,
0f,
false
)
}
}
}
return width
}
private fun setHeightMeasurement(heightMeasureSpec: Int): Int {
var height: Int
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val heightRequirement = MeasureSpec.getSize(heightMeasureSpec)
if (heightMode == MeasureSpec.EXACTLY) {
height = heightRequirement
} else {
height = layout?.height?.plus(paddingTop)?.plus(paddingBottom) ?: 0
if (heightMode == MeasureSpec.AT_MOST) {
if (height > heightRequirement) {
height = min(height, heightRequirement)
}
}
}
return height
}
@JvmName("setText1")
fun setText(text:String){
if (text.isNotBlank()) {
this.text = text
paint.isAntiAlias = true
paint.textSize = 34 * resources.displayMetrics.density
val width = paint.measureText(text)
layout = DynamicLayout(text, paint,
width.toInt(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, false)
}
else throw RuntimeException("Stub!")
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.save()
canvas?.translate(paddingLeft.toFloat(), paddingTop.toFloat())
layout?.draw(canvas)
canvas?.restore()
}
}