1、我们再Android布局的时候会涉及到不同分辨率的手机显示效果不同。
2、如果我们一律用XML布局,字体用SP,间距用DP,可以很好地显示TextView。
3、如果我们一律用自定义的布局,设置好mTextSize,mSpaceHeight,也可以显示TextView
4、但是如果我们要求自定义的布局,Paint画出来的字体和XML文件设置的效果是一样的,如何做到?
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="0"
android:layout_marginTop="-5dp"
android:textColor="@color/c_ffffff"
android:textSize="45sp" />
<TextView
android:id="@+id/text_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text=""
android:layout_marginTop="-6dp"
android:textColor="@color/c_ffffff"
android:textSize="12sp"/>
LinearLayout>
根据上面的布局文件,可以发现两个TextView,第一个字体45SP,第二个字体12SP,上下距离-6dp。效果如图所示:
现在我们要求在定义布局中,用Paint画出这样的效果。
首先我们看一张图:
这张图标记了很多高度,但我们需要关注的只有3个
我们要用画笔画的效果如图所示:
可以看出此时字体大小,甚至两个TextView之间高度和前面XML布局的效果都有很大的差异,现在我们要求大字体在圆圈的中间,小字体距离大字体-6dp。
本文只关注字体的设置,其他不论。
String str = nums;
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Style.FILL);
float textWidth = mPaint.measureText(str);
Paint.FontMetrics metric = mPaint.getFontMetrics();
float baseline = getHeight() / 2 - (metric.ascent + metric.descent) / 2;
canvas.drawText(str, getWidth() / 2 - textWidth / 2, baseline, mPaint);
mPaint.setTextSize(mSmallTextSize);
String strstatus = mStatus;
canvas.drawText(strstatus, (getWidth()-mPaint.measureText(strstatus)) / 2, baseline+spaceH+((metric.descent-metric.ascent))/2, mPaint);
首先在设置mTextSize和mSmallTextSize的时候要注意,一定要把sp转换px。
(最初的时候,我把UI设计师标注的px直接设置进来,导致在分辨率低的手机上太难看)
画第一个Text的时候,位置为总高度的中间位置,我们获取字体的metric ,得到ascent 和descent,求得字体的baseline高度。(descent为正数,ascent为负数)
其次在画第二个Text的时候,切记位置为,第一个Text的高度+Space高度。高度必须把dp转换为px
mTextSize = sp2px(context,45);
mSmallTextSize = sp2px(context,12);
spaceH = dip2px(context,-6);
转换代码如下:
1、sp转px
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
2、dp转px
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
这样就达到了和XML布局一样的效果,即使在分辨率低的手机上也是一样。
如图效果: