View详解(4)

在上文中我们简单介绍了Canvas#drawCircle()的使用方式,以及Paint#setStyle(),Paint#setStrokeWidth(),Paint#setColor()等相关函数,不知道小伙伴们了解了多少?那么是不是所有的图形都能通过圆来描述呢?当然不行,那么熟悉API套路的我们就应该知道,这时候应该去看Canvas源码中提供的公有方法是否能满足我们的需求,这样我们就会看到下表中的公有函数:

公有函数函数说明
drawBitmap绘制图片
drawArc绘制圆弧
drawLine绘制线条
drawOval绘制椭圆
drawPoint绘制点
drawRect绘制矩形
drawRoundRect绘制圆角矩形
drawText绘制字符串

上表中大多数函数都不止一个实现,具体的参数含义也不同。激动的你们是不是已经搬好小板凳,等着我讲解这些函数的用法及参数了?不好意思,要让你们失望了,我一向秉承,授之以鱼,不如授之以渔,所以亲们自行尝试这些函数哦,绘制结果老规矩,后台等你们哦!

接下来敲黑板,开始画重点喽,仔细排查上表中函数,思考三角形,五角形,六角形,五角星等的绘制方法。肯定有小伙伴立刻补刀,傻不傻?画线啊,拼起来不就好?那么问题来了,让你画一个红色三角形怎么搞?三条线拼起来,Paint设置成Style.FILL能搞定?

机智的我立马去撸了一波代码

  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    canvas.drawLine(10,10,200,200,mPaint);    canvas.drawLine(200,200,150,200,mPaint);    canvas.drawLine(150,200,10,10,mPaint);  }  private void init(){    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    mPaint.setColor(Color.RED);    mPaint.setStyle(Style.FILL);  }复制代码

手抖一运行,秒打脸,结果是图-错误的三角


那到底要怎么整呢?Google爸爸设计API不可能没考虑到这些东东啊?不服气,接着搜源码,终于找到了一个看不懂的东东:
public void drawPath(@NonNull Path path, @NonNull Paint paint)复制代码

这个Path到底是个什么东东,下面我们一起来学习下。

Path

什么是Path

Path英翻汉的结果是路径,路途,也就是说Path代表着一段可用路径。使用Path可以构建一个路径对象,用于Canvas绘制,Path中的相关函数及说明我们用到一个讲解一个,有兴趣的小伙伴可以自行查阅尝试,资料很多。

绘制三角形

在使用Path定义路径时,我们首先应该为该路径指定起点,使用Path#moveTo()方法,随后使用其他函数绘制所需路径即可,以开篇三角形为例,构建Path的代码如下:

    //Path对象初始化    mPath = new Path();    //移动路径起点到(10,10)    mPath.moveTo(10,10);    //从点(10,10)绘制直线到点(200,200)    mPath.lineTo(200,200);    //从点(200,200)绘制直线到点(150,200)    mPath.lineTo(150,200);    //闭合该路径,从当前点绘制直线到起点    mPath.close();复制代码

随后使用Canvas#drawPath绘制该路径,代码如下:

//第一个参数为路径对象,第二个参数为画笔canvas.drawPath(mPath,mPaint);复制代码

再次运行,我们可以看到界面上有一个实心红色三角形,如下图:

这里请大家自行绘制五边形,六边形。老规矩,截图甩后台。

前面小试牛刀,绘制了一个小小三角形,大家对Path应该还是一知半解,接下来我们进一步学习如何使用Path描述自定义View中的不规则路径。目标下面动图:


咋一看,是不是一个头两个大,不要方,都是纸老虎,我们来一点一点分析。

动画形成过程

仔细观察上面动图,我们不难发现整个图形由四部分组成,拿出其中一部分单独分析,我们不难得到下图:


左上角这四分之一是由两条直线加四分之一圆弧组成,其中动画是由点P的位置变化形成的,P点坐标范围起于图1止于图4.

Path组成及点坐标

还是以左上角四分之一做细致分析,讲解Path的形成过程及点坐标,详细的左上角坐标标记如下图:


描述左上角的Path路径对象伪代码如下:

移动起点到点B,绘制四分之一圆,绘制直线AP,然后闭合该路径即可复制代码

进一步细化上图中辅助点,计算我们所需要的三个关键点P,A,B的坐标,细化后的分析图如下:

如上图所示我们假设要绘制的圆半径为R,那么可以得到P点所能取得的最大坐标值为(O-B1,O-A1),其中O-B1=O-A1。

由于三角形OPA是等腰三角形,所以其高线P-A1=R/2,又B1-O = P-A1,所以O-B1 = R/2

进而我们可以得到P点的取值范围为(0,0)到(R/2,R/2).

生成Path

切换坐标系到我们的View坐标系内,假设P点坐标为(x,x),x取值范围为0到R/2,从而我们可以确认得到左上角路径上的P,A,B三点坐标,其中:

A(mWidth/2,mHeight/2 - R)
B(mWidth/2 - R,mHeight/2)
P(mWidth/2 - x,mHeight/2 - x)

获得ABP三点坐标后,接下来的重点就是怎么将四分之圆加入Path对象了,这里我们就需要用到Path#addArc()方法了,函数声明如下:

//第一个参数为圆弧所在矩形区域,第二个参数为截图的开始角度,第三个参数为截取的角度大小public void addArc(RectF oval, float startAngle, float sweepAngle)复制代码

画图说明如下:

一点要注意第三个参数是截取得角度大小,从水平方向开始,顺时针取正值,逆时针取负值

那么此时我们就可以确定左上角的Path对象了,代码如下:

    //清空上一次Path中存放的所有路径    mPath3.reset();    //移动路径起点到B点    mPath3.moveTo(mWidth / 2 - mRadius, mHeight / 2);    //绘制四分之一圆弧BA    mPath3.addArc(new RectF(mWidth / 2 - mRadius, mHeight / 2 - mRadius, mWidth / 2 + mRadius,        mHeight / 2 + mRadius), 180, 90);    //绘制直线AP    mPath3.lineTo(mWidth / 2 - x, mHeight / 2 - x);    //闭合曲线,默认绘制直线PB    mPath3.close();复制代码

生成动画

  public void startAnimation() {    //新建ValueAnimator对象    mValueAnimator = ValueAnimator.ofFloat(0f, mRadius / 2f);    //设置动画单次时长    mValueAnimator.setDuration(5000);    //设置动画重复模式,REVERSE--反转,RESTART--重新开始    mValueAnimator.setRepeatMode(ValueAnimator.REVERSE);    //设置动画重复次数,-1 --- INFINE    mValueAnimator.setRepeatCount(-1);    mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator valueAnimator) {        //更新P点坐标        x = (float) valueAnimator.getAnimatedValue();        postInvalidate();      }    });    mValueAnimator.start();  }复制代码

运行后效果如下:

作业

上面已经详细解释了左上角的绘制过程,相信机智的你已经完全懂了,那么请自行完成剩余三部分的绘制,交流群里gif甩起来。

下期预告

提前透漏个动画给你们。还是在圆上搞事情,感觉和圆杠上了。


完整代码

public class ArcView extends View {  private Paint mPathPaint;  private Path mPath;  private int mWidth;  private int mHeight;  private int mRadius = 200;  private ValueAnimator mValueAnimator;  private float x = 0f;  public ArcView(Context context) {    super(context);    init();  }  public ArcView(Context context, @Nullable AttributeSet attrs) {    super(context, attrs);    init();  }  @Override  protected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    if (w > 0 && h > 0) {      mWidth = w;      mHeight = h;    }  }  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    initPaths();    mPathPaint.setColor(Color.parseColor("#FD9A59"));    canvas.drawPath(mPath, mPathPaint);  }  private void init() {    mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    mPathPaint.setStyle(Style.FILL);    mPath = new Path();  }  private void initPaths() {    mPath.reset();    mPath.moveTo(mWidth / 2 - mRadius, mHeight / 2);    mPath.addArc(new RectF(mWidth / 2 - mRadius, mHeight / 2 - mRadius, mWidth / 2 + mRadius,        mHeight / 2 + mRadius), 180, 90);    mPath.lineTo(mWidth / 2 - x, mHeight / 2 - x);    mPath.close();  }  public void startAnimation() {    mValueAnimator = ValueAnimator.ofFloat(0f, mRadius / 2f);    mValueAnimator.setDuration(5000);    mValueAnimator.setRepeatMode(ValueAnimator.REVERSE);    mValueAnimator.setRepeatCount(-1);    mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator valueAnimator) {        x = (float) valueAnimator.getAnimatedValue();        postInvalidate();      }    });    mValueAnimator.start();  }}复制代码


觉得不错的亲们动动手指分享转发下哈。



转载于:https://juejin.im/post/5bc85103e51d450e925290d3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成为一名真正的数据科学家有多困难

Data Science and Machine Learning are hard sports to play. It’s difficult enough to motivate yourself to sit down and learn some maths, let alone to becoming an expert on the matter.数据科学和机器学习是一项艰巨的运动。 激励自己坐下来学习一些数学知识是非常…

Ubuntu 装机软件

Ubuntu16.04 软件商店闪退打不开 sudo apt-get updatesudo apt-get dist-upgrade# 应该执行一下更新就好,不需要重新安装软件中心 sudo apt-get install –reinstall software-center Ubuntu16.04 深度美化 https://www.jianshu.com/p/4bd2d9b1af41 Ubuntu18.04 美化…

数据分析中的统计概率_了解统计和概率:成为专家数据科学家

数据分析中的统计概率Data Science is a hot topic nowadays. Organizations consider data scientists to be the Crme de la crme. Everyone in the industry is talking about the potential of data science and what data scientists can bring in their BigTech and FinT…

Keras框架:Mobilenet网络代码实现

Mobilenet概念: MobileNet模型是Google针对手机等嵌入式设备提出的一种轻量级的深层神经网络,其使用的核心思想便是depthwise separable convolution。 Mobilenet思想: 通俗地理解就是3x3的卷积核厚度只有一层,然后在输入张量上…

clipboard 在 vue 中的使用

简介 页面中用 clipboard 可以进行复制粘贴&#xff0c;clipboard能将内容直接写入剪切板 安装 npm install --save clipboard 使用方法一 <template><span>{{ code }}</span><iclass"el-icon-document"title"点击复制"click"co…

数据驱动开发_开发数据驱动的股票市场投资方法

数据驱动开发Data driven means that your decision are driven by data and not by emotions. This approach can be very useful in stock market investment. Here is a summary of a data driven approach which I have been taking recently数据驱动意味着您的决定是由数据…

前端之sublime text配置

接下来我们来了解如何调整sublime text的配置&#xff0c;可能很多同学下载sublime text的时候就是把它当成记事本来使用&#xff0c;也就是没有做任何自定义的配置&#xff0c;做一些自定义的配置可以让sublime text更适合我们的开发习惯。 那么在利用刚才的命令面板我们怎么打…

python 时间序列预测_使用Python进行动手时间序列预测

python 时间序列预测Time series analysis is the endeavor of extracting meaningful summary and statistical information from data points that are in chronological order. They are widely used in applied science and engineering which involves temporal measureme…

keras框架:目标检测Faster-RCNN思想及代码

Faster-RCNN&#xff08;RPN CNN ROI&#xff09;概念 Faster RCNN可以分为4个主要内容&#xff1a; Conv layers&#xff1a;作为一种CNN网络目标检测方法&#xff0c;Faster RCNN首先使用一组基础的convrelupooling层提取 image的feature maps。该feature maps被共享用于…

算法偏见是什么_算法可能会使任何人(包括您)有偏见

算法偏见是什么在上一篇文章中&#xff0c;我们展示了当数据将情绪从动作中剥离时会发生什么 (In the last article, we showed what happens when data strip emotions out of an action) In Part 1 of this series, we argued that data can turn anyone into a psychopath, …

大数据笔记-0907

2019独角兽企业重金招聘Python工程师标准>>> 复习: 1.clear清屏 2.vi vi xxx.log i-->edit esc-->command shift:-->end 输入 wq 3.cat xxx.log 查看 --------------------------- 1.pwd 查看当前光标所在的path 2.家目录 /boot swap / 根目录 起始位置 家…

Tensorflow框架:目标检测Yolo思想

Yolo-You Only Look Once YOLO算法采用一个单独的CNN模型实现end-to-end的目标检测&#xff1a; Resize成448448&#xff0c;图片分割得到77网格(cell)CNN提取特征和预测&#xff1a;卷积部分负责提取特征。全链接部分负责预测&#xff1a;过滤bbox&#xff08;通过nms&#…

线性回归非线性回归_了解线性回归

线性回归非线性回归Let’s say you’re looking to buy a new PC from an online store (and you’re most interested in how much RAM it has) and you see on their first page some PCs with 4GB at $100, then some with 16 GB at $1000. Your budget is $500. So, you es…

朴素贝叶斯和贝叶斯估计_贝叶斯估计收入增长的方法

朴素贝叶斯和贝叶斯估计Note from Towards Data Science’s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works wi…

numpy统计分布显示

import numpy as np from sklearn.datasets import load_iris dataload_iris()petal_lengthnumpy.array(list(len[2]for len in data[data]))#取出花瓣长度数据 print(np.max(petal_length))#花瓣长度最大值 print(np.mean(petal_length))#花瓣长度平均值 print(np.std(petal_l…

python数据结构:进制转化探索

*********************************第一部分******************************************************************************************************************************************************************************************# 输入excel的行号&#xff0c;…

Keras框架:人脸检测-mtcnn思想及代码

人脸检测-mtcnn 概念&#xff1a; MTCNN&#xff0c;英文全称是Multi-task convolutional neural network&#xff0c;中文全称是多任务卷积神经网络&#xff0c; 该神经网络将人脸区域检测与人脸关键点检测放在了一起。 从工程实践上&#xff0c;MTCNN是一种检测速度和准确率…

python中格式化字符串_Python中所有字符串格式化的指南

python中格式化字符串Strings are one of the most essential and used datatypes in programming. It allows the computer to interact and communicate with the world, such as printing instructions or reading input from the user. The ability to manipulate and form…

Javassist实现JDK动态代理

提到JDK动态代理&#xff0c;相信很多人并不陌生。然而&#xff0c;对于动态代理的实现原理&#xff0c;以及如何编码实现动态代理功能&#xff0c;可能知道的人就比较少了。接下一来&#xff0c;我们就一起来看看JDK动态代理的基本原理&#xff0c;以及如何通过Javassist进行模…

数据图表可视化_数据可视化如何选择正确的图表第1部分

数据图表可视化According to the World Economic Forum, the world produces 2.5 quintillion bytes of data every day. With so much data, it’s become increasingly difficult to manage and make sense of it all. It would be impossible for any person to wade throug…