本文实例为大家分享了android自定义波浪加载动画的具体代码,供大家参考,具体内容如下

效果图

1.自定义控件 WaveView

package com.example.wh.myapplication;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.support.annotation.Nullable;

import android.support.v4.content.ContextCompat;

import android.util.AttributeSet;

import android.view.View;

import java.text.DecimalFormat;

public class WaveView extends View {

/**

* 默认波浪1长度

*/

private final int WAVE_LENGTH1 = 600;

/**

* 默认波浪1高度

*/

private final int WAVE_HEIGHT1 = 30;

/**

* 波浪1高度

*/

private int mWaveHeight1 = WAVE_HEIGHT1;

/**

* 波浪1长度

*/

private int mWaveLenght1 = WAVE_LENGTH1;

/**

* 默认波浪1颜色

*/

private final int WAVE_COLOR1 = Color.parseColor("#0000ff");

/**

* 默认边框颜色

*/

private final int BORDER_COLOR = Color.parseColor("#800000ff");

/**

* 默认文字颜色

*/

private final int DEFAULT_TEXT_COLOR = Color.parseColor("#ff0000");

/**

* 默认文字大小

*/

private final int DEFAULT_TEXT_SIZE = 30;

/**

* 文字颜色

*/

private int mTextColor = DEFAULT_TEXT_COLOR;

/**

* 文字大小

*/

private int mTextSize = DEFAULT_TEXT_SIZE;

/**

* 波浪1颜色

*/

private int mWaveColor1 = WAVE_COLOR1;

/**

* 默认每一次重绘时波峰1的移动的距离,实现移动效果

*/

private final int WAVE_OFFSET1 = 8;

/**

* 每一次重绘时波峰1的移动的距离,实现移动效果

*/

private int mOffset1 = WAVE_OFFSET1;

/**

* 默认边框宽度

*/

private final int BORDER_WIDTH = 2;

/**

* 边框颜色

*/

private int mBorderColor = BORDER_COLOR;

/**

* 边框宽度

*/

private int mBorderWidth = BORDER_WIDTH;

/**

* 绘制的高度,百分比。0表示内有高度,1表示全部高度

*/

private float mPrecent = 0.5f;

/**

* 形状枚举,暂时只支持矩形和圆形,可扩展

*/

public enum ShowShape {

RECT

}

/**

* 形状默认矩形

*/

private ShowShape mShape = ShowShape.RECT;

/**

* 默认两次重绘之间间隔的时间,5毫秒

*/

private final int DEFAULT_TIME = 5;

/**

* 两次重绘之间间隔的时间,毫秒。

*/

private int mTime = DEFAULT_TIME;

/**

* 设置两次重绘之间的间隔时间,毫秒

*

* @param time

* @return

*/

public WaveView setTime(int time) {

this.mTime = time;

return this;

}

/**

* 波浪1画笔

*/

private Paint mWavePaint1;

/**

* 边框画笔

*/

private Paint mBorderPaint;

/**

* 文字画笔

*/

private Paint mTextPaint;

/**

* 波浪1路径

*/

private Path mWavePath1;

/**

* 定义数字格式转行类

*/

private DecimalFormat mFormat;

/**

* 控件的宽度

*/

private int mWidth;

/**

* 控件的高度

*/

private int mHeight;

/**

* 水位上升时不断变化的 y 坐标

*/

private float mChangeY;

/**

* 水位最终的高度,通过控件的高度和百分比计算出来

*/

private float mFinalY;

/**

* 波峰的个数

*/

private int mWaveCount = 8;

/**

* 重置标记,开始为重置状态

*/

private boolean isReset = true;

/**

* 当前百分比

*/

private float mCurrentPrecent = 0.0f;

/**

* 重绘值波峰移动距离的和

*/

private int mMoveSum1;

/**

* 能够绘制标记位,开始不能绘制

*/

private boolean invalidateFlag = false;

/**

* 百分比改变监听

*/

private PrecentChangeListener mPrecentChangeListener;

/**

* 百分比改变监听接口

*/

public interface PrecentChangeListener {

/**

* 百分比发生改变时调用的方法

*

* @param precent 当前的百分比,格式 0.00 范围 [0.00 , 1.00]

*/

void precentChange(double precent);

}

public WaveView(Context context) {

this(context, null);

}

public WaveView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initAttrs(context, attrs); // 获取布局文件中dingy9i的属性

init();

}

//获取布局中的初始属性

private void initAttrs(Context context, AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaveView);

mWaveLenght1 = typedArray.getInteger(R.styleable.WaveView_wave1Length, WAVE_LENGTH1);

mWaveHeight1 = typedArray.getInteger(R.styleable.WaveView_wave1Height, WAVE_HEIGHT1);

mWaveColor1 = typedArray.getColor(R.styleable.WaveView_wave1Color, WAVE_COLOR1);

mOffset1 = typedArray.getInteger(R.styleable.WaveView_wave1Offset, WAVE_OFFSET1);

mBorderWidth = typedArray.getDimensionPixelSize(R.styleable.WaveView_borderWidth, BORDER_WIDTH);

mBorderColor = typedArray.getColor(R.styleable.WaveView_borderColor, BORDER_COLOR);

mTime = typedArray.getInteger(R.styleable.WaveView_intervalTime, DEFAULT_TIME);

mPrecent = typedArray.getFloat(R.styleable.WaveView_precent, 0.5f);

/**

* 绘制的高度,百分比。0表示内有高度,1表示全部高度

*/

int shapeValue = typedArray.getInteger(R.styleable.WaveView_showShape, 0);

mShape = ShowShape.RECT;

typedArray.recycle();

}

private void init() {

mWavePaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);

mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mWavePath1 = new Path();

mWavePaint1.setColor(mWaveColor1);

mWavePaint1.setStyle(Paint.Style.FILL);

mBorderPaint.setColor(mBorderColor);

mBorderPaint.setStrokeWidth(mBorderWidth);

mBorderPaint.setStyle(Paint.Style.STROKE);

mTextPaint.setColor(mTextColor);

mTextPaint.setTextSize(mTextSize);

// 定义数字显示个格式

mFormat = new DecimalFormat("###,###,##0.00");

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mWidth = w;

mHeight = h;

mChangeY = mHeight;

// 计算波峰个数,为了实现移动效果,保证至少绘制两个波峰

mFinalY = (1 - mPrecent) * mHeight; // 计算水位最终高度

}

@Override

protected void onDraw(Canvas canvas) {

mWavePath1.reset();

if (mBorderWidth > 0) {

// 边框大于0,表示需要绘制边框

if(mShape == ShowShape.RECT) {

canvas.drawRect(0, 0, mWidth, mHeight, mBorderPaint);

}

}

mWavePath1.moveTo(-mWaveLenght1, mChangeY);

if (!isReset) { // 判断重置标记

// 利用贝塞尔曲线绘制波浪

for (int i = 0; i < mWaveCount; i++) {

// 绘制波浪1的曲线

mWavePath1.quadTo((-mWaveLenght1 * 3 / 4) + (i * mWaveLenght1) + mMoveSum1, mChangeY + mWaveHeight1, (-mWaveLenght1 / 2) + (i * mWaveLenght1) + mMoveSum1, mChangeY);

mWavePath1.quadTo((-mWaveLenght1 * 1 / 4) + (i * mWaveLenght1) + mMoveSum1, mChangeY - mWaveHeight1, (i * mWaveLenght1) + mMoveSum1, mChangeY);

}

// 不断改变高度,实现逐渐水位逐渐上涨效果

mChangeY -= 1;

if (mChangeY < mFinalY) mChangeY = mFinalY;

// 波峰1往右移动,波峰2往左移动

mMoveSum1 += mOffset1;

if (mMoveSum1 >= mWaveLenght1) mMoveSum1 = 0;

// 填充矩形,让上涨之后的水位下面填充颜色

mWavePath1.lineTo(mWidth, mHeight);

mWavePath1.lineTo(0, mHeight);

mWavePath1.close();

canvas.drawPath(mWavePath1, mWavePaint1);

} else {

// 是重置

canvas.drawColor(Color.TRANSPARENT);

}

// 计算当前的百分比

mCurrentPrecent = 1 - mChangeY / mHeight;

// 格式化数字格式

String format1 = mFormat.format(mCurrentPrecent);

// 绘制文字,将百分比绘制到界面。此处用的是 "50%" 的形式,可以根据需求改变格式

double parseDouble = Double.parseDouble(format1);

canvas.drawText((int) (parseDouble * 100) + " %", (mWidth - mTextPaint.measureText(format1)) / 2, mHeight / 5, mTextPaint);

// 监听对象不为null并且没有达到设置高度时,调用监听方法

if (mPrecentChangeListener != null && mChangeY != mFinalY) {

mPrecentChangeListener.precentChange(parseDouble);

}

//高度到达设置高度

if (mChangeY == mFinalY){

canvas.drawColor(ContextCompat.getColor(getContext(), R.color.bowencolor));

}

// 判断绘制标记

if (invalidateFlag) postInvalidateDelayed(mTime);

}

/**

* 设置边框宽度

*

* @param borderWidth

* @return

*/

public WaveView setBorderWidth(int borderWidth) {

this.mBorderWidth = borderWidth;

return this;

}

/**

* 设置波浪1颜色

*

* @param waveColor1

* @return

*/

public WaveView setWaveColor1(int waveColor1) {

this.mWaveColor1 = waveColor1;

return this;

}

/**

* 设置边框颜色

*

* @param borderColor

* @return

*/

public WaveView setBorderColor(int borderColor) {

this.mBorderColor = borderColor;

return this;

}

/**

* 设置文字颜色

*

* @param textColor

* @return

*/

public WaveView setTextColor(int textColor) {

this.mTextColor = textColor;

return this;

}

/**

* 设置百分比

*

* @param precent

* @return

*/

public WaveView setPrecent(float precent) {

this.mPrecent = precent;

return this;

}

/**

* 设置文字大小

*

* @param textSize

* @return

*/

public WaveView setTextSize(int textSize) {

this.mTextSize = textSize;

return this;

}

/**

* 设置当前显示形状

*

* @param shape

* @return

*/

public WaveView setShape(ShowShape shape) {

this.mShape = shape;

return this;

}

/**

* 开始

*/

public void start() {

invalidateFlag = true;

isReset = false;

postInvalidateDelayed(mTime);

}

/**

* 暂停

*/

public void stop() {

invalidateFlag = false;

isReset = false;

}

/**

* 重置

*/

public void reset() {

invalidateFlag = false;

isReset = true;

mChangeY = mHeight;

postInvalidate();

}

}

2.attrs

3.布局

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.example.wh.myapplication.MainActivity">

android:id="@+id/waveview1"

android:layout_width="200dp"

android:layout_height="200dp" />

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginTop="30dp"

android:orientation="horizontal">

android:id="@+id/bt_start"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="开始"/>

android:id="@+id/bt_stop"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="暂停"/>

android:id="@+id/bt_reset"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="重置"/>

4.MainActivity

package com.example.wh.myapplication;

import android.graphics.Color;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private WaveView waveview1;

private Button btStart;

private Button btStop;

private Button btReset;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

waveview1 = (WaveView) findViewById(R.id.waveview1);

btStart = (Button) findViewById(R.id.bt_start);

btStop = (Button) findViewById(R.id.bt_stop);

btReset = (Button) findViewById(R.id.bt_reset);

// 代码设置相关属性

waveview1.setBorderWidth(2)

.setWaveColor1(Color.RED)

.setBorderColor(Color.GREEN)

.setTextColor(Color.BLUE)

.setShape(WaveView.ShowShape.RECT)

.setTextSize(36)

.setPrecent(1f)//设置水波纹的百分比

.setTime(2);

btStart.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

waveview1.start();

}

});

btStop.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

waveview1.stop();

}

});

btReset.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

waveview1.reset();

}

});

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android 海浪动画,android自定义波浪加载动画的实现代码相关推荐

  1. Android 自定义进度加载动画

    偶尔浏览一个android开发网站,发现进度加载动画比较不错,觉得挺有意思 就自己参考了下自己做了一个进度加载动画 效果图如下: 首选来看自定义动画 package com.itzb.paintdem ...

  2. android 仿 动画,Android动画 - 仿58同城加载动画

    Android动画 - 仿58同城加载动画 效果图 58LoadingView.gif 分析动画 首先分析动画,如上图所示: 动画分为三部分,分别为上方跳动部分,中间阴影部分,和下方文字部分. 上方跳 ...

  3. android 自定义图片加载动画效果,Android自定义加载动画-感染体

    Android自定义动画系列七,今天来分享第七个自定义Loading动画(InfectionBallBuilder),看上去感觉有种病毒源被感染的感觉,所以名字就叫感染体,这个动画做出来的效果,我不怎 ...

  4. Android仿英雄联盟/斗鱼波形加载动画

    先上效果图: 实现原理: 通过自定义一个布局,继承自LinearLayout,然后在这个布局当中添加5条竖线,也即是5个矩形View:通过对这5个View分别加入属性动画,即可实现.动画是一个组合动画 ...

  5. Android 抖音爱心动画,Android动画 - 仿抖音加载动画

    在地铁中刷抖音,由于网络不通畅加载很慢,抖音会加载一个加载动画,感觉很有意思,于是分析了一下,自己写了Demo,实现效果. 效果图 分析动画 首先分析动画,初始状态是由两个相切的圆形图案组成. 将动画 ...

  6. vue element-ui Loading加载事件的使用以及自定义Loading加载动画

    elemen-ui官方使用 <el-tablev-loading="loading"element-loading-text="拼命加载中"element ...

  7. 自定义动画(仿Win10加载动画)——优化

    此为前文章写的仿Win10加载动画的优化版 源代码 已更新到github 优化分析 原生 自定义高仿(v1版) 一直觉得自己写的与原生的有差别,经过仔细对比观察,发现: 原生的圆点出发位置不是都在底部 ...

  8. 微信小程序自定义loading加载动画(2)

    1.实现效果 2.实现原理 animation 3.实现代码 <view class="loading-row"><view class="loadin ...

  9. flutter 页面加载动画_Flutter撸一个加载动画

    目标 先上效果图: 目标.gif 是不是感觉跟ProgressDialog创建出来的一毛一样!!! 实现思路 使用对话框 首先想到的是用Flutter自带的SimpleDialog对话框,但是想到这玩 ...

最新文章

  1. 去掉button按钮左右两边的留白
  2. wxWidgets:wxMouseEvent类用法
  3. centos 7 No package python-dev available
  4. 严格地说来的zhajinhuagame
  5. 什么时候找到HAVE_CONFIG_H的定义啊
  6. IOS炫酷的引导界面
  7. java发送请求_Java发送Http请求
  8. android全局livedata,Android 使用ViewModel,LiveData高效、简
  9. matlab rand函数
  10. mysql loader_Mysql的批量导入类 MySqlBulkLoader
  11. 包括8个html的网页设计作品,8个超棒的HTML5网站设计欣赏
  12. 详解24个经典股票技术指标(二)
  13. 微信公众号自动回复如何添加超链接
  14. 贵大和杭电计算机科学与技术,【20考研】计算机考研专业课变动汇总
  15. 月销13485台的理想ONE,到底做对了哪些事儿?
  16. 技术动态 | 不确定性知识图谱的表示和推理
  17. 举个栗子~Tableau 技巧(225):制作事件节点时间轴
  18. spark.reducer.maxReqsInFlight和spark.reducer.maxBlocksInFlightPerAddress
  19. 基于微信小程序云开(统计学生信息并导出excel)2.0版
  20. 场效应三极管及其放大电路(1)MOSFET详解

热门文章

  1. 复制百度文库的文字加什么后缀_后缀大全
  2. validation engine
  3. 『机器学习』了解分类,回归,聚类算法,实现小规模预测
  4. 【Python学习笔记】b站@同济子豪兄 用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类
  5. Mysql常见的日期、时间函数
  6. 数据库关系模式的范式总结
  7. Java -- 日期对象转字符串、字符串转日期
  8. 2019年广东工业大学腾讯杯新生程序设计竞赛(同步赛)F-失踪的玫瑰
  9. icmp回复报文_ICMP报文
  10. 国庆特惠|戴尔高性能商用电脑低至¥1919+500元携程卡