Path是什么?

The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint's Style), or it can be used for clipping or to draw text on a path.

Path类封装了由直线段,二次贝塞尔曲线和三次贝塞尔曲线组成的复合几何路径。它可以使用canvas.drawPath(path,paint)绘制,填充或描边,或者它可以用于剪切或在路径上绘制文本。

我们此处说的Path就是单纯的路径,不是文件的路径,是在android.graphics包下的.它在自定义View的时候能帮我们记录路径,然后调用Canvas.drawPath就可以画出.这个图形可以是简单的几何图形,也可以使圆弧等,可以使用到贝塞尔曲线(额,本人大专生,先开始看到这个名词也是一脸懵逼,那么api中只给出了二阶和三阶的贝塞尔曲线,如有需要,自行百度了解).

Path的构造函数?

第一个创建一个空的Path

第二个创建一个拥有路径的Path

Path中的三个枚举值?

Path.Direction     方向,CW为顺时针,CCW为逆时针

Path.FillType       一共有4种填充类型,看下去你就知道了

Path.Op                用来做布尔运算,可以简单的理解为交集,并集等的运算

不要着急,在接下来的操作中我们会一一介绍

Path的方法?

下面一一介绍咯,看好,走你~

在说怎么用之前,先说一下,关于Rect,Canvas以及Paint,Point的用法,请看我的另外文章

自定义View之Rect的使用与理解

自定义View之Canvas的使用

自定义View之Point的使用

paint的文章暂时没有写,上面两篇文章也不完整,但快了,后续会把这里更新了.

下面直接给出自定义View的代码以及xml文件,防止你说我不给源码

public class MyPathView extends View {private static final String TAG = "MyPathView";private Paint mPaint;private Paint mMyPathViewPaint;public MyPathView(Context context) {this(context,null);}public MyPathView(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public MyPathView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);/*初始化画笔,相关知识请查看我写的其他博客进行学习,这里主要讲的是Path的用法与理解*/mPaint = new Paint();mPaint.setAntiAlias(true);                  //抗锯齿mPaint.setStyle(Paint.Style.STROKE);        //设置画笔风格为描边mPaint.setColor(Color.RED);                 //画笔颜色mPaint.setStrokeWidth(2);                   //描边的宽度mPaint.setTextSize(30);                     //字体大小/*这里是我们用到的画笔*/mMyPathViewPaint = new Paint();mMyPathViewPaint.setAntiAlias(true);mMyPathViewPaint.setStyle(Paint.Style.STROKE);mMyPathViewPaint.setColor(Color.BLACK);mMyPathViewPaint.setStrokeWidth(2);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);
//       这里是我用来画坐标轴的,注意android的坐标轴y轴向下才是正的canvas.drawLine(getWidth()/2,0,getWidth()/2,getHeight(),mPaint);canvas.drawLine(getWidth()/2,getHeight(),getWidth()/2-20,getHeight()-20,mPaint);canvas.drawLine(getWidth()/2,getHeight(),getWidth()/2+20,getHeight()-20,mPaint);canvas.drawLine(0,getHeight()/2,getWidth(),getHeight()/2,mPaint);canvas.drawLine(getWidth(),getHeight()/2,getWidth()-20,getHeight()/2-20,mPaint);canvas.drawLine(getWidth(),getHeight()/2,getWidth()-20,getHeight()/2+20,mPaint);canvas.drawText("Y",getWidth()/2+10,getHeight()-30,mPaint);canvas.drawText("X",getWidth()-50,getHeight()/2-10,mPaint);//       之后的代码都是写在这里的,这个是模板}
}
<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"tools:context=".MainActivity"><xhj.zime.com.pathdemo.MyPathViewandroid:layout_width="match_parent"android:layout_height="match_parent" /></android.support.constraint.ConstraintLayout>

Path怎么用?

个人把里面的方法分为这几大类

1.Line系列

2.addXXX系列

3.is系列

4.没有系列的系列

接下来我们一起来细看Path的一些用法:

Line系列:

line系列我总结的主要方法有这几个,综合起来看效果比较好:

第一组:

public void moveTo(float x, float y)
public void lineTo(float x, float y)
public void setLastPoint(float dx, float dy)
public void close()

不使用setLastPoint:

        canvas.translate(getWidth()/2,getHeight()/2);    //把画布移到中间Path path = new Path();                          path.moveTo(200,0);                              //移动原点(最初的点)path.lineTo(200,200);                            //连线path.lineTo(100,100);canvas.drawPath(path,mMyPathViewPaint);          //画出路径

效果图:

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.moveTo(200,0);path.lineTo(200,200);path.lineTo(100,100);path.close();                                       //这里多了一个close方法canvas.drawPath(path,mMyPathViewPaint);

效果图

这里A点应该是(200,0),笔误,请理解

这里两处只是多了一个close方法,这个方法表示取最后一个点(这里为C)和第一个点(这里为A)连接,如果能组成封闭图形,则画出封闭图形,如果不能组成,那么这个方法什么也不做

(注意:最后一个点和第一个点是不一定能组成封闭图形的)

使用setLastPoint:

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.moveTo(200,0);path.lineTo(200,200);path.setLastPoint(100,50);                         //设置当前最后一个点的坐标path.lineTo(100,100);canvas.drawPath(path,mMyPathViewPaint);

效果图

可以很明显的看到,下过大大不同,setLastPoint方法的作用就是把当前的最后一个点的坐标设置为你所设置的坐标值,这里相当于把B(200,200)的坐标设置为了D(100,50),坐标A(200,0)就直接与D(100,50)相连,而不是(200,200).

第二组:

下面再看这一组出现的加 r 的方法

public void rMoveTo(float dx, float dy)
public void rLineTo(float dx, float dy)

这一组方法很简单, r 代表相对(Relative)的意思,不加 r 的moveTo代表移动到一个绝对的坐标,而加 r 的表示相对于原来的坐标x和y坐标分别移动多少自行解决,不进行演示~相信你可以搞定的,爱你哦~

注意:Path里面出现的所有方法前带 r 的都代表相对的意思,下面将不再指出

addXXX系列:

第一组:

首先我们来看基本图形

public void addRect(RectF rect, Direction dir)
public void addRect(float left, float top, float right, float bottom, Direction dir)
public void addOval(RectF oval, Direction dir)
public void addOval(float left, float top, float right, float bottom, Direction dir)
public void addCircle(float x, float y, float radius, Direction dir)
public void addRoundRect(RectF rect, float rx, float ry, Direction dir)
public void addRoundRect(float left, float top, float right, float bottom, float rx, float                         ry,Direction dir) 

addRect

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addRect(rectF, Path.Direction.CW);             //添加矩形路径,顺时针画canvas.drawPath(path,mMyPathViewPaint);

效果图

addCircle

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.addCircle(0,0,200, Path.Direction.CW);       //顺时针方向画圆canvas.drawPath(path,mMyPathViewPaint);

效果图

等等.什么是Path.Direction.CW,你上一个也用到了这个,怎么没解释?这是什么鬼?哦呵呵,源码点进去一看,原来就只是和字面意思一样,方向.我只是故意不讲看你有没有发现这个问题咯,能自己解决那当然是好事情啦~

CW:顺时针

CCW:逆时针

为毛需要方向?我直接使用一种方向不就完了吗?没有你想的那么简单,上文api说了,Path用来记录直线和曲线,一个矩形用两个点的坐标来表示,实际上Path是用四条线段来记录的,否则你需要有一个标记来表示它是一个矩形,又需要内存空间,不划算啊,兄dei~java本来就是一种省资源的一种设计啊.接下来,我们借助setLastPoint让这种方向的事情原形毕露!(吃俺老孙一棒~~~)

首先,我们用Path画一个矩形

就用上面的那个好了,直接看效果图,给他加上坐标

然并卵~然后这里并看不出效果,来咯,看着

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addRect(rectF, Path.Direction.CW);path.setLastPoint(150,50);                        //让它原形毕露的关键canvas.drawPath(path,mMyPathViewPaint);

效果图

啊哈,被我发现了吧,小样~你也不过如此嘛~原来,我们在绘制矩形的时候,也是调用moveTo和lineTo来实现画一个矩形的其实也就是一条线一条线画出来的.如果一定要深究是为什么,注意看最终会追述到一些带有native的方法,代表是由其他语言实现的,java只是负责调用,你想看源码的话自行解决吧~我并没有深究他的原因~因为如果要追究是在是太多了.了解原理就好~那么现在给一个猜想,如果换成是逆时针的,同样调用setLastPoint方法是不是就会是逆时针的最后一个点改变了呢?

给出代码:

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addRect(rectF, Path.Direction.CCW);path.setLastPoint(150,50);canvas.drawPath(path,mMyPathViewPaint);

效果图

果然,和我们预想的结果一样,完美,似不似自豪感爆棚?啊哈.我们接着来看

drawOval

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);             //圆弧也是通过矩形来画的path.addOval(rectF, Path.Direction.CW);canvas.drawPath(path,mMyPathViewPaint);

效果图

drawRoundRect

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addRoundRect(rectF,20,30, Path.Direction.CW);      //圆角矩形canvas.drawPath(path,mMyPathViewPaint);

效果图

下面来解释一下它的第二个和第三个参数的意思,round意思代表圆角,也就是圆角的矩形

rx : 表示x轴上的半径

ry : 表示y轴上的半径

总的来说就是圆弧的两个半径,控制圆弧的大小

下面来解释一下我没用到的几个重载方法的用法以及含义,解释一个你就马上懂了,哦~soga,原来就是这样的

来看两段代码

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addRoundRect(rectF,20,30, Path.Direction.CW);canvas.drawPath(path,mMyPathViewPaint);
        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.addRoundRect(0,0,200,200,20,30, Path.Direction.CW);canvas.drawPath(path,mMyPathViewPaint);

上面两段代码的含义和作用是一样的,无非就是第一个你已经创建好了一个RectF矩形,它需要四个参数,它对应的就是下面的前四个参数,这你还不懂?呵呵,不可能~其他的重载方法的区别也是如此,有参数少的为什么要用参数多的呢,待会儿把自己都要搞晕了,这就龙体欠佳了,不划算是吧~

第二组:

addArc和arcTo

public void addArc(RectF oval, float startAngle, float sweepAngle)
public void addArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle)
public void arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)
public void arcTo(RectF oval, float startAngle, float sweepAngle)
public void arcTo(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean forceMoveTo)

addArc

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.addArc(rectF,0,270);                        //添加圆弧,也是根据矩形画的canvas.drawPath(path,mMyPathViewPaint);

效果图

参数理解

1.矩形

2.开始画弧度线的角度

3.扫过的角度

也是非常简单滴,现在的你是不是掌握了差不多了,以上说的这些其实都是差不多的

再来看一个addArc

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.lineTo(100,100);                            //加线path.addArc(rectF,0,270);                        //加圆弧canvas.drawPath(path,mMyPathViewPaint);

效果图

这里无非就是多加了一条直线而已,那么我想表达什么呢.既然arcTo方法存在,那么他和addArc有什么区别呢,接下来我们看~

arcTo

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.lineTo(100,100);path.arcTo(rectF,0,270,true);canvas.drawPath(path,mMyPathViewPaint);

效果和上图一样

这里的arcTo方法有几个参数

1.矩形

2.弧度开始的角度

3.弧线扫过的角度

4. forceMoveTo : 这是什么意思呢?就是强制moveTo,我们画完弧线后,最后一个点默认会和之前的那个点相连,这里设置为true之后就不会强制相连,addArc只是追加上去,并不会默认相连,这就是两个方法的区别,看以下效果更佳明显

把forceMoveTo改为false

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();RectF rectF = new RectF(0,0,200,200);path.lineTo(100,100);path.arcTo(rectF,0,270,false);canvas.drawPath(path,mMyPathViewPaint);

效果图

不用我多说了吧,效果很明显,再多逼逼毫无意义,这里说明一下,forceMoveTo可以不写,不写默认为false,还有一个就是参数之中如果没有Direction(顺时针还是逆时针),那么默认就是逆时针的,你可看到了,他们两个点相连了.

第三组

addPath系列

public void addPath(Path src)
public void addPath(Path src, float dx, float dy)
public void addPath(Path src, Matrix matrix)

首先我们来看第一个,就是把一个路径加进来

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.addCircle(0,0,100, Path.Direction.CW);Path newPath = new Path();newPath.addCircle(-100,0,100, Path.Direction.CW);newPath.addPath(path);canvas.drawPath(newPath,mMyPathViewPaint);

效果图

没啥好说的,就是path里面再加上一个path,就是这么简单~

第二个addPath

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.addCircle(0,0,100, Path.Direction.CW);Path newPath = new Path();newPath.addCircle(-100,0,100, Path.Direction.CW);newPath.addPath(path,100,0);                        //平移之后再添加canvas.drawPath(newPath,mMyPathViewPaint);

效果图

多了两个参数 dx 和 dy

把之前的path进行x轴平移和y轴平移后再合并到新的Path中,也是如此的简单

第三个addPath

        canvas.translate(getWidth()/2,getHeight()/2);Matrix matrix = new Matrix();Path path = new Path();path.addCircle(0,0,100, Path.Direction.CW);Path newPath = new Path();newPath.addCircle(-100,0,100, Path.Direction.CW);matrix.postTranslate(100,0);newPath.addPath(path,matrix);                        //根据矩阵变化变化path再添加canvas.drawPath(newPath,mMyPathViewPaint);

效果图

注意:这里效果图是一样的,但是这里是进行矩阵变换,想要了解Matrix?请看大神写的这篇文章 Android Matrix的用法总结

本人不才,高数没学好,只知道调用方法,不知道这个矩阵的原理,以后有机会定会回来继续学习!

就这样,第二个系列也讲完了,还剩下两个系列,我们接着来看一个最简单的系列,is系列

is系列

public boolean isEmpty()
public boolean isRect(@Nullable  RectF rect)
public boolean isConvex()
public boolean isInverseFillType()

第一个简单,就不演示了,自行演示

isRectF

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.lineTo(100,0);path.lineTo(100,100);path.lineTo(0,100);path.lineTo(0,0);boolean isRect = path.isRect(new RectF(0,0,200,100));Log.i(TAG, "isRect: "+isRect);canvas.drawPath(path,mMyPathViewPaint);

效果图

isConvex和isInverseFillType()用的不多,自行查看api看意思就知道了

没有系列的系列

set

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.lineTo(100,200);Path dest = new Path();dest.set(path);canvas.drawPath(dest,mMyPathViewPaint);

效果图

这里就是把path里面的路径设置到我所new的Path里面

offset

public void offset(float dx, float dy)
public void offset(float dx, float dy, @Nullable Path dst)

第一个不带dst的

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.lineTo(100,200);Path dest = new Path();path.offset(100,0);                            //路径平移一段距离canvas.drawPath(path,mMyPathViewPaint);

效果图

offSet的意思就是把这个路径平移然后显示

第二个带dst参数的,效果都是一样的

带dst参数的方法的意思就是把平移后的路径存入到dst中,如果这个dst为null,就和不带参数的含义是相同的

op方法(用来做布尔运算,类似求交集,并集等)

public boolean op(Path path, Op op)
public boolean op(Path path1, Path path2, Op op)

这里两个方法的主要区别在于第一个的话会改变调用的path为做完布尔运算的路径,会改变原来的路径

我演示的方法会采用第二个方法,因为他不会改变调用者的路径,而且容易理解

        canvas.translate(getWidth()/2,getHeight()/2);mMyPathViewPaint.setStyle(Paint.Style.FILL);Path path = new Path();Path path1 = new Path();path1.addCircle(-50,0,100, Path.Direction.CW);Path path2 = new Path();path2.addCircle(50,0,100, Path.Direction.CW);path.op(path1,path2,Path.Op.INTERSECT);               //布尔运算canvas.drawPath(path,mMyPathViewPaint);canvas.drawPath(path1,mPaint);                        //方便观看效果画出的两个圆canvas.drawPath(path2,mPaint);

效果图

什么?你又用了什么鬼?Path.Op.INTERSECT???打扰了?其实我也不知道它后面具体的英文单词是什么意思,我们看效果,它一共有5个,那我们一一看一下吧~

public enum Op {/*** Subtract the second path from the first path.*/DIFFERENCE,/*** Intersect the two paths.*/INTERSECT,/*** Union (inclusive-or) the two paths.*/UNION,/*** Exclusive-or the two paths.*/XOR,/*** Subtract the first path from the second path.*/REVERSE_DIFFERENCE}

 DIFFERENCE(我理解为第一个和第二个路径不相交的部分)

        canvas.translate(getWidth()/2,getHeight()/2);mMyPathViewPaint.setStyle(Paint.Style.FILL);Path path = new Path();Path path1 = new Path();path1.addCircle(-50,0,100, Path.Direction.CW);Path path2 = new Path();path2.addCircle(50,0,100, Path.Direction.CW);path.op(path1,path2,Path.Op.DIFFERENCE);canvas.drawPath(path,mMyPathViewPaint);canvas.drawPath(path1,mPaint);canvas.drawPath(path2,mPaint);

效果图

INTERRSECT(相交部分)

下面三个我也同样不贴代码了,因为只要改Path.Op后面的常量就可以了,直接上效果图

UNION(合并,并集)

XOR(两个集合除去共有的交集)

REVERSE_DIFFERENCE(第二个集合中除去第一个集合的内容,java命名为反向,很灵性~~)

reset和rewind

都是擦除path中的内容,区别是
reset不保留内部数据结构,但会保留FillType
rewind会保留内部的数据结构,但不保留FillType

一般我们使用reset

transform

public void transform(Matrix matrix)
public void transform(Matrix matrix, Path dst)
        canvas.translate(getWidth()/2,getHeight()/2);Matrix matrix = new Matrix();Path path = new Path();path.addCircle(0,0,200, Path.Direction.CW);matrix.postTranslate(100,50);path.transform(matrix);canvas.drawPath(path,mMyPathViewPaint);

效果图

这里多个参数的方法和上面所说的一样,只不过把路径存储到一个新的path中.这里就是一个根据矩阵的变换.

到此,本篇博客终于要结束啦~但是还有两个哦,坚持一下,先说难的,其实也不难,嘻嘻~

setFillType

public enum FillType {// these must match the values in SkPath.h/*** Specifies that "inside" is computed by a non-zero sum of signed* edge crossings.*/WINDING         (0),/*** Specifies that "inside" is computed by an odd number of edge* crossings.*/EVEN_ODD        (1),/*** Same as {@link #WINDING}, but draws outside of the path, rather than inside.*/INVERSE_WINDING (2),/*** Same as {@link #EVEN_ODD}, but draws outside of the path, rather than inside.*/INVERSE_EVEN_ODD(3);FillType(int ni) {nativeInt = ni;}final int nativeInt;}

哦,呵呵,很好理解,填充模式,但是这些又是什么鬼,我们不用懂他是怎么命名的,你问我我也不知道,一个个试过去不就知道了

WINDING(并集)

        canvas.translate(getWidth()/2,getHeight()/2);mMyPathViewPaint.setStyle(Paint.Style.FILL);Path path = new Path();path.addCircle(-50,0,100, Path.Direction.CW);path.addCircle(0,0,100, Path.Direction.CW);path.setFillType(Path.FillType.WINDING);canvas.drawPath(path,mMyPathViewPaint);

效果图

下面的代码就不给出啦,一样,只要改Path.FillType后面的常量就可以了

EVEN_ODD(除去两者共同的部分)

INVERSE_EVEN_ODD(直接看效果吧,我也说不出这是什么鬼)

INVERSE_WINDING(也直接看效果图吧)

getFillType                         用来获取填充类型

isInverseFillType                判断填充类型是不是INVERSE开头的

toggleInverseFillType         转换填充类型

incReserve  用来提示当前路径还有多少个要画的点,反正我是不知道他是干嘛用的

还有最后两个,是贝塞尔曲线,分别为

quadTo     二阶贝塞尔曲线
cubicTo    三阶贝塞尔曲线

这两者我会在后续的文章中更新,内容比较多,篇幅大了,就到此为止吧,也累了

哦对了,忘了一个方法,这下真的是最后一个了哦

computeBounds

        canvas.translate(getWidth()/2,getHeight()/2);Path path = new Path();path.addCircle(0,0,100, Path.Direction.CW);path.addCircle(50,0,100, Path.Direction.CW);RectF rectF = new RectF();path.computeBounds(rectF,true);               //精确测量矩形大小canvas.drawRect(rectF,mMyPathViewPaint);      //方便观察,把圆和矩形都画了canvas.drawPath(path,mMyPathViewPaint);      

这个方法需要两个参数,第一个可以是一个空的矩形Rectf,第二个顾名思义表示是否需要精确的去测量这个矩形所占的大小

啊哈~满满的一篇关于Path的总结,看的爽吗?今天就到这里吧,后续我会带给大家别的一些文章,可以关注我哦~加油,每天进步一点点,积少成多,坚持者才能成大事儿~再见咯,谢谢各位的观看~

自定义View之Path的使用相关推荐

  1. 自定义view(二) Path绘画详解 圆形进度条

    目录 简介 基础api 圆形进度条 总结 简介 view的绘制可以由无数个形状组成,在canvas基础图形绘制中,我们已经把api提供好的基本图形讲过了.Path之所以单独一章出来是因为path可以由 ...

  2. 自定义view - 收藏集 - 掘金

    Android 从 0 开始自定义控件之 View 的 draw 过程 (九) - Android - 掘金 转载请标明出处: http://blog.csdn.net/airsaid/... 本文出 ...

  3. Android自定义View之画圆环(进阶篇:圆形进度条)

    前言: 如果你想读懂或者更好的理解本篇文章关于自定义圆环或圆弧的内容.请你务必提前阅读下Android自定义View之画圆环(手把手教你如何一步步画圆环).在这篇文章中,详细描述了最基本的自定义圆环的 ...

  4. 自定义View之Paint(画笔)的使用

    我们在自定义View的时候总是会用到Paint画笔对象和Canvas对象,我是这么理解的,你要画一个自定义View就必须要有水彩笔和你的A4纸(当然我只是这么一说,也可以使任何纸),水彩笔就相当于Pa ...

  5. 自定义View之绘图篇(一):基础图形的绘制

    生活是一面镜子,你对它笑,它就对你笑:你对它哭,它也对你哭.--萨克雷 在正文开始之前,我先抛一个脑洞大开的题目给大家:商人以45元一双进购了2双鞋子,然后亏本30一双出售.某个顾客给了他100买了2 ...

  6. 自定义View,和Canvas(画布),Paint(画笔),Path(路径)的用法

    重点 怎么自定义控件,Canvas画布,Paint画笔,Path路径的使用 首先为什么要自定义View: 在Android开发中有很多业务场景,原生的控件是无法满足应用,并且经常也会遇到一个UI在多处 ...

  7. 自定义View合辑(8)-跳跃的小球(贝塞尔曲线)

    为了加强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,所有的代码也都会开源,也希望读者能给个 star 哈 GitH ...

  8. android 画布实现签名,Android 自定义View手写签名并保存图片

    1.自定义View--支撑设置画笔色彩,画笔宽度,画板色彩,铲除画板,查看是否有签名,保存画板图片(仿制粘贴可直接使用) /***CreatedbyYyyyQon2020/3/5. *电子签名*/pu ...

  9. android canvas绘制圆角_Android自定义View撸一个渐变的温度指示器(TmepView)

    秦子帅明确目标,每天进步一点点..... 作者 |  andy 地址 |  blog.csdn.net/Andy_l1/article/details/82910061 1.概述 自定义View对需要 ...

最新文章

  1. PHP网站首页打不开的原因讲起
  2. 实战 | 哪个瞬间让你突然觉得CV技术真有用?
  3. ASP.NET页面借助IFrame提交表单数据所遇到的问题
  4. Kali Linux安装第三方软件
  5. 软考考后常见问题汇总
  6. Jira 的 数据库备份恢复 简单过程
  7. 列举python中可变数据类型_python 可变数据类型 和 不可变数据类型
  8. 模型需要对特征进行归一化吗_模型融合完全手册 - 套娃的艺术:将模型作为特征进行建模...
  9. CSS垂直居中,你会多少种写法?
  10. SAP 产品条码WMS结合 以及ABAP script的集成 BarCode
  11. open表和closed表_什么是左外连接?左外连接在工作表查询中的应用
  12. js右下角广告[兼容]
  13. 【解决方案修复谷歌翻译 Windows、macOS】谷歌翻译退出了中国市场不能用了
  14. 运动控制芯片 Motion Control ICs
  15. oracle学习札记94
  16. exploit completed, but no session was created
  17. 编程实践(Pandas)Task08
  18. 卡耐基计算机专业课程,你以为卡耐基梅隆大学只有计算机专业厉害吗?
  19. [动态规划-0] 前言-我的动态规划学习之路
  20. lg android 互动游戏,LG G7 开启游戏模式(理论适用所有LG手机)

热门文章

  1. 关于网站架构的几封邮件摘抄
  2. QTdesigner
  3. 类似零基础学python的小说_零基础小白十分钟用Python搭建小说网站!Python真的强!...
  4. 计算机毕业设计ssm家纺商品展示平台6gggz系统+程序+源码+lw+远程部署
  5. 我做分析师的十年感受 ( 三 )
  6. 从无法启动的Mac中恢复数据的3种方法
  7. 吃鸡游戏对服务器性能,超级服务器已部署!吃鸡国服再爆好消息,游戏速度将会起飞!...
  8. Jackson(二):@JsonFormat时间格式及时区问题
  9. UIlabel的行间距和字间距
  10. 深度学习中的几个错误率和准确率