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.pswp.cn/news/389471.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389471.shtml
英文地址,請注明出處:http://en.pswp.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…