从一个例子开始:写一个方法,判断textview 文本是否超过了一行。
1. 协程方式实现:
suspend fun TextView.isOneLine(str: String?) = suspendCoroutine<Boolean> {
if(str.isNullOrEmpty()){
it.resume(true)
return@suspendCoroutine
}
val viewTreeObserver = this.viewTreeObserver
val mTextPaint: TextPaint = paint
mTextPaint.textSize = textSize
val mTextViewWidth = mTextPaint.measureText(str).toInt()
viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener(this)
if (mTextViewWidth > width) {//超出一行
it.resume(false)
} else {//没有超出一行
it.resume(true)
}
}
})
}
使用:
GlobalScope.launch(Dispatchers.Main) {
val oneLine = tv3?.isOneLine(null)
Toast.makeText(this@MeasureActivity,"is oneLine $oneLine",Toast.LENGTH_SHORT).show()
}
2.方法回调实现:
fun TextView.isOneLine1(str: String?,block:(Boolean)->Unit){
if(str.isNullOrEmpty()){
block.invoke(true)
return
}
val viewTreeObserver = this.viewTreeObserver
val mTextPaint: TextPaint = paint
mTextPaint.textSize = textSize
val mTextViewWidth = mTextPaint.measureText(str).toInt()
viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener(this)
if (mTextViewWidth > width) {//超出一行
block.invoke(false)
} else {//没有超出一行
block.invoke(true)
}
}
})
}
使用:
tv2?.isOneLine1("这是测试文本哦") {
if (it) {
Toast.makeText(this,"not 超出一行", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this,"超出一行", Toast.LENGTH_SHORT).show()
}
}