Android仿百度地圖小度語音助手的貝塞爾曲線動畫
更新時間:2018年07月27日 10:28:42 作者:何浪
這篇文章主要為大家詳細介紹了Android仿百度地圖小度語音助手的貝塞爾曲線動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文為大家分享了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 h1 = 200,h2 = 200, h3 = 300,h4 = 300,h5 = 200;
private int range = 0;//波動的幅度,你可以動態(tài)改變這個值,比如麥克風錄入的音量的高低
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方法中不要創(chuàng)建大量對象,盡量復用對象
* @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-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);//起點
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);
}
/**
* 添加屬性動畫
*/
public void startAnimation() {
Random random = new Random();
range = random.nextInt(100)%(100-10+1) + 10;//波動的幅度,模擬動態(tài)音量輸入,你可以自己設置
animator1 = ValueAnimator.ofInt(0,HEIGHT1,0);
animator1.setDuration(1400);
animator1.setInterpolator(new DecelerateInterpolator());
//無限循環(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());
//無限循環(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());
//無限循環(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());
//無限循環(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());
//無限循環(huán)
animator5.setRepeatCount(ValueAnimator.INFINITE);
animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
h5 = (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中的貝塞爾曲線,然后加上屬性動畫,動態(tài)改變曲線的高度就可以了
喜歡的話,就去github給個star吧
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- Android 利用三階貝塞爾曲線繪制運動軌跡的示例
- Android Path繪制貝塞爾曲線實現(xiàn)QQ拖拽泡泡
- Android貝塞爾曲線初步學習第三課 Android實現(xiàn)添加至購物車的運動軌跡
- Android貝塞爾曲線實現(xiàn)直播點贊效果
- Android貝塞爾曲線初步學習第一課
- Android利用二階貝塞爾曲線實現(xiàn)添加購物車動畫詳解
- Android貝塞爾曲線實現(xiàn)填充不規(guī)則圖形并隨手指運動
- Android使用貝塞爾曲線仿QQ聊天消息氣泡拖拽效果
- Android貝塞爾曲線實現(xiàn)消息拖拽消失
- Android自定義view實現(xiàn)圓形waveview
相關文章
android?studio項目:綁定服務和線程實現(xiàn)計時器
這篇文章主要介紹了android?studio項目:綁定服務和線程實現(xiàn)計時器,完成一個秒表,具備啟停功能,通過綁定服務實現(xiàn)功能,通過Thread+handler更新界面,需要的朋友可以參考一下2021-12-12
Android自定義控件實現(xiàn)UC瀏覽器語音搜索效果
這篇文章主要為大家詳細介紹了Android自定義控件實現(xiàn)UC瀏覽器語音搜索效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
通過案例分析Android WindowManager解析與騙取QQ密碼的過程
Windows Manager是一款窗口管理終端,可以遠程連接到Linux的X桌面進行管理,與服務器端產生一個session相互通信,通過本文給大家分享Android WindowManager解析與騙取QQ密碼的過程,需要的朋友參考下2016-01-01

