Android仿百度地圖小度語(yǔ)音助手的貝塞爾曲線動(dòng)畫(huà)
本文為大家分享了Android仿小度語(yǔ)音助手的貝塞爾曲線動(dòng)畫(huà),供大家參考,具體內(nèi)容如下
廢話不多說(shuō),看下面的動(dòng)圖,和百度的還是有點(diǎn)點(diǎn)差別,我也不修改了,很簡(jiǎn)單,我實(shí)在是沒(méi)有多余的時(shí)間,還要學(xué)習(xí)其他的東西。
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 h1 = 200,h2 = 200, h3 = 300,h4 = 300,h5 = 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-h1, getWidth()/2, HEIGHT);//第一條二階貝塞爾曲線 path.moveTo(getWidth()/2+splitWidth,HEIGHT); path.quadTo(getWidth()/2+splitWidth+getWidth()/4, HEIGHT-h2, 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-h3, getWidth()/2, HEIGHT);//第一條二階貝塞爾曲線 canvas.drawPath(path,paint2); path.reset(); path.moveTo(getWidth()/2+splitWidth,HEIGHT); path.quadTo(getWidth()/2+getWidth()/4, HEIGHT-h4, 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-h5, 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) { h1 = (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) { h2 = (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) { h3 = (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) { h4 = (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) { h5 = (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)改變曲線的高度就可以了
喜歡的話,就去github給個(gè)star吧
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 利用三階貝塞爾曲線繪制運(yùn)動(dòng)軌跡的示例
- Android Path繪制貝塞爾曲線實(shí)現(xiàn)QQ拖拽泡泡
- Android貝塞爾曲線初步學(xué)習(xí)第三課 Android實(shí)現(xiàn)添加至購(gòu)物車(chē)的運(yùn)動(dòng)軌跡
- Android貝塞爾曲線實(shí)現(xiàn)直播點(diǎn)贊效果
- Android貝塞爾曲線初步學(xué)習(xí)第一課
- Android利用二階貝塞爾曲線實(shí)現(xiàn)添加購(gòu)物車(chē)動(dòng)畫(huà)詳解
- Android貝塞爾曲線實(shí)現(xiàn)填充不規(guī)則圖形并隨手指運(yùn)動(dòng)
- Android使用貝塞爾曲線仿QQ聊天消息氣泡拖拽效果
- Android貝塞爾曲線實(shí)現(xiàn)消息拖拽消失
- Android自定義view實(shí)現(xiàn)圓形waveview
相關(guān)文章
Android getActivity()為空的問(wèn)題解決辦法
這篇文章主要介紹了Android getActivity()為空的問(wèn)題解決辦法的相關(guān)資料,導(dǎo)致apk空指針崩潰問(wèn)題,很?chē)?yán)重的問(wèn)題,為了解決這問(wèn)題,上網(wǎng)搜索了很多資料,需要的朋友可以參考下2017-07-07android-使用環(huán)信SDK開(kāi)發(fā)即時(shí)通信功能(附源碼下載)
本篇文章主要介紹了android-使用環(huán)信SDK開(kāi)發(fā)即時(shí)通信功能,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。2016-12-12Android onLoadFinished與onLoaderReset回調(diào)詳解及實(shí)例
這篇文章主要介紹了Android onLoadFinished與onLoaderReset回調(diào)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03Android開(kāi)發(fā)實(shí)現(xiàn)TextView顯示豐富的文本
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)TextView顯示豐富的文本,涉及Android中TextView的使用技巧,需要的朋友可以參考下2015-12-12Android加載loading對(duì)話框的功能及實(shí)例代碼(不退出沉浸式效果)
這篇文章主要介紹了Android加載loading對(duì)話框的功能及實(shí)例代碼,不退出沉浸式效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12