Paint 基本使用

《Paint的方法主要可以抽象成两大类》:

      1.1 负责设置获取图形绘制、路径相关的1.setStyle(Paint.Style style) 设置画笔样式,取值有Paint.Style.FILL :填充内部Paint.Style.FILL_AND_STROKE :填充内部和描边Paint.Style.STROKE :仅描边、注意STROKE、FILL_OR_STROKE与FILL模式下外轮廓的位置会扩大。2.setStrokeWidth(float width) 设置画笔宽度 3.setAntiAlias(boolean aa) 设置画笔是否抗锯齿 4.setStrokeCap(Paint.Cap cap) ------demo演示 设置线冒样式,取值有Cap.ROUND(圆形线冒)、Cap.SQUARE(方形线冒)、Paint.Cap.BUTT(无线冒) 注意:冒多出来的那块区域就是线帽!就相当于给原来的直线加上一个帽子一样,所以叫线帽 5.setStrokeJoin(Paint.Join join) ------ demo演示设置线段连接处样式,取值有:Join.MITER(结合处为锐角)、Join.Round(结合处为圆弧)、Join.BEVEL(结合处为直线) 6.setStrokeMiter(float miter) 设置笔画的倾斜度,90度拿画笔与30拿画笔,画出来的线条样式肯定是不一样的吧。(事实证明,根本看不出来什么区别好吗……囧……)void reset() 清空画笔复位。void set(Paint src) 设置一个外来Paint画笔。7.void setARGB(int a, int r, int g, int b) int getAlpha() void setAlpha(int a) int getColor() void setColor(int color) 获取与设置alpha值、颜色、ARGB等。final boolean isAntiAlias() 8.void setAntiAlias(boolean aa) 获取与设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢,一般会开启。设置后会平滑一些;final boolean isDither() 9.void setDither(boolean dither) 获取与设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满、图像更加清晰。10.setPathEffect(PathEffect effect);   * 设置绘制路径的效果,如点画线等 (1)、CornerPathEffect——圆形拐角效果 paint.setPathEffect(new CornerPathEffect(100));利用半径R=50的圆来代替原来两条直线间的夹角(2)、DashPathEffect——虚线效果 //画同一条线段,偏移值为15  paint.setPathEffect(new DashPathEffect(new float[]{20,10,50,100},15));intervals[]:表示组成虚线的各个线段的长度;整条虚线就是由intervals[]中这些基本线段循环组成的。比如,我们定义new float[] {20,10};那这个虚线段就是由两段线段组成的,第一个可见的线段长为20,每二个线段不可见,长度为10;phase:开始绘制的偏移值 .....11.setXfermode(Xfermode xfermode);   设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果12.setMaskFilter(MaskFilter maskfilter);   设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等 13.setColorFilter(ColorFilter colorfilter);   设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果14.setShader(Shader shader);   设置图像效果,使用Shader可以绘制出各种渐变效果   15.setShadowLayer(float radius ,float dx,float dy,int color);   在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色  1.2 负责设置获取文字相关的float getFontSpacing() 获取字符行间距。float getLetterSpacing() void setLetterSpacing(float letterSpacing) 设置和获取字符间距final boolean isUnderlineText() void setUnderlineText(boolean underlineText) 是否有下划线和设置下划线。final boolean isStrikeThruText() void setStrikeThruText(boolean strikeThruText) 获取与设置是否有文本删除线。float getTextSize() void setTextSize(float textSize) 获取与设置文字大小,注意:Paint.setTextSize传入的单位是px,TextView.setTextSize传入的单位是sp,注意使用时不同分辨率处理问题。Typeface getTypeface() Typeface setTypeface(Typeface typeface) 获取与设置字体类型。Android默认有四种字体样式:BOLD(加粗)、BOLD_ITALIC(加粗并倾斜)、ITALIC(倾斜)、NORMAL(正常),我们也可以通过Typeface类来自定义个性化字体。float getTextSkewX() void setTextSkewX(float skewX) 获取与设置文字倾斜,参数没有具体范围,官方推荐值为-0.25,值为负则右倾,为正则左倾,默认值为0。Paint.Align getTextAlign() void setTextAlign(Paint.Align align) 获取与设置文本对齐方式,取值为CENTER、LEFT、RIGHT,也就是文字绘制是左边对齐、右边还是局中的。setSubpixelText(boolean subpixelText)固定的几个范围:320*480,480*800,720*1280,1080*1920等等;那么如何在同样的分辨率的显示器中增强显示清晰度呢?亚像素的概念就油然而生了,亚像素就是把两个相邻的两个像素之间的距离再细分,再插入一些像素,这些通过程序加入的像素就是亚像素。在两个像素间插入的像素个数是通过程序计算出来的,一般是插入两个、三个或四个。所以打开亚像素显示,是可以在增强文本显示清晰度的,但由于插入亚像素是通过程序计算而来的,所以会耗费一定的计算机性能。int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth) 比如文本阅读器的翻页效果,我们需要在翻页的时候动态折断或生成一行字符串,这就派上用场了~计算指定参数长度能显示多少个字符,同时可以获取指定参数下可显示字符的真实长度,譬如:private static final String STR = "动脑ABCDEF";mPaint.setTextSize(50);float[] value = new float[1];int ret = mPaint.breakText(STR, true, 200, value);Log.i("YYYY", "breakText="+ret+", STR="+STR.length()+", value="+value[1]);//breakText=5, STR=8, value=195.0void getTextBounds(char[] text, int index, int count, Rect bounds) void getTextBounds(String text, int start, int end, Rect bounds) 获取文本的宽高,通过bounds的Rect拿到整型。float measureText(String text) float measureText(CharSequence text, int start, int end) float measureText(String text, int start, int end) float measureText(char[] text, int index, int count) 粗略获取文本的宽度,和上面的getTextBounds比较类似,返回浮点数。int getTextWidths(String text, int start, int end, float[] widths) int getTextWidths(String text, float[] widths) int getTextWidths(CharSequence text, int start, int end, float[] widths) int getTextWidths(char[] text, int index, int count, float[] widths) 精确计算文字宽度,与上面两个类似。

Paint画文字文字的位置

Paint画笔来画文字
Paint.FontMetrics  float类型Paint.FontMetricsInt  int类型
里面有top,ascent,desent, bottom, leading这几个属性top = top线的y坐标 - baseline线的y坐标
bottom = bottom线的y坐标 - baseline线的y坐标
ascent = ascent线的y坐标 - baseline线的y坐标
desent = desent线的y坐标 - baseline线的y坐标1、A = B = (bottom - top)/2
bottom = baseline + FontMetrics.bottom
top = baseline + FontMetrics.top---> A = B = (FontMetrics.bottom - FontMetrics.top)/ 22、C =  B - (bottom - baseline)=  B - FontMetrics.bottom3、C = baseline - center综上可得
baseline - center = (FontMetrics.bottom - FontMetrics.top)/2 - FontMetrics.bottombaseline = center +(FontMetrics.bottom - FontMetrics.top)/2 - FontMetrics.bottom

Paint 高级渲染

Shader —着色器,Canvas的drawXXXX这个方法是画具体的形状,画笔的shader定义的就是图形的着色和外观

BitmapShader --位图图像渲染,用BitMap对绘制的图形进行渲染着色,简单来说是用图片对图形进行贴图
圆形头像,放大镜效果

TileMode 拉伸形式CLAMP --是拉伸最后一个像素铺满MIRROR ---是横向纵向不足处不断翻转镜像平铺REPEAT ---类似电脑壁纸,横向纵向不足的重复放置

LinearGradient --线性渲染
霓虹灯文字,倒影图片

SweepGradient ----渐变渲染/梯度渲染

 雷达扫描效果

RadialGradient ----环形渲染
水波纹效果

ComposeShader ----组合渲染

 可以自己发挥想象去组合一下

下面开始例子:

BitmapShader 例子 画一个圆形 原型头像

  @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);/*** TileMode.CLAMP 拉伸最后一个像素去铺满剩下的地方* TileMode.MIRROR 通过镜像翻转铺满剩下的地方。* TileMode.REPEAT 重复图片平铺整个画面(电脑设置壁纸)*//*** Call this to create a new shader that will draw with a bitmap.*          调用这个来创建一个新的着色器,它将用位图来绘制。* @param bitmap            The bitmap to use inside the shader 在着色器中使用的位图* @param tileX             The tiling mode for x to draw the bitmap in.用于绘制位图的x的平铺模式* @param tileY             The tiling mode for y to draw the bitmap in.用于绘制位图的Y的平铺模式*///BitmapShader使用  图片着色器BitmapShader bitmapShader = new BitmapShader(mBitMap, Shader.TileMode.MIRROR,Shader.TileMode.MIRROR);mPaint.setShader(bitmapShader);mPaint.setAntiAlias(true);//抗锯齿//圆形头像//参数 圆点的x,y, 半径, 画笔//画出原型头像canvas.drawCircle(mHeight / 2,mHeight / 2, mHeight / 2 ,mPaint);//椭圆//canvas.drawOval(new RectF(0 , 0, mWidth, mHeight),mPaint);//设置像素矩阵,来调整大小,为了解决宽高不一致的问题。float scale = Math.max(mWidth,mHeight) / Math.min(mWidth,mHeight);//矩阵使用 完成缩放Matrix matrix = new Matrix();matrix.setScale(scale,scale);bitmapShader.setLocalMatrix(matrix);//画出矩形canvas.drawRect(new Rect(0,500 , 1000, 1600),mPaint);
}

以上代码效果


LinearGradient --线性渲染
可以做 霓虹灯文字,倒影图片

      private int[] mColors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW};protected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);/**线性渐变* x0, y0, 起始点*  x1, y1, 结束点* int[]  mColors, 中间依次要出现的几个颜色* float[] positions,数组大小跟colors数组一样大,中间依次摆放的几个颜色分别放置在那个位置上(参考比例从左往右)*    tile*/LinearGradient linearGradient = new LinearGradient( 0, 0,800, 800, mColors, null, Shader.TileMode.CLAMP);// linearGradient = new LinearGradient(0, 0, 400, 400, mColors, null, Shader.TileMode.REPEAT);mPaint.setShader(linearGradient);canvas.drawRect(0, 0, 800, 800, mPaint);}

以上效果


-RadialGradient 环形渐变,渲染
(水波纹效果)

RadialGradient mRadialGradient = new RadialGradient(300, 300, 100, mColors, null, Shader.TileMode.REPEAT);mPaint.setShader(mRadialGradient);canvas.drawCircle(300, 300, 300, mPaint);

-SweepGradient 梯度渐变 ,梯度渲染
(可做雷达扫描效果)

private int[] mColors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW};SweepGradient mSweepGradient = new SweepGradient(300, 300, mColors, null);mPaint.setShader(mSweepGradient);canvas.drawCircle(300, 300, 300, mPaint);

-组合渐变


放大镜效果

分析下如何做放大镜效果:

首先底部需要画原图,因为是放大镜所以需要获取放大后的图片,我这里是把整张图片放大,然后使用ShapeDrawable来画放大镜,通过矩阵变换和触摸事件来移动放大镜.

效果图:


代码:


public class ZoomImageView1 extends View {//放大倍数private static final int FACTOR = 2;//放大镜的半径private static final int RADIUS = 100;// 原图private Bitmap mBitmap;// 放大后的图private Bitmap mBitmapScale;// 制作的圆形的图片(放大的局部),盖在Canvas上面private ShapeDrawable mShapeDrawable;private Matrix mMatrix;public ZoomImageView1(Context context) {super(context);//原图mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.xyjy3);//赋值mBitmapScale = mBitmap;//创建放大后的图 参数 是X Y 轴放大的倍数mBitmapScale = Bitmap.createScaledBitmap(mBitmap, mBitmapScale.getWidth() * FACTOR,mBitmapScale.getHeight() * FACTOR, true);//使用BitmapShaderBitmapShader bitmapShader = new BitmapShader(mBitmapScale, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
//        Android中,利用ShapeDrawable来绘制图像,ShapeDrawable可以设置画笔的形状。通过geiPaint方可以得到Paint对象。mShapeDrawable = new ShapeDrawable(new OvalShape());//我这里做了个椭圆mShapeDrawable.getPaint().setShader(bitmapShader);//设置bitmapshader//setBounds 为可绘制的矩形指定一个边界矩形。这就是可拉的地方 当调用它的draw()方法时将会绘制。mShapeDrawable.setBounds(0, 0, RADIUS * 2, RADIUS * 2);mMatrix = new Matrix();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 1、画原图canvas.drawBitmap(mBitmap, 0, 0, null);// 2、画放大镜的图mShapeDrawable.draw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();//实际上是平移放大后的图片// setTranslate方法 : 将矩阵转换为(dx,dy), 这里的作用将放大的图片往相反的方向挪动mMatrix.setTranslate(RADIUS - x * FACTOR, RADIUS - y * FACTOR);//设置着色器的本地矩阵。传递null将重置着色器//矩阵的身份。//参数着色器的新本地矩阵,或空来指定标识mShapeDrawable.getPaint().getShader().setLocalMatrix(mMatrix);// 切出手势区域点位置的圆mShapeDrawable.setBounds(x - RADIUS, y - RADIUS, x + RADIUS, y + RADIUS);invalidate();return true;}
}

LinearGradient 线性渲染-> 霓虹灯文字效果

原理: 在文字上面有一层线性渲染.

package com.dongnao.lsn4_paint_gradient;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;/*** @author liuml* @explain* @time 2018/1/9 15:18*/@SuppressLint("AppCompatCustomView")
public class LinearGradientTextView1 extends TextView {private TextPaint mPaint;private LinearGradient mLinearGradient;private Matrix mMatrix;private float mTranslate;private float DELTAX = 20;public LinearGradientTextView1(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public LinearGradientTextView1(Context context) {super(context);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//在onSizeChanged 中//拿到TextView的画笔mPaint = getPaint();//获取文本String text = getText().toString();float textwith = mPaint.measureText(text);//一次高亮三个文字 获取三个文字的宽度int gradientSize = (int) (textwith / text.length() * 3);/*** 创建一个在直线上绘制线性渐变的着色器。@param x0是梯度线起始点的x坐标@param y0是梯度线起始点的y坐标@param x1是梯度线末端的x坐标@param y1是梯度线末端的y坐标@param 颜色颜色分布沿渐变线@param 位置可能是零,相对位置(0 . .颜色数组中的每一个对应的颜色,如果这是null,那么颜色就会沿着梯度线均匀分布@param 平铺的着色模式*///改变的是透明度  最中间的是白色 然后改变两边的透明度.//颜色数组  gradientSize 放在x0处 是让起始点放在外面mLinearGradient = new LinearGradient(-gradientSize, 0, 0, 0,new int[]{0x22ffffff, 0xffffffff, 0x22ffffff},null, Shader.TileMode.CLAMP);//设置到画笔中mPaint.setShader(mLinearGradient);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//在onDraw里面 不断改变mTranslate += DELTAX;float textWidth = getPaint().measureText(getText().toString());//如果到头了需要改变 超过文本长度或者回到起始点.需要返回来if(mTranslate>textWidth+1|| mTranslate < 1){//需要往相反的方向运动  给个负值就行DELTAX = -DELTAX;}mMatrix = new Matrix();
//        将矩阵转换为(dx,dy)mMatrix.setTranslate(mTranslate,0);//设置着色器的本地矩阵。传递null将重置着色器 矩阵的身份。mLinearGradient.setLocalMatrix(mMatrix);//延时postInvalidateDelayed(50);}
}

XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000"tools:context="com.dongnao.lsn4_paint_gradient.MainActivity"><!-- <com.dongnao.lsn4_paint_gradient.MyGradientViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />--><com.dongnao.lsn4_paint_gradient.LinearGradientTextView1android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="30sp"android:textColor="#666666"android:text="六道对穿肠自定义霓虹灯文字效果"/></android.support.constraint.ConstraintLayout>

下面是效果图

高级UI - Paint基本使用.高级渲染使用(最后实现放大镜效果)相关推荐

  1. html触摸电脑ui系统,如何用高级UI制作触摸系统界面

    一.什么是触摸系统 触摸系统实际上是一个令玩家与作品中的角色产生互动的环节.顾名思义,通过模拟触摸这个行为,来令作品中的角色产生不同的反应.说出不同的台词.设计巧妙的触摸系统,一方面可以增添作品的可玩 ...

  2. Android 高级UI解密 (二) :Paint滤镜 与 颜色过滤(矩阵变换)

    若是曾经查看过系统UI的源码, 会发现其中使用了一些渲染效果,例如将图片加上黑白.怀旧的效果,生活中常用的逆天美颜相机,其中的原理就是使用了滤镜效果.颜色通道过滤.若还要深究其原理组成,便涉及到了高等 ...

  3. android高级UI之Paint Xfermode

    在上一次https://www.cnblogs.com/webor2006/p/12660322.html学习了Paint的第二高级用法之滤镜效果,接下来这次将它的最后一个高级用法给搞定----Xfe ...

  4. Android 高级UI解密 (三) :Canvas裁剪 与 二维、三维Camera几何变换(图层Layer原理)

    Android的绘图机制是核心内容之一,无论是什么样的功能最终都是以图像的形式呈现给用户.因此掌握Android的绘图技巧,有助于Android理解层次的提高,在面对产品经理提出的idea时也更有底气 ...

  5. Android 高级UI解密 (四) :花式玩转贝塞尔曲线(波浪、轨迹变换动画)

    讲解此UI系列必然少不了一个奇妙数学曲线-–贝塞尔曲线,它目前运用于App的范围是在太广了,最初的QQ气泡拖拽,到个人界面的波浪效果.Loading波浪效果,甚至于轨迹变化的动画都可以依赖贝塞尔曲线完 ...

  6. android炫酷动画代码,Android高级UI特效仿直播点赞动画效果

    Android高级UI特效仿直播点赞动画效果 发布时间:2020-10-02 16:06:18 来源:脚本之家 阅读:117 作者:mrr 本文给大家分享高级UI特效仿直播点赞效果-一个优美炫酷的点赞 ...

  7. android scroller,高级UI第四十四篇:Android Scroller详解

    滚动视图的方法有两种:scrollTo和scrollBy,而Scroller就是它们的辅助工具类,所以Scroller是学好高级UI必不可少的一课. (1)scrollTo.scrollBy.getS ...

  8. 你连《Android高级UI与FrameWork源码》都搞不懂学什么Android?还敢面试阿里P7!

    Android高级UI与FrameWork源码 重要性? 这块知识是现今使用者最多的,我们称之为Android2013~2016年的技术,但是,即使是这样的技术,Android开发者也往往因为网上Co ...

  9. BlackBerry高级UI设计

    作者: 王志刚 概论 这篇文档 讲述的 是如何 在 Bla ckB erry 设备上应用 的 UI 效果, 文档的 介绍 的内容包 括如下 部分 : 1 .     基于 M I D P 的 UI 2 ...

最新文章

  1. LaxTex-----参考文献中同名作者被默认缺省的问题
  2. python将注释写入xml_python 注释xml的元素
  3. 每日一皮:曾经的你是不是也这般天真?
  4. 【Applet编写应用小程序】Applet类APIの基本知识和第一个程序
  5. 找到真爱了-sublime
  6. Linux CentOS6.7设置为固定静态IP的方法
  7. AtCoder Regular Contest 058
  8. oracle秘钥到期,Oracle – 更新加入 – 非密钥保留表
  9. 作者:张峰(1978-),男,博士,国家海洋信息中心副研究员
  10. Elasticsearch实战:给博客打造全文检索
  11. paintevent参数_Qt学习: QPaintEvent和QMouseEvent的简单程序示例
  12. 回归预测的评价指标(附python代码)
  13. linux 对整个文件 url解码,linux shell实现 URL 编码/解码方法
  14. silvaco AMS安装方法
  15. 阿里云服务器 免费获取SSL证书 配置HTTPS安全访问
  16. Java 数据填充到word模板中
  17. #windowsxpsp3系统MS12-020漏洞测试
  18. 蜂鸟数据Trochil:论述制定策略的两种主要方法:市场假设和瑞士法郎案例研究-构建更好的策略1
  19. yigo2.0定时器集合
  20. 利用空闲服务器搭建frps服务端-实现穿透代理

热门文章

  1. 计算直柱体的面积和体积
  2. mapr 和cdh对比_教程:使用PySpark和MapR沙盒
  3. 广州地区《程序员》杂志购买渠道告知
  4. 准考证打印系统关闭怎么办_准考证打印系统关闭怎么办_公务员考录专题网站...
  5. 五大常用算法—动态规划详解和经典题目(python)
  6. 手拉手教你实现一门编程语言 Enkel, 系列 14
  7. 解决nrf52832 radio配置反复切换,radio不能读标签的问题
  8. Nodejs内存治理
  9. 20V,24V转5V,20V,24V转3.3V降压芯片,IC介绍
  10. vue3 diff算法优化