
上图第一个阿道夫:直接使用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后,自定义控件。
下面说下自定义控件如何实现上面三个阿道夫的效果

说一下我对上图的理解:
首先我们通过自定义View 来实现第一个阿道夫的效果
。。。。。。
// 重写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;
}
}
效果就是第三个阿道夫。。。。