android自定义波浪加载动画的实现代码
程序员文章站
2023-10-29 12:47:40
本文实例为大家分享了android自定义波浪加载动画的具体代码,供大家参考,具体内容如下
效果图
1.自定义控件 waveview
package com...
本文实例为大家分享了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
<?xml version="1.0" encoding="utf-8"?> <resources> <!--自定义水波纹效果属性--> <declare-styleable name="waveview"> <!--波浪1的长度、高度、颜色和每次重绘的偏移量--> <attr name="wave1length" format="integer" /> <attr name="wave1height" format="integer" /> <attr name="wave1color" format="color" /> <attr name="wave1offset" format="integer" /> <!--边框的宽度和颜色--> <attr name="borderwidth" format="dimension" /> <attr name="bordercolor" format="color" /> <!--文字的大小和颜色--> <attr name="textcolor" format="color" /> <attr name="textsize" format="dimension" /> <!--水位高度的百分比--> <attr name="precent" format="float" /> <!--两次重绘的间隔时间--> <attr name="intervaltime" format="integer" /> <!--控件的显示形状,rect矩形、circle圆形--> <attr name="showshape" format="enum"> <enum name="rect" value="0" /> <enum name="circle" value="1" /> </attr> </declare-styleable> </resources>
3.布局
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" 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"> <com.example.wh.myapplication.waveview android:id="@+id/waveview1" android:layout_width="200dp" android:layout_height="200dp" /> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="30dp" android:orientation="horizontal"> <button android:id="@+id/bt_start" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="开始"/> <button android:id="@+id/bt_stop" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="暂停"/> <button android:id="@+id/bt_reset" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="重置"/> </linearlayout> </linearlayout>
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(); } }); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 韭菜与啤酒,可以一起吃吗
下一篇: js日历控件(可精确到分钟)