一、系统自带的方法

使用系统自带的方法android:includeFontPadding=”false”,不能完全消除内间距,但是可以一定程度上减少内间距。

效果图对比:
image.pngimage.png
第一个没有任何处理,第二个加了android:includeFontPadding=”false”,第三个是自定义 View.

二、自定义 View

NoTextView

说明:使用这种方式将无法设置 padding。

  1. class NoTextView @JvmOverloads constructor(context: Context?,
  2. attrs: AttributeSet? = null,
  3. defStyleAttr: Int = 0) : AppCompatTextView(context,attrs, defStyleAttr) {
  4. init {
  5. val textSize = textSize
  6. val paint = Paint()
  7. paint.textSize = textSize
  8. val fontMetricsInt = paint.fontMetricsInt
  9. setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
  10. val top =
  11. ceil(abs((fontMetricsInt.top - fontMetricsInt.ascent) / 2.0)).toInt()
  12. setPadding(
  13. 0, -(abs(fontMetricsInt.top - fontMetricsInt.ascent) + top)
  14. , 0,
  15. fontMetricsInt.top - fontMetricsInt.ascent
  16. )
  17. }
  18. }

直接使用即可,像普通的 TextView 一样,如下:

  1. <com.kiwilss.xview.widget.textview.NoTextView
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content"
  4. android:text="汉字字"
  5. android:textSize="20dp"
  6. android:background="@color/blue_74D3FF"
  7. />

ExcludeFontPaddingTextView

说明:这个控件可以设置 padding。

  1. class ExcludeFontPaddingTextView : AppCompatTextView {
  2. init {
  3. includeFontPadding = false
  4. }
  5. constructor(context: Context) : super(context)
  6. constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
  7. constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
  8. context,
  9. attrs,
  10. defStyleAttr
  11. )
  12. override fun setText(text: CharSequence?, type: BufferType?) {
  13. super.setText(getCustomText(text), type)
  14. }
  15. private fun getCustomText(text: CharSequence?): SpannableStringBuilder? {
  16. return text?.let {
  17. val rect = Rect()
  18. paint.getTextBounds(text.toString(), 0, text.length, rect)
  19. val ssb = SpannableStringBuilder(text)
  20. //设置LineHeightSpan
  21. ssb.setSpan(
  22. object : LineHeightSpan {
  23. @RequiresApi(Build.VERSION_CODES.N)
  24. override fun chooseHeight(
  25. text: CharSequence,
  26. start: Int,
  27. end: Int,
  28. spanstartv: Int,
  29. lineHeight: Int,
  30. fm: Paint.FontMetricsInt
  31. ) {
  32. val viewHeight = fm.descent - fm.ascent
  33. val textHeight = max(textSize.toInt(), rect.bottom - rect.top)
  34. val paddingTop = abs(fm.ascent - rect.top)
  35. val paddingBottom = fm.descent - rect.bottom
  36. val minPadding = min(paddingTop, paddingBottom)
  37. val avgPadding = (viewHeight - textHeight) / 2
  38. when {
  39. avgPadding < minPadding -> {
  40. fm.ascent += avgPadding
  41. fm.descent -= avgPadding
  42. }
  43. paddingTop < paddingBottom -> {
  44. fm.ascent = rect.top
  45. fm.descent = textHeight + fm.ascent
  46. }
  47. else -> {
  48. fm.descent = rect.bottom
  49. fm.ascent = fm.descent - textHeight
  50. }
  51. }
  52. }
  53. },
  54. 0,
  55. text.length,
  56. Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
  57. )
  58. ssb
  59. }
  60. }
  61. }

参考

Android的TextView自动适配文本大小的几种方案