android實(shí)現(xiàn)貝塞爾曲線之波浪效果
本文實(shí)例為大家分享了android實(shí)現(xiàn)貝塞爾曲線之波浪效果的具體代碼,供大家參考,具體內(nèi)容如下
1 前言
為了給我以前的博客填坑,這章講解貝塞爾曲線的幾個常用的應(yīng)用:
1.波浪效果
2.qq聊天列表上的沾粘體效果
3.翻書頁效果
4.彈性球效果
大家如果把這些看懂并掌握,以后做和貝塞爾曲線相關(guān)的效果應(yīng)該都能信手拈來!
2 波浪效果
原理分析:
其實(shí)這個效果應(yīng)用了2個階的貝塞爾曲線來完成的,先看一下原理分析圖:
有上面的圖可以看出:在屏幕的左面畫出了1.5個波長,在屏幕中畫出1個波長,然后讓它循環(huán)的向右移動,這個就會出現(xiàn)波浪效果,這里有幾點(diǎn)需要注意:
1.為什么是1.5個波長而不是1個波長呢?
理論上1個波長就夠了,但是實(shí)際運(yùn)行出來的效果會出現(xiàn)不協(xié)調(diào),所以經(jīng)過調(diào)試,我又加了0.5個波長
2.那條綠線是干什么用的?
在波浪線以下的所有空間都要填充成一個顏色,所以path必須是封閉的區(qū)間,只有這個才能填充。代碼中我會具體的解釋
我們在編碼的時候只需要計(jì)算最左面半個波長的坐標(biāo),其他的用for循環(huán)搞定。
好了我們看一下代碼:
public class WaveView extends View { ? ? private int ?width = 0; ? ? private int height = 0; ? ? private int baseLine = 0;// 基線,用于控制水位上漲的,這里是寫死了沒動,你可以不斷的設(shè)置改變。 ? ? private Paint mPaint; ? ? private int waveHeight = 100;// 波浪的最高度 ? ? private int waveWidth ?;//波長 ? ? private float offset =0f;//偏移量 ? ? public WaveView(Context context, AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? initView(); ? ? } ? ? /** ? ? ?* 不斷的更新偏移量,并且循環(huán)。 ? ? ?*/ ? ? private void updateXControl(){ ? ? ? ? //設(shè)置一個波長的偏移 ? ? ? ? ValueAnimator mAnimator = ValueAnimator.ofFloat(0,waveWidth); ? ? ? ? mAnimator.setInterpolator(new LinearInterpolator()); ? ? ? ? mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onAnimationUpdate(ValueAnimator animation) { ? ? ? ? ? ? ? ? float animatorValue = (float)animation.getAnimatedValue() ; ? ? ? ? ? ? ? ? offset = animatorValue;//不斷的設(shè)置偏移量,并重畫 ? ? ? ? ? ? ? ? postInvalidate(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? mAnimator.setDuration(1000); ? ? ? ? mAnimator.setRepeatCount(ValueAnimator.INFINITE); ? ? ? ? mAnimator.start(); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? super.onDraw(canvas); ? ? ? ? canvas.drawPath(getPath(),mPaint); ? ? } ? ? //初始化paint,沒什么可說的。 ? ? private void initView(){ ? ? ? ? mPaint = new Paint(); ? ? ? ? mPaint.setColor(Color.RED); ? ? ? ? mPaint.setStyle(Paint.Style.FILL); ? ? } ? ? @Override ? ? protected void onLayout(boolean changed, int left, int top, int right, int bottom) { ? ? ? ? super.onLayout(changed, left, top, right, bottom); ? ? ? ? width = getMeasuredWidth();//獲取屏幕寬度 ? ? ? ? height = getMeasuredHeight();//獲取屏幕高度 ? ? ? ? waveWidth = width; ? ? ? ? baseLine = height/2; ? ? ? ? updateXControl(); ? ? } ? ? /** ? ? ?* 核心代碼,計(jì)算path ? ? ?* @return ? ? ?*/ ? ? private Path ?getPath(){ ? ? ? ? int itemWidth = waveWidth/2;//半個波長 ? ? ? ? Path mPath = new Path(); ? ? ? ? mPath.moveTo(-itemWidth * 3, baseLine);//起始坐標(biāo) ? ? ? ? //核心的代碼就是這里 ? ? ? ? for (int i = -3; i < 2; i++) { ? ? ? ? ? ? int startX = i * itemWidth; ? ? ? ? ? ? mPath.quadTo( ? ? ? ? ? ? ? ? ? ? startX + itemWidth/2 + offset,//控制點(diǎn)的X,(起始點(diǎn)X + itemWidth/2 + offset) ? ? ? ? ? ? ? ? ? ? getWaveHeigh( i ),//控制點(diǎn)的Y ? ? ? ? ? ? ? ? ? ? startX + itemWidth + offset,//結(jié)束點(diǎn)的X ? ? ? ? ? ? ? ? ? ? baseLine//結(jié)束點(diǎn)的Y ? ? ? ? ? ? );//只需要處理完半個波長,剩下的有for循環(huán)自已就添加了。 ? ? ? ? } ? ? ? ? //下面這三句話很重要,它是形成了一封閉區(qū)間,讓曲線以下的面積填充一種顏色,大家可以把這3句話注釋了看看效果。 ? ? ? ? mPath.lineTo(width,height); ? ? ? ? mPath.lineTo(0,height); ? ? ? ? mPath.close(); ? ? ? ? return ?mPath; ? ? } ? ? //奇數(shù)峰值是正的,偶數(shù)峰值是負(fù)數(shù) ? ? private int getWaveHeigh(int num){ ? ? ? ? if(num % 2 == 0){ ? ? ? ? ? ? return baseLine + waveHeight; ? ? ? ? } ? ? ? ? return baseLine - waveHeight; ? ? } }
核心的代碼在 getPath()方法中,其實(shí)這個坐標(biāo)是有規(guī)律的:
先找到最左面的半個波長,設(shè)置貝塞爾曲線坐標(biāo),
然后用for循環(huán),不斷的設(shè)置,
這個規(guī)律大家體會,我這里簡單提一下。
3 qq聊天列表上的沾粘體效果
先看一個效果圖:
這個做起來小有點(diǎn)復(fù)雜。具體思路如下:
1.畫兩個圓,一個黏連小球固定在一個點(diǎn)上,一個氣泡小球跟隨手指的滑動改變坐標(biāo)。隨著兩個圓間距越來越大,黏連小球半徑越來越小。
2.當(dāng)間距小于一定值,松開手指氣泡小球會恢復(fù)原來位置;
3.當(dāng)間距超過一定值之后,黏連小球消失,氣泡小球繼續(xù)跟隨手指移動,此時手指松開,氣泡小球消失~
結(jié)尾
本來想把上面的全部弄在一篇博客呢,現(xiàn)在看來不太可能,一篇一篇的來吧。核心就是貝塞爾曲線的應(yīng)用,大家如何理解了貝塞爾曲線,這些都不難。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android ListView與ScrollView沖突的解決方法總結(jié)
這篇文章主要介紹了Android ListView與ScrollView沖突的解決方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-04-04使用Android studio查看Kotlin的字節(jié)碼教程
這篇文章主要介紹了使用Android studio查看Kotlin的字節(jié)碼教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例
下面小編就為大家分享一篇Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12Android組件Glide實(shí)現(xiàn)圖片平滑滾動效果
這篇文章主要介紹了Android組件Glide實(shí)現(xiàn)圖片平滑滾動效果的相關(guān)資料,具有一定的參考價值,需要的朋友可以參考下2016-07-07Android App中使用RatingBar實(shí)現(xiàn)星級打分功能的教程
這篇文章主要介紹了Android App中使用RatingBar實(shí)現(xiàn)星級打分功能的教程,文中舉了一個使用SeekBar與RatingBar制作的應(yīng)用內(nèi)打分條的功能,非常簡單,需要的朋友可以參考下2016-04-04Android判斷和監(jiān)聽底座狀態(tài)和類型的方法介紹
這篇文章主要介紹了Android判斷和監(jiān)聽底座狀態(tài)和類型的方法介紹,例如判斷當(dāng)前底座狀態(tài)、判斷插入底座類型、監(jiān)控充電充電狀態(tài)等,需要的朋友可以參考下2014-06-06