您好,登錄后才能下訂單哦!
小編給大家分享一下Android如何實現仿百度地圖小度語音助手的貝塞爾曲線動畫,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
具體內容如下
效果圖
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; /** * 仿百度的語音助手--波浪動畫控件 */ public class VolumeWaveView extends View { private static final String TAG = "VolumeWaveView"; private static final int HEIGHT = 400;//整個控件的高度 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;//波動的幅度,你可以動態改變這個值,比如麥克風錄入的音量的高低 private static final int splitWidth = -200;//扇形的交錯距離 private Path path; private Paint paint1,paint2,paint3,paint4; private LinearGradient linearGradient1,linearGradient2,linearGradient3,linearGradient4;//四種漸變色 private ValueAnimator animator1,animator2,animator3,animator4,animator5;//五種動畫 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方法中不要創建大量對象,盡量復用對象 * @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);//起點 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);//起點 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); } /** * 添加屬性動畫 */ public void startAnimation() { Random random = new Random(); range = random.nextInt(100)%(100-10+1) + 10;//波動的幅度,模擬動態音量輸入,你可以自己設置 animator1 = ValueAnimator.ofInt(0,HEIGHT1,0); animator1.setDuration(1400); animator1.setInterpolator(new DecelerateInterpolator()); //無限循環 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()); //無限循環 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()); //無限循環 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()); //無限循環 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()); //無限循環 animator5.setRepeatCount(ValueAnimator.INFINITE); animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { h6 = (int) animation.getAnimatedValue(); invalidate(); } }); animator5.start(); } /** * 關閉動畫 */ 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中的貝塞爾曲線,然后加上屬性動畫,動態改變曲線的高度就可以了
以上是“Android如何實現仿百度地圖小度語音助手的貝塞爾曲線動畫”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。