一、系统自带的方法
使用系统自带的方法android:includeFontPadding=”false”,不能完全消除内间距,但是可以一定程度上减少内间距。
效果图对比:
第一个没有任何处理,第二个加了android:includeFontPadding=”false”,第三个是自定义 View.
二、自定义 View
NoTextView
说明:使用这种方式将无法设置 padding。
class NoTextView @JvmOverloads constructor(context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0) : AppCompatTextView(context,attrs, defStyleAttr) {
init {
val textSize = textSize
val paint = Paint()
paint.textSize = textSize
val fontMetricsInt = paint.fontMetricsInt
setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
val top =
ceil(abs((fontMetricsInt.top - fontMetricsInt.ascent) / 2.0)).toInt()
setPadding(
0, -(abs(fontMetricsInt.top - fontMetricsInt.ascent) + top)
, 0,
fontMetricsInt.top - fontMetricsInt.ascent
)
}
}
直接使用即可,像普通的 TextView 一样,如下:
<com.kiwilss.xview.widget.textview.NoTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="汉字字"
android:textSize="20dp"
android:background="@color/blue_74D3FF"
/>
ExcludeFontPaddingTextView
说明:这个控件可以设置 padding。
class ExcludeFontPaddingTextView : AppCompatTextView {
init {
includeFontPadding = false
}
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun setText(text: CharSequence?, type: BufferType?) {
super.setText(getCustomText(text), type)
}
private fun getCustomText(text: CharSequence?): SpannableStringBuilder? {
return text?.let {
val rect = Rect()
paint.getTextBounds(text.toString(), 0, text.length, rect)
val ssb = SpannableStringBuilder(text)
//设置LineHeightSpan
ssb.setSpan(
object : LineHeightSpan {
@RequiresApi(Build.VERSION_CODES.N)
override fun chooseHeight(
text: CharSequence,
start: Int,
end: Int,
spanstartv: Int,
lineHeight: Int,
fm: Paint.FontMetricsInt
) {
val viewHeight = fm.descent - fm.ascent
val textHeight = max(textSize.toInt(), rect.bottom - rect.top)
val paddingTop = abs(fm.ascent - rect.top)
val paddingBottom = fm.descent - rect.bottom
val minPadding = min(paddingTop, paddingBottom)
val avgPadding = (viewHeight - textHeight) / 2
when {
avgPadding < minPadding -> {
fm.ascent += avgPadding
fm.descent -= avgPadding
}
paddingTop < paddingBottom -> {
fm.ascent = rect.top
fm.descent = textHeight + fm.ascent
}
else -> {
fm.descent = rect.bottom
fm.ascent = fm.descent - textHeight
}
}
}
},
0,
text.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
ssb
}
}
}