android 消除字体上下间距

15 篇文章 0 订阅

案例
上图第一个阿道夫:直接使用AppCompatTextView的展示效果

 <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:background="@color/purple_200"
        android:padding="0dp"
        android:text="阿道夫"
        android:textSize="20dp" />

第二个阿道夫:在第一个的基础上添加了 android:includeFontPadding=“false”,发现还是有一点留白。

第三个阿道夫:通过继承View后,自定义控件。


下面说下自定义控件如何实现上面三个阿道夫的效果
在这里插入图片描述
说一下我对上图的理解:

  1. FontMetricInt.top 和 FontMetricInt.bottom ------- 表示字体的顶部和底部,其会比字体实际更大些
  2. FontMetricInt.ascent 和 FontMetricInt.descent -------- 表示字体可能占据的顶部和底部。为啥说可能了?
    可以看到上图的dangwen中的g的底部会比danwen都要底,其他字体可能比g的底部还要低。那么最低的底线就是FontMetricInt.descent.
  3. Rect ------- 红框部分,表示字体实际需要的大小。也是第三个阿道夫想要的。

首先我们通过自定义View 来实现第一个阿道夫的效果

模拟第一个阿道夫

  1. 获得 fontMetrics 对象
。。。。。。

// 重写onMeasure 和 onDraw
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        calculateTextParams();
        setMeasuredDimension(widthMeasureSpec, (int) (-fm.top + fm.bottom));
    }
     
@Override
    protected void onDraw(Canvas canvas) {
        final String text = calculateTextParams();
        canvas.save();
        // -fm.top 就是基线位置
        canvas.drawText(text, 0, -fm.top, mPaint);
        canvas.restore();
    }
    
 private final Paint mPaint = new Paint();
 private Paint.FontMetrics fm;
 private String calculateTextParams() {
        final String text = "阿道夫";
        final int textLength = text.length();
        mPaint.setTextSize(60);
        fm = mPaint.getFontMetrics();
        if (textLength == 0) {
            mBounds.right = mBounds.left;
        }
        return text;
 } 
 。。。。。。   

效果图如下:
在这里插入图片描述

模拟第二个阿道夫

将上面的代码修改下:

  setMeasuredDimension(widthMeasureSpec, (int) (-fm.top + fm.bottom));
  
  canvas.drawText(text, 0, -fm.top, mPaint);

在这里插入图片描述

模拟第三个阿道夫

第三个阿道夫上下不需要留白,我们只需要获得Rect红框就行。

public class TextNoPaddingextends View {
    private final static String TAG = "TextNoPadding";
    private final Paint mPaint = new Paint();
    private final Rect mBounds = new Rect();

    public TestTextView(Context context) {
        super(context);
    }

    public TestTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TestTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        final String text = calculateTextParams();
        canvas.save();
        canvas.drawText(text, 0, -mBounds.top, mPaint);
        canvas.restore();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        calculateTextParams();
        setMeasuredDimension(widthMeasureSpec, (int) (-mBounds.top + mBounds.bottom));
    }

    private String calculateTextParams() {
        final String text = "阿道夫";
        final int textLength = text.length();
        mPaint.setTextSize(60);
        mPaint.getTextBounds(text, 0, textLength, mBounds);
        if (textLength == 0) {
            mBounds.right = mBounds.left;
        }
        return text;
    }
}

效果就是第三个阿道夫。。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值