1.曾经也算半个艺术家,深知笔的重要性与复杂性 2.Android里的Paint设置项好多基本上都是setXXX,getXXX,很多文字相关的内容都在Paint里 3.主要由画笔常规配置,画笔类型、画笔特效(线效,着色,滤色)、画笔文字 4.本文暂时还无法覆盖Paint的所有API,能用的吾尽量都会涉及一下
paint的Set一览.png
public void setColor(@ColorInt int color) //设置颜色 public void setAlpha(int a)//设置透明度 public void setARGB(int a, int r, int g, int b)//设置ARGB颜色 public void setStrokeWidth(float width)//设置宽度 public void setAntiAlias(boolean aa)//设置抗锯齿
基本设置.png
Paint.Style.
:[#FILL
|STROKE
|FILL_AND_STROKE
]/** * 样式测试 * @param canvas */ private void testStyle(Canvas canvas) { Rect rect = new Rect(0, 0, 100, 100); mRedPaint.setStrokeWidth(15); canvas.save(); mRedPaint.setStyle(Paint.Style.FILL); canvas.translate(50, 450); canvas.drawRect(rect, mRedPaint); canvas.translate(150, 0); mRedPaint.setStyle(Paint.Style.STROKE); canvas.drawRect(rect, mRedPaint); canvas.translate(150 , 0); mRedPaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawRect(rect, mRedPaint); canvas.restore(); mRedPaint.setStrokeWidth(40); }
画笔样式测试.png
Paint.Cap.
:[#BUTT
|ROUND
|SQUARE
]/** * 绘制圆形的点 * * @param canvas */ private void drawPos(Canvas canvas) { //设置画笔圆帽 mRedPaint.setStrokeCap(Paint.Cap.ROUND); mRedPaint.setStrokeWidth(20); //绘制点 canvas.drawPoint(100, 100, mRedPaint); canvas.drawPoints(new float[]{ 400, 400, 500, 500, 600, 400, 700, 350, 800, 300, 900, 300 }, mRedPaint); }
绘制圆点.png
2.三种线帽比较
/** * 线帽型状测试:Paint.Cap.BUTT、Paint.Cap.ROUND、Paint.Cap.SQUARE * * @param canvas */ private void testOfCap(Canvas canvas) { canvas.save(); canvas.translate(150, 200); //线帽测试: mRedPaint.setStrokeCap(Paint.Cap.BUTT);//无头(默认) canvas.drawLine(0, 0, 0, 200, mRedPaint); canvas.translate(50, 0); mRedPaint.setStrokeCap(Paint.Cap.ROUND);//圆头 canvas.drawLine(0, 0, 0, 200, mRedPaint); canvas.translate(50, 0); mRedPaint.setStrokeCap(Paint.Cap.SQUARE);//方头 canvas.drawLine(0, 0, 0, 200, mRedPaint); canvas.restore(); }
线帽型状测试.png
Paint.Join.
:[#BEVEL
|ROUND
|MITER
]注意:只有路径绘制的线才有交角效果
/** * 角型测试:Paint.Join.BEVEL、Paint.Join.ROUND、Paint.Join.MITER * * @param canvas */ private void testOfJoin(Canvas canvas) { mRedPaint.setStyle(Paint.Style.STROKE); mRedPaint.setStrokeWidth(40); Path path = new Path(); path.moveTo(30, 0); path.lineTo(0, 100); path.lineTo(100, 100); canvas.save(); canvas.translate(600, 100); mRedPaint.setStrokeJoin(Paint.Join.BEVEL);//直线(默认) canvas.drawPath(path, mRedPaint); canvas.translate(150, 0); mRedPaint.setStrokeJoin(Paint.Join.ROUND);//圆角 canvas.drawPath(path, mRedPaint); canvas.translate(150, 0); mRedPaint.setStrokeJoin(Paint.Join.MITER);//锐角 canvas.drawPath(path, mRedPaint); canvas.restore(); }
线交角测试.png
第一参为显隐线段的长度,第二参为偏移值 下面会动的线是不断改变偏移量:mDashOffSet的结果
虚线效果.gif
/** * 虚线测试 * * @param canvas */ private void dashEffect(Canvas canvas) { mEffectPaint = new Paint(mRedPaint); mEffectPaint.setStrokeCap(Paint.Cap.BUTT); //显示100,隐藏50,显示50,隐藏50,的循环 mEffectPaint.setPathEffect(new DashPathEffect(new float[]{100, 50, 50, 50}, 0)); Path path = new Path(); path.moveTo(100, 650); path.lineTo(1000, 650); canvas.drawPath(path, mEffectPaint); //显示100,隐藏50,显示60,隐藏50,的循环,偏移:mDashOffSet mEffectPaint.setPathEffect(new DashPathEffect(new float[]{100, 50, 50, 50}, mDashOffSet)); Path pathOffset50 = new Path(); pathOffset50.moveTo(100, 750); pathOffset50.lineTo(1000, 750); canvas.drawPath(pathOffset50, mEffectPaint); }
动画是不断改变圆角大小:mEffectCorner的结果
折角弧.gif
/** * 圆角折线 * * @param canvas */ private void cornerEffect(Canvas canvas) { mEffectPaint.setPathEffect(new CornerPathEffect(mEffectCorner)); mEffectPaint.setStyle(Paint.Style.STROKE); mEffectPaint.setStrokeWidth(40); Path path = new Path(); path.moveTo(550, 550); path.lineTo(900, 300); path.lineTo(1000, 550); canvas.drawPath(path, mEffectPaint); //蓝色辅助线 Paint tempPaint = new Paint(); tempPaint.setStyle(Paint.Style.STROKE); tempPaint.setColor(Color.BLUE); tempPaint.setStrokeWidth(2); tempPaint.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0)); Path helpPath = new Path(); helpPath.moveTo(550, 550); helpPath.lineTo(900, 300); helpPath.lineTo(1000, 550); canvas.drawPath(helpPath, tempPaint); }
离散路径.png
/** * 离散路径 * * @param canvas */ private void discreteEffect(Canvas canvas) { canvas.save();//保存画布状态 canvas.translate(0, 950); //第一个参数:将原来的路径切成多长的线段,越小,所切成的小线段越多 //第二参数:被切成的每个小线段的可偏移距离。越大,每个线段的可偏移距离就越大。 Path path = new Path(); // 定义路径的起点 path.moveTo(100, 0); path.lineTo(600, -100); path.lineTo(1000, 0); mEffectPaint.setPathEffect(new DiscretePathEffect(2, 5)); mEffectPaint.setStrokeWidth(2); canvas.drawPath(path, mEffectPaint); canvas.translate(0, 100); mEffectPaint.setPathEffect(new DiscretePathEffect(20, 5)); canvas.drawPath(path, mEffectPaint); canvas.restore();//重新储存画布状态 }
路径样点.gif
通过动图可以很清楚得看出三个样式的区别 动图是不断改变偏移量:mDashOffSet的结果
//Path shape:表示[路径点样],这里是一个五角星 //float advance:表示两个[路径点样]间的距离 //float phase:路径绘制偏移距离 //Style style:表示在遇到转角时的过渡样式 // ----Style.ROTATE表示通过旋转[路径点样]来过渡转角; // ----Style.MORPH表示通过变形[路径点样]来过渡转角; // ----Style.TRANSLATE表示通过位移[路径点样]来过渡转角。
/** * 路径点样路径样式 * * @param canvas */ private void PathDashEffect(Canvas canvas) { canvas.save(); canvas.translate(0, 1100); Path path = new Path(); // 定义路径的起点 path.moveTo(100, 80); path.lineTo(600, -100); path.lineTo(1000, 80); //变形过渡 mEffectPaint.setPathEffect(new PathDashPathEffect( CommonPath.nStarPath(5, 16, 8), 40, mDashOffSet, PathDashPathEffect.Style.ROTATE)); canvas.drawPath(path, mEffectPaint); canvas.restore(); //旋转过渡 canvas.save(); canvas.translate(0, 1200); mEffectPaint.setPathEffect(new PathDashPathEffect( CommonPath.nStarPath(5, 16, 8), 40, mDashOffSet, PathDashPathEffect.Style.MORPH)); canvas.drawPath(path, mEffectPaint); canvas.restore(); //移动过渡 canvas.save(); canvas.translate(0, 1300); mEffectPaint.setPathEffect(new PathDashPathEffect( CommonPath.nStarPath(5, 16, 8), 40, mDashOffSet, PathDashPathEffect.Style.TRANSLATE)); canvas.drawPath(path, mEffectPaint); canvas.restore(); } /** * 离散路径 * * @param canvas */ private void discreteEffect(Canvas canvas) { canvas.save();//保存画布状态 canvas.translate(0, 950); //第一个参数:将原来的路径切成多长的线段,越小,所切成的小线段越多 //第二参数:被切成的每个小线段的可偏移距离。越大,每个线段的可偏移距离就越大。 Path path = new Path(); // 定义路径的起点 path.moveTo(100, 0); path.lineTo(600, -100); path.lineTo(1000, 0); mEffectPaint.setPathEffect(new DiscretePathEffect(2, 5)); mEffectPaint.setStrokeWidth(2); canvas.drawPath(path, mEffectPaint); canvas.translate(0, 100); mEffectPaint.setPathEffect(new DiscretePathEffect(20, 5)); canvas.drawPath(path, mEffectPaint); canvas.restore();//重新储存画布状态 }
/** * n角星路径 * * @param num 几角星 * @param R 外接圆半径 * @param r 内接圆半径 * @return n角星路径 */ public static Path nStarPath(int num, float R, float r) { Path path = new Path(); float perDeg = 360 / num; float degA = perDeg / 2 / 2; float degB = 360 / (num - 1) / 2 - degA / 2 + degA; path.moveTo( (float) (Math.cos(rad(degA + perDeg * 0)) * R + R * Math.cos(rad(degA))), (float) (-Math.sin(rad(degA + perDeg * 0)) * R + R)); for (int i = 0; i < num; i++) { path.lineTo( (float) (Math.cos(rad(degA + perDeg * i)) * R + R * Math.cos(rad(degA))), (float) (-Math.sin(rad(degA + perDeg * i)) * R + R)); path.lineTo( (float) (Math.cos(rad(degB + perDeg * i)) * r + R * Math.cos(rad(degA))), (float) (-Math.sin(rad(degB + perDeg * i)) * r + R)); } path.close(); return path; } /** * 角度制化为弧度制 * * @param deg 角度 * @return 弧度 */ public static float rad(float deg) { return (float) (deg * Math.PI / 180); }
特效叠加.gif
/** * 叠加样式 * * @param canvas */ private void composeEffect(Canvas canvas) { mEffectPaint.setStyle(Paint.Style.STROKE); mEffectPaint.setStrokeWidth(40); canvas.save(); canvas.translate(0, 1400); Path path = new Path(); // 定义路径的起点 path.moveTo(100, 80); path.lineTo(600, -100); path.lineTo(1000, 80); PathDashPathEffect effect1 = new PathDashPathEffect( CommonPath.nStarPath(5, 16, 8), 40, mDashOffSet, PathDashPathEffect.Style.ROTATE); DiscretePathEffect effect2 = new DiscretePathEffect(20, 5); mEffectPaint.setPathEffect(new ComposePathEffect(effect1, effect2));//离散效果+样点效果 canvas.drawPath(path, mEffectPaint); canvas.restore(); }
路径叠加.gif
/** * 路径叠加 * * @param canvas */ private void sumEffect(Canvas canvas) { canvas.save(); canvas.translate(0, 1500); Path path = new Path(); // 定义路径的起点 path.moveTo(100, 80); path.lineTo(600, -100); path.lineTo(1000, 80); PathDashPathEffect effect1 = new PathDashPathEffect( CommonPath.nStarPath(5, 16, 8), 40, mDashOffSet, PathDashPathEffect.Style.ROTATE); DiscretePathEffect effect2 = new DiscretePathEffect(20, 5); mEffectPaint.setPathEffect(new SumPathEffect(effect1, effect2));//离散效果+样点效果 canvas.drawPath(path, mEffectPaint); canvas.restore(); }
一个很简单的类,有5个子类:
Shader.png
渐变模式:
Shader.TileMode.
[MIRROR
|CLAMP
|REPEAT
] (图中很形象,就不解释了)
int colorStart = Color.parseColor("#84F125"); int colorEnd = Color.parseColor("#5825F1"); canvas.save(); canvas.translate(mCoo.x, mCoo.y); mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setShader( new LinearGradient( -200, 0, 200, 0, colorStart, colorEnd, Shader.TileMode.MIRROR )); canvas.drawRect(-400,-200,400,-100,mRedPaint); canvas.translate(0, 150); mRedPaint.setShader( new LinearGradient( -100, 0, 100, 0, colorStart, colorEnd, Shader.TileMode.CLAMP )); canvas.drawRect(-400,-200,400,-100,mRedPaint); canvas.translate(0, 150); mRedPaint.setShader( new LinearGradient( -100, 0, 100, 0, colorStart, colorEnd, Shader.TileMode.REPEAT )); canvas.drawRect(-400,-200,400,-100,mRedPaint);
线性渐变.png
多色渐变.png
int[] colors = new int[]{ Color.parseColor("#F60C0C"),//红 Color.parseColor("#F3B913"),//橙 Color.parseColor("#E7F716"),//黄 Color.parseColor("#3DF30B"),//绿 Color.parseColor("#0DF6EF"),//青 Color.parseColor("#0829FB"),//蓝 Color.parseColor("#B709F4"),//紫 }; float[] pos = new float[]{ 1.f / 7, 2.f / 7, 3.f / 7, 4.f / 7, 5.f / 7, 6.f / 7, 1 }; canvas.translate(0, 150); mRedPaint.setShader( new LinearGradient( -300, 0, 300, 0, colors, pos, Shader.TileMode.CLAMP )); canvas.drawRect(-400, -200, 400, -100, mRedPaint);
canvas.translate(mCoo.x, mCoo.y); int colorStart = Color.parseColor("#84F125"); int colorEnd = Color.parseColor("#5825F1"); mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setShader( new RadialGradient( 0,0,50, colorStart, colorEnd, Shader.TileMode.MIRROR )); canvas.drawCircle(0, 0, 150, mRedPaint); canvas.translate(350, 0); mRedPaint.setShader( new RadialGradient( 0,0,50, colorStart, colorEnd, Shader.TileMode.CLAMP )); canvas.drawCircle(0, 0, 150, mRedPaint); canvas.translate(350, 0); mRedPaint.setShader( new RadialGradient( 0,0,50, colorStart, colorEnd, Shader.TileMode.REPEAT )); canvas.drawCircle(0, 0, 150, mRedPaint);
径像渐变.png
RadialGradient(渐变中心,渐变半径,渐变模式,颜色数组,位置百分点数组0~1,渐变模式)
多色径向渐变.png
int[] colors = new int[]{ Color.parseColor("#F60C0C"),//红 Color.parseColor("#F3B913"),//橙 Color.parseColor("#E7F716"),//黄 Color.parseColor("#3DF30B"),//绿 Color.parseColor("#0DF6EF"),//青 Color.parseColor("#0829FB"),//蓝 Color.parseColor("#B709F4"),//紫 }; float[] pos = new float[]{ 1.f / 7, 2.f / 7, 3.f / 7, 4.f / 7, 5.f / 7, 6.f / 7, 1 }; mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setShader( new RadialGradient( 0, 0, 200, colors, pos, Shader.TileMode.CLAMP )); canvas.drawCircle(0, 0, 250, mRedPaint);
这个要比上面的简单一点,没有渐变的模式 双色扫描渐变:SweepGradient(中心点x,y,颜色1,颜色2) 多色扫描渐变:SweepGradient(中心点x,y,颜色数组,位置百分点数组0~1)
扫描渐变.png
int colorStart = Color.parseColor("#84F125"); int colorEnd = Color.parseColor("#5825F1"); mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setShader( new SweepGradient(0, 0, colorStart, colorEnd)); canvas.drawCircle(0, 0, 150, mRedPaint); canvas.translate(400, 0); int[] colors = new int[]{ Color.parseColor("#F60C0C"),//红 Color.parseColor("#F3B913"),//橙 Color.parseColor("#E7F716"),//黄 Color.parseColor("#3DF30B"),//绿 Color.parseColor("#0DF6EF"),//青 Color.parseColor("#0829FB"),//蓝 Color.parseColor("#B709F4"),//紫 }; float[] pos = new float[]{ 1.f / 7, 2.f / 7, 3.f / 7, 4.f / 7, 5.f / 7, 6.f / 7, 1 }; mRedPaint.setShader( new SweepGradient(0, 0, colors, pos)); canvas.drawCircle(0, 0, 150, mRedPaint);
用图片的所有像素点作为画笔的颜色
//加载图片,生成图片着色器 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.menu_bg); BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP); mRedPaint.setShader(bs); mRedPaint.setTextSize(150); mRedPaint.setStrokeWidth(10); mRedPaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawText("张风捷特烈", 0, 500, mRedPaint);
图片着色.png
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.menu_bg); BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mRedPaint.setShader(bs); mRedPaint.setStyle(Paint.Style.FILL); Path path = CommonPath.nStarPath(8, 500, 250); canvas.drawPath(path, mRedPaint);
使用路径裁剪图片.png
还有一个ComposeShader比较复杂,以后有需求会专门写一篇
颜色过滤器.png
看图体会一下吧...我不说了
LightingColorFilter测试.png
Bitmap mainBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.menu_bg); mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setColorFilter(new LightingColorFilter( Color.parseColor("#FF0000"),//红 Color.parseColor("#0000ff")//蓝 )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); mRedPaint.setColorFilter(new LightingColorFilter( Color.parseColor("#FF0000"),//红 Color.parseColor("#00ff00")//绿 )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); mRedPaint.setColorFilter(new LightingColorFilter( Color.parseColor("#FF0000"),//红 Color.parseColor("#000000")//黑 )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.restore();
PorterDuff.Mode一共17中,在Color专题会详述,这里举几个栗子看看
PorterDuffColorFilter测试.png
Bitmap mainBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.menu_bg); mRedPaint.setStyle(Paint.Style.FILL); mRedPaint.setColorFilter(new PorterDuffColorFilter( Color.parseColor("#0000ff"), PorterDuff.Mode.DARKEN)); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); mRedPaint.setColorFilter(new PorterDuffColorFilter( Color.parseColor("#0000ff"),PorterDuff.Mode.LIGHTEN )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); mRedPaint.setColorFilter(new PorterDuffColorFilter( Color.parseColor("#0000ff"),PorterDuff.Mode.SCREEN )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); mRedPaint.setColorFilter(new PorterDuffColorFilter( Color.parseColor("#0000ff"),PorterDuff.Mode.OVERLAY )); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint);
刚好前端时间对ColorMatrix有一点研究,这里拿来用用
颜色矩阵.png
ColorMatrix.png
Bitmap mainBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.menu_bg); mRedPaint.setStyle(Paint.Style.FILL); //关闭RGB颜色通道(变为黑色),后偏移红色255 float[] matrix = new float[]{ -1, 0, 0, 0, 255, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0 }; ColorMatrix colorMatrix = new ColorMatrix(matrix); mRedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); //关闭RGB颜色通道(变为黑色),后偏移蓝色255 float[] matrix2 = new float[]{ -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0 }; ColorMatrix colorMatrix2 = new ColorMatrix(matrix2); mRedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix2)); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); //关闭RGB颜色通道(变为黑色),后偏移三色255 float[] matrix3 = new float[]{ -1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0 }; ColorMatrix colorMatrix3 = new ColorMatrix(matrix3); mRedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix3)); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint); canvas.translate(350, 0); float[] matrix4 = new float[]{ //只要把RGB三通道的色彩信息设置成一样:即:R=G=B, // 为了保证图像亮度不变,同一个通道中的R+G+B=1 0.3086f, 0.6094f, 0.0820f, 0, 0, 0.3086f, 0.6094f, 0.0820f, 0, 0, 0.3086f, 0.6094f, 0.0820f, 0, 0, 0, 0, 0, 1, 0 }; ColorMatrix colorMatrix4 = new ColorMatrix(matrix4); mRedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix4)); canvas.drawBitmap(mainBitmap, 0, 0, mRedPaint);
字体.setTypeface(Typeface.SANS_SERIF); 对齐方式.setTextAlign(Paint.Align.LEFT); 字体大小.setTextSize(100);
对齐:
Paint.Align.
[#LEFT
|RIGHT
|CENTER
] 内置字体:Typeface.
[#DEFAULT
|DEFAULT_BOLD
|SANS_SERIF
|SERIF
|MONOSPACE
]
canvas.save(); canvas.translate(550, 1600); mTextPaint.setTypeface(Typeface.SANS_SERIF); mTextPaint.setTextAlign(Paint.Align.LEFT); mTextPaint.setTextSize(100); canvas.drawText("SANS_SERIF", 0, 0, mTextPaint); Paint tempPaint = new Paint(Paint.ANTI_ALIAS_FLAG); tempPaint.setStrokeWidth(4); tempPaint.setColor(Color.RED); tempPaint.setStyle(Paint.Style.STROKE); canvas.drawRect(0, - 100, mWinSize.x, 0, tempPaint); canvas.translate(0, 150); mTextPaint.setTextAlign(Paint.Align.RIGHT); mTextPaint.setTypeface(Typeface.SERIF); canvas.drawText("SERIF", 0, 0, mTextPaint); canvas.drawRect(0, - 100, mWinSize.x, 0, tempPaint); canvas.translate(0, 150); mTextPaint.setTypeface(Typeface.MONOSPACE); mTextPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText("MONOSPACE", 0, 0, mTextPaint); canvas.drawRect(0, - 100, mWinSize.x, 0, tempPaint); canvas.restore();
文字相关.png
/** * 创建字体 * @param canvas */ private void createTypeface(Canvas canvas) { mTextPaint.setTextSize(50); canvas.save(); canvas.translate(50, 1600); mTextPaint.setTypeface(Typeface.MONOSPACE); canvas.drawText("MONOSPACE", 0, 0, mTextPaint); //粗体 canvas.translate(0, 100); Typeface typeface = Typeface.create(Typeface.MONOSPACE, Typeface.BOLD); mTextPaint.setTypeface(typeface); canvas.drawText("MONOSPACE+BOLD", 0, 0, mTextPaint); //斜体 canvas.translate(0, 100); Typeface typeface2 = Typeface.create(Typeface.MONOSPACE, Typeface.ITALIC); mTextPaint.setTypeface(typeface2); canvas.drawText("MONOSPACE+ITALIC", 0, 0, mTextPaint); //粗斜体 canvas.translate(0, 100); Typeface typeface3 = Typeface.create(Typeface.MONOSPACE, Typeface.BOLD_ITALIC); mTextPaint.setTypeface(typeface3); canvas.drawText("MONOSPACE+BOLD_ITALIC", 0, 0, mTextPaint); //使用外部字体 canvas.translate(0, 100); Typeface myFont = Typeface.createFromAsset(getContext().getAssets(), "ACHAFSEX.TTF"); mTextPaint.setTypeface(myFont); canvas.drawText("Hello I am Toly", 0, 0, mTextPaint); canvas.restore(); }
创建字体.png
public static class FontMetrics { public float top;//最顶 public float ascent;// public float leading; public float descent; public float bottom;//最底 }
字体5线.png
/** * 获取字体尺寸信息 * @param canvas */ private void fontMetricsTest(Canvas canvas) { canvas.save(); canvas.translate(100, 500); mTextPaint.setTextSize(200); mTextPaint.setTypeface(Typeface.SERIF); canvas.drawText("I am Toly", 0, 0, mTextPaint); //获取字体尺寸 Paint.FontMetrics fm = mTextPaint.getFontMetrics(); Log.e(TAG, "top: " + fm.top); Log.e(TAG, "ascent: " + fm.ascent); Log.e(TAG, "leading: " + fm.leading); Log.e(TAG, "descent: " + fm.descent); Log.e(TAG, "bottom: " + fm.bottom); Paint tempPaint = new Paint(Paint.ANTI_ALIAS_FLAG); tempPaint.setStrokeWidth(1); tempPaint.setColor(Color.RED); tempPaint.setStyle(Paint.Style.STROKE); canvas.drawLine(0, fm.top, mWinSize.x, fm.top, tempPaint); tempPaint.setColor(Color.MAGENTA); canvas.drawLine(0, fm.ascent, mWinSize.x, fm.ascent, tempPaint); tempPaint.setColor(Color.parseColor("#4C17F9")); canvas.drawLine(0, fm.leading, mWinSize.x, fm.leading, tempPaint); tempPaint.setColor(Color.GREEN); canvas.drawLine(0, fm.descent, mWinSize.x, fm.descent, tempPaint); tempPaint.setColor(Color.parseColor("#E74EDD")); canvas.drawLine(0, fm.bottom, mWinSize.x, fm.bottom, tempPaint); canvas.restore(); }
2018-11-05 21:17:35.264 28726-28726/? E/PaintView: top: -209.57031 2018-11-05 21:17:35.264 28726-28726/? E/PaintView: ascent: -185.54688 2018-11-05 21:17:35.264 28726-28726/? E/PaintView: leading: 0.0 2018-11-05 21:17:35.264 28726-28726/? E/PaintView: descent: 48.828125 2018-11-05 21:17:35.264 28726-28726/? E/PaintView: bottom: 50.0
String text = "I am Toly"; Rect textRect = new Rect(); mTextPaint.getTextBounds(text, 0, text.length(), textRect); Log.e(TAG, textRect.toShortString());// [7,-152][886,49] //绘制矩形 tempPaint.setColor(Color.parseColor("#66F4F628")); tempPaint.setStyle(Paint.Style.FILL); canvas.drawRect(textRect, tempPaint);
文字最小矩形区.png
mTextPaint.setTextScaleX(.5f);//水平伸缩 mTextPaint.setStrikeThruText(true);//删除线 mTextPaint.setUnderlineText(true);//下划线 mTextPaint.setTextSkewX(-.5f);//倾斜
其他效果.png
就先这样吧,还有很多不常用的,以后有需求遇到了,在加吧
项目源码 | 日期 | 备注 |
---|---|---|
V0.1--无 | 2018-11-7 | Android关于Paint你所知道的和不知道的一切 |
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句