搞 Android 开发的兄弟们都知道,想要进阶高级,自定义 View 绝对是一道绕不过去的坎儿。而在自定义 View 的世界里,如果说 Canvas(画布)是我们的画板,那么 Paint(画笔)就是我们手里的那支马良神笔。
今天,咱们就抛开枯燥的官方文档,用大白话给大家盘一盘 Paint 那些最常用的 API、让人头疼的文字对齐计算,以及能玩出各种炫酷花样的 Shader 渲染特效。
提示:在开始阅读前,大家可以先看一眼下面的知识脑图,对今天要讲的内容有个大致的框架。
一、 Paint 画笔初探:那些藏在源码里的秘密
Paint 主要是用来保存绘制几何图形、文本和位图的样式以及颜色信息的。
如果你平时有翻看源码的习惯,点进 Paint 类看一眼,就会发现里面密密麻麻全是一堆 get/set 方法。更有意思的是,真正干活的方法基本都带着 native 关键字。这意味着啥?意味着我们在 Java/Kotlin 层调用的这些 API,本质上就像是个“遥控器”,真正的绘制工作是交给了底层的图形渲染引擎去高效完成的。
二、 常用 API 避坑指南
为了方便记忆,我把平时开发中最常用的 API 分成了几个大类:
1. 基础设置(必会款)
- setColor / setARGB:选颜色,调透明度,没啥好说的。
- setAntiAlias(boolean):抗锯齿。这个强烈建议在初始化画笔时无脑设置为 true!不然画出来的圆边缘全是锯齿,非常影响 UI 质感。
- setStyle(Paint.Style):画笔模式。
- FILL:实心填充(默认)。
- STROKE:空心描边。
- FILL_AND_STROKE:既填充又描边。
2. 描边细节(UI 设计师的强迫症)
当你的画笔设置为 STROKE(描边)时,这几个方法就派上用场了:
- setStrokeWidth:线有多粗。
- setStrokeCap:线条两端的形状(线帽)。比如 BUTT(平头)、ROUND(圆头,画圆角进度条必备)、SQUARE(方头,注意它比平头会长出半个线宽)。
- setStrokeJoin:线条拐角处的形状。MITER(尖角)、BEVEL(平切角)、ROUND(圆角)。
3. 高级滤镜与特效
- setShader(Shader):大招来了,设置渲染器,后面咱们单开一章讲。
- setXfermode:图层混合模式。配合 PorterDuff 使用,处理两张图的交集、并集,实现刮刮乐效果全靠它。
- setFilterBitmap:双线性过滤。简单来说,如果你要把一张小图放大画出来,开启它能让图片不那么“马赛克”,过渡更平滑。
三、 让人又爱又恨的 FontMetrics(字体度量)
说到用 Paint 画文字,十个 Android 开发者里有九个都在“文字垂直居中”上踩过坑。这是因为 Android 画文字并不是从左上角开始画的,而是基于一条叫 Baseline(基线)的参考线。
这时候,就轮到 FontMetrics 出场了。
为了更直观地理解,大家一定要对照着下面这张图来看:
我们以红色的 Baseline 为坐标轴的 \(Y=0\)(注意:在 Android 坐标系中,向下为正,向上为负):
- baseline:基线,文字绘制的基石。
- ascent:字符最高点到基线的“推荐”距离(绿线,通常是负值)。
- top:字符最高点到基线的“极限”距离(灰线,绝对值一般比 ascent 大一点)。
- descent:字符最低点到基线的“推荐”距离(黄线,通常是正值,比如字母 g 下面那个弯弯)。
- bottom:字符最低点到基线的“极限”距离(紫线)。
- leading:行间距,就是上一行的 descent 到下一行的 ascent 之间的距离。
实战小技巧: 想要计算一行文字的精确高度怎么办?非常简单,套公式: \(Height = descent - ascent\)
四、 Shader 渲染器:给 UI 加点特效
如果说前面的 API 是给图形上单色,那 Shader 就是教你怎么给图形穿上花衣服。Shader 有五大派系,配合 TileMode 可以玩出无数花样:
1. 五大渲染器介绍
- LinearGradient(线性渲染):指定起点和终点,颜色顺着一条线慢慢过渡。
- RadialGradient(环形渲染):像水波纹一样,从一个圆心向外围辐射渐变。
- SweepGradient(扫描渲染):这个最典型,想想雷达扫描图,或者那种五颜六色的圆环进度条,就是它干的。围绕圆心 360 度顺时针渐变。
- BitmapShader(位图渲染):划重点! 这是做“圆形头像”的神器。直接把一张图片当成颜料(纹理)画上去,省去了复杂的图层叠加(Xfermode)裁剪。
- ComposeShader(组合渲染):如果一种特效不够,那就把两个 Shader 绑在一起,通过图层混合模式叠加,效果拉满。
2. TileMode 排版方式
当你要绘制的区域(比如一个大长方形)比你的 Shader 设定的范围还要大时,超出的部分怎么办?这时候就要选 TileMode 填充规则了:
- CLAMP:死命拉伸边缘的最后一个像素,强行铺满剩余空间。
- REPEAT:像贴瓷砖一样,超出部分不断重复原来的图案。
- MIRROR:也是平铺,但是每次重复都会像照镜子一样反转一下,衔接处会更自然。
掌握了以上这些 Paint 和 Shader 的核心套路,绝大多数的自定义 View 绘制需求你都能拿捏得死死的了。
本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。
Android's development brothers know that trying to get to the top, self-defined View is definitely not going to go around together. And in the self-defined View world, if Canvas is our drawing board, then Pant is the horse's magic pen in our hands.
Today, let's leave out the dry official files and play a plate of Paint's most common APIs, headaches, and Shaders that can play all sorts of fancy tricks.
Note: Before you start reading, you can take a look at the following picture of your knowledge and have a broad framework for what we are going to say today.
First, Paint, the first work of the brush: the secrets hidden in the source code.
Pant is primarily used to preserve styles and colour information for geometric graphics, text and bitmaps.
If you're used to looking through the source code, click into the Pant class, you'll see that all the incisors are a bunch of get/set methods. And what's more interesting is that the real way to work is basically a native keyword. What does that mean? It means that the API that we're using on Java/Kotlin level is essentially like a remote control, and the real work is being done efficiently with the bottom graphic rendering engine.
II. Common API shelter guide
In order to facilitate memory, I divided the API most commonly developed into several broad categories:
1. Foundation (mandatory)
- SetColor/setarGB: Color selection, transparency, nothing to say.
- Set Antialias (boolean): Anti-sawing. This strongly suggests setting brainless at initialization of the brush as true! Otherwise, the edges of the circle are all sawn teeth, which affect very much the UI taste.
- SetStyle (Paint.Style): Brush pattern.
- FILL: Solid filling (default).
- STROKE: Empty side.
- FIL AND STROKE: Filling and drawing.
2. Side details (UI Designers ' Compulsive Disorder)
When your brush is set to Strooke, these methods work:
- Set StrokeWidth: How thick is the line?
- SetStrokeCap: shape of both ends of the line (wire hat). For example, the BUTT, the ROUND, the roundhead, the drawing of the roundabout, and the SQUARE, the square head, notice that it will grow half a line wider than the flathead.
- setStrokeJoin: shape at the corner of the line. MITER (twice angle), BEVEL (square angle), ROUND (round corner).
3. Advanced filters and effects
- SetShader: Here's the big move. Set the rendering, and then we'll talk in one chapter.
- SetXfermode: Layer Mixed Mode. Complementing the PorterDuff use, handles the intersection of the two maps, and combines them to achieve the scraping effect.
- SetFilterBitmap: Double-linear filter. Simply put, if you're going to zoom out a little picture, turn it on and make it less "Marsake" and more smoother.
III. FontMetrics
Speaking of drawing text in Paint, nine of the ten Android developers have stepped on the pit on the "text vertically." This is because Android did not start with the upper left corner, but was based on a reference line called Baseline (baseline).
It's time for FontMetrics to show up.
In order to understand more intuitively, you must look at the following picture:
We have red Baseline as the axis of the coordinates (note: in the Android coordinates, down is positive, up is negative):
- Baseline: a baseline, a cornerstone of text drawing.
- Ascent: the " recommended " distance from the top of the character to the baseline (green line, usually negative).
- top point of character to the " limit " distance of the baseline (grey line, absolute value is generally a little larger than ascent).
- Discent: minimum point of character to the " recommended " distance from the baseline (yellow line, usually a positive value, such as the letter g below).
- bottom: minimum point of character to the " limit " distance from the baseline (twilight).
-Lating: The line spacing is the distance between the previous line and the next line.
What about the exact height of a line of words? Very simple. Set formula: \(Height = discent - ascent\)
IV. Shader Renderer: Add some special effects to UI
If the API in front is monochromatic, then Shader is teaching you how to wear flowers for graphics. Shader has five factions, working with TileMode, who can do countless tricks:
1. Introduction to the five renderers
- Linear Gradient (linear rendering): specify the starting point and end point, with the colour slowly transitioning along a line.
- Radial Gradient: Gradiently, like a water waver, from a circle to the outer.
-SweepGradient: This is the most typical thing, thinking about radar scans, or the colored circle of progress that it did. Gradient around a circle centre at 360 degrees.
- BitmapShader: Focus! It's the god of the circle. It's just a painting of a picture as paint (texture), saving a complex layer of cross-cut.
- ComposeShader (combining): If one of the effects is not enough, then tie two Shaders together, superimpose them by mixing the layers, and the effect is full.
TileMode layout
What happens when you're going to draw more areas than your Shader set? It's time to select TileMode filler:
- CLAMP: The last pixel on the edge of death stretches, forced to fill the remaining space.
- REPEAT: Like tiles, the excess repeats the original pattern.
- MIRROR: It's also paved, but it's more natural to rewind each time it's repeated like a mirror.
With the above pant and Shader cores, most of the custom-defined Viw drawing needs you can squeeze to death.
Auto-fetched and translated by AI Atlas. All rights belong to the original author.