自定义View时,如何设置字体的大小和间距,和XML布局达到一样的效果

问题

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个

  • 1、Baseline,基准点是baseline
  • 2、Accent,Ascent是baseline之上至字符最高处的距离
  • 3、Descent,Descent是baseline之下至字符最低处的距离

我们要用画笔画的效果如图所示:

可以看出此时字体大小,甚至两个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布局一样的效果,即使在分辨率低的手机上也是一样。
如图效果:

XML布局

自定义View

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇