您好,登錄后才能下訂單哦!
小編給大家分享一下Android如何實(shí)現(xiàn)仿百度地圖小度語(yǔ)音助手的貝塞爾曲線動(dòng)畫(huà),相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
具體內(nèi)容如下
效果圖
package com.example.helang.volumewave; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Shader; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator; import java.util.Random; /** * 仿百度的語(yǔ)音助手--波浪動(dòng)畫(huà)控件 */ public class VolumeWaveView extends View { private static final String TAG = "VolumeWaveView"; private static final int HEIGHT = 400;//整個(gè)控件的高度 private static final int HEIGHT1 = 200;//第一層曲線的高度 private static final int HEIGHT2 = 400;//第二層曲線的高度 private static final int HEIGHT3 = 350;//第三層曲線的高度 private float h2 = 200,h3 = 200, h4 = 300,h5 = 300,h6 = 200; private int range = 0;//波動(dòng)的幅度,你可以動(dòng)態(tài)改變這個(gè)值,比如麥克風(fēng)錄入的音量的高低 private static final int splitWidth = -200;//扇形的交錯(cuò)距離 private Path path; private Paint paint1,paint2,paint3,paint4; private LinearGradient linearGradient1,linearGradient2,linearGradient3,linearGradient4;//四種漸變色 private ValueAnimator animator1,animator2,animator3,animator4,animator5;//五種動(dòng)畫(huà) public VolumeWaveView(Context context) { this(context,null); } public VolumeWaveView(Context context, @Nullable AttributeSet attrs) { this(context,attrs,0); } public VolumeWaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs,defStyleAttr); initPaint(); } private void initPaint(){ path = new Path(); paint1 = new Paint(); paint1.setStyle(Paint.Style.FILL); paint1.setAntiAlias(true);//抗鋸齒 //漸變色1 linearGradient1 = new LinearGradient(0, 0, 0, HEIGHT1, Color.parseColor("#e652a6d2"), Color.parseColor("#e652d5a1"), Shader.TileMode.MIRROR); paint1.setShader(linearGradient1); paint2 = new Paint(); paint2.setAntiAlias(true);//抗鋸齒 paint2.setStyle(Paint.Style.FILL); //漸變色2 linearGradient2 = new LinearGradient(0, 0, 0, HEIGHT2, Color.parseColor("#e68952d5"), Color.parseColor("#e6525dd5"), Shader.TileMode.MIRROR); paint2.setShader(linearGradient2); paint3 = new Paint(); paint3.setAntiAlias(true);//抗鋸齒 paint3.setStyle(Paint.Style.FILL); //漸變色3 linearGradient3 = new LinearGradient(0, 0, 0, HEIGHT3, Color.parseColor("#e66852d5"), Color.parseColor("#e651b9d2"), Shader.TileMode.MIRROR); paint3.setShader(linearGradient3); paint4 = new Paint(); paint4.setAntiAlias(true);//抗鋸齒 paint4.setStyle(Paint.Style.FILL); //漸變色4 linearGradient4 = new LinearGradient(0, 0, 0, HEIGHT2, Color.parseColor("#e6d5527e"), Color.parseColor("#e6bf52d5"), Shader.TileMode.MIRROR); paint4.setShader(linearGradient4); } /** * draw方法中不要?jiǎng)?chuàng)建大量對(duì)象,盡量復(fù)用對(duì)象 * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawLayer3(canvas); drawLayer2(canvas); drawLayer1(canvas); } /** * 繪制第一層 * @param canvas */ private void drawLayer1(Canvas canvas){ path.reset();//重置path path.moveTo(0, HEIGHT);//起點(diǎn) path.quadTo(getWidth()/4, HEIGHT-h2, getWidth()/2, HEIGHT);//第一條二階貝塞爾曲線 path.moveTo(getWidth()/2+splitWidth,HEIGHT); path.quadTo(getWidth()/2+splitWidth+getWidth()/4, HEIGHT-h3, getWidth(), HEIGHT);//第二條二階貝塞爾曲線 canvas.drawPath(path,paint1); } /** * 繪制第二層 * @param canvas */ private void drawLayer2(Canvas canvas){ path.reset();//重置path path.moveTo(0, HEIGHT);//起點(diǎn) path.quadTo(getWidth()/4, HEIGHT-h4, getWidth()/2, HEIGHT);//第一條二階貝塞爾曲線 canvas.drawPath(path,paint2); path.reset(); path.moveTo(getWidth()/2+splitWidth,HEIGHT); path.quadTo(getWidth()/2+getWidth()/4, HEIGHT-h5, getWidth(), HEIGHT);//第二條二階貝塞爾曲線 canvas.drawPath(path,paint4); } /** * 繪制第三層 * @param canvas */ private void drawLayer3(Canvas canvas){ path.reset();//重置path path.moveTo(200,HEIGHT); path.quadTo(200+getWidth()/3, HEIGHT-h6, getWidth(), HEIGHT);//二階貝塞爾曲線 canvas.drawPath(path,paint3); } /** * 添加屬性動(dòng)畫(huà) */ public void startAnimation() { Random random = new Random(); range = random.nextInt(100)%(100-10+1) + 10;//波動(dòng)的幅度,模擬動(dòng)態(tài)音量輸入,你可以自己設(shè)置 animator1 = ValueAnimator.ofInt(0,HEIGHT1,0); animator1.setDuration(1400); animator1.setInterpolator(new DecelerateInterpolator()); //無(wú)限循環(huán) animator1.setRepeatCount(ValueAnimator.INFINITE); animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h2 = (int) animation.getAnimatedValue(); invalidate(); } }); animator1.start(); animator2 = ValueAnimator.ofInt(0,HEIGHT1,0); animator2.setDuration(1700); animator2.setInterpolator(new DecelerateInterpolator()); //無(wú)限循環(huán) animator2.setRepeatCount(ValueAnimator.INFINITE); animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h3 = (int) animation.getAnimatedValue(); invalidate(); } }); animator2.start(); animator3 = ValueAnimator.ofInt(0,HEIGHT2,0); animator3.setDuration(1600); animator3.setInterpolator(new DecelerateInterpolator()); //無(wú)限循環(huán) animator3.setRepeatCount(ValueAnimator.INFINITE); animator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h4 = (int) animation.getAnimatedValue() + range; invalidate(); } }); animator3.start(); animator4 = ValueAnimator.ofInt(0,HEIGHT2,0); animator4.setDuration(1300); animator4.setInterpolator(new DecelerateInterpolator()); //無(wú)限循環(huán) animator4.setRepeatCount(ValueAnimator.INFINITE); animator4.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h5 = (int) animation.getAnimatedValue(); invalidate(); } }); animator4.start(); animator5 = ValueAnimator.ofInt(0,HEIGHT2,0); animator5.setDuration(1250); animator5.setInterpolator(new DecelerateInterpolator()); //無(wú)限循環(huán) animator5.setRepeatCount(ValueAnimator.INFINITE); animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h6 = (int) animation.getAnimatedValue(); invalidate(); } }); animator5.start(); } /** * 關(guān)閉動(dòng)畫(huà) */ public void removeAnimation(){ if (animator1 != null){ animator1.cancel(); animator1 = null; } if (animator2 != null){ animator2.cancel(); animator2 = null; } if (animator3 != null){ animator3.cancel(); animator3 = null; } if (animator4 != null){ animator4.cancel(); animator4 = null; } if (animator5 != null){ animator5.cancel(); animator5 = null; } } }
主要是利用Path中的貝塞爾曲線,然后加上屬性動(dòng)畫(huà),動(dòng)態(tài)改變曲線的高度就可以了
以上是“Android如何實(shí)現(xiàn)仿百度地圖小度語(yǔ)音助手的貝塞爾曲線動(dòng)畫(huà)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。