系列文章目录
前言
这系列的文章主要是基于扔物线的HenCoderPlus课程的源码来分析学习。
- 扔物线课程源码:ImageTextView.java
- Android官方文档:自定义绘制
这一篇文章主要介绍的是文字的测量,更多的内容可以参考:HenCoder Android 开发进阶:自定义 View 1-3 drawText() 文字的绘制。
创建绘制对象
我们需要创建一个画笔🖌Paint
来绘制我们的头像的边框,也需要提前加载我们的头像到内存(Bitmap)中。
public class ImageTextView extends View {
// 图片的宽度
private static final float IMAGE_WIDTH = Utils.dp2px(100);
// 图片的偏移位置
private static final float IMAGE_OFFSET = Utils.dp2px(80);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 头像
Bitmap bitmap;
public ImageTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
// 记载图片的代码请见下一小节
bitmap = getAvatar((int) IMAGE_WIDTH);
}
}
加载图片
为避免出现
java.lang.OutOfMemory
异常,请先检查位图的尺寸,然后再对其进行解码,除非您绝对信任该来源可为您提供大小可预测的图片数据,以轻松适应可用的内存。——引用自Android官方文档:高效加载大型位图
下述源码的分析请见官方的说明:将按比例缩小的版本加载到内存中。
public class ImageTextView extends View {
// 头像
Bitmap bitmap;
Bitmap getAvatar(int width) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.avatar_rengwuxian, options);
options.inJustDecodeBounds = false;
options.inDensity = options.outWidth;
options.inTargetDensity = width;
return BitmapFactory.decodeResource(getResources(), R.drawable.avatar_rengwuxian, options);
}
}
自定义绘制内容
先上一下我们绘制简易图文混排的效果图。
![示意图](https://i-blog.csdnimg.cn/blog_migrate/f3f17e8022787f37baaf255c8862f66e.png)
绘制图片
public class ImageTextView extends View {
// 图片的宽度
private static final float IMAGE_WIDTH = Utils.dp2px(100);
// 图片的偏移位置
private static final float IMAGE_OFFSET = Utils.dp2px(80);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 头像
Bitmap bitmap;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, getWidth() - IMAGE_WIDTH, IMAGE_OFFSET, paint);
}
}
![示意图](https://i-blog.csdnimg.cn/blog_migrate/ae65f86bc0413ecd3d7e16557c2afb4d.png)
绘制文字
绘制文字是图文混排的重头戏。我们需要在确保不会和图片重合的前提下,将文字分布在图片的周围。同时,我们还需要让文字和合适的地方自动换行,确保不会绘制到屏幕外边去。
![示意图](https://i-blog.csdnimg.cn/blog_migrate/f12ca60390cf191b96e2ee57cc68eeb7.png)
如上图所示,我们需要将文字绘制在红色区域。那么我们开始绘制吧。
绘制中,有几个关键的问题:
- 如何计算/获取将要绘制的文本的宽高?
- 如何计算第N行的将要绘制文本的起始位置?
- 如何计算将要绘制文本的位置所允许的最大宽度和字符数量?
让我们带着问题去学习吧。
文本宽高获取
文本的宽高的获取可以通过android.graphics.Paint.FontMetrics
来实现。