欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义View实现波浪动画

程序员文章站 2022-03-21 22:21:07
本文实例为大家分享了android自定义view实现波浪动画的具体代码,供大家参考,具体内容如下效果演示代码调用与实现效果xml中调用

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

效果演示

代码调用与实现效果

xml中调用

<developer.shivam.waveview.wave
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:amplitude="100"
  app:quadrant="0.5"
  app:speed="0.15"/>

Android自定义View实现波浪动画

实现原理

属性配置

attrs.xml文件中,进行属性配置

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="wave">
  <!--波浪颜色-->
  <attr name="wavecolor" format="color"/>
  <!--波浪背景颜色-->
  <attr name="wavebackgroundcolor" format="color"/>
  <!--波浪速度-->
  <attr name="speed" format="float"/>
  <!--正弦曲线相关-->
  <!--波浪振幅-->
  <attr name="amplitude" format="integer"/>
  <!--波浪相对于控件的位置-->
  <attr name="quadrant" format="float"/>
  <!--波浪的频率-->
  <attr name="frequency" format="float"/>
 </declare-styleable>
</resources>

获取属性,同时对属性赋默认值

final typedarray array = context.obtainstyledattributes(set, r.styleable.wave);
  mspeed = array.getfloat(r.styleable.wave_speed, default_speed);
  mwavecolor = array.getcolor(r.styleable.wave_wavecolor, default_wave_color);
  mwavebkcolor = array.getcolor(r.styleable.wave_wavebackgroundcolor, default_wave_bk_color);
  mamplitude = array.getint(r.styleable.wave_amplitude, default_amplitude);
  mquadrant = array.getfloat(r.styleable.wave_quadrant, default_quadrant);
  mfrequency = array.getfloat(r.styleable.wave_frequency, default_frequency);
  array.recycle();

绘制波浪

在ondraw()中使用canvas进行绘制即可,这里需要注意的正弦曲线的绘制.

正弦曲线(y=asin(ωx+φ)+k)的一些参数如下:

a——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2。
(ωx+φ)——相位,反映变量y所处的状态。
φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动。
k——偏距,反映在坐标系上则为图像的上移或下移。
ω——角速度, 控制正弦周期(单位角度内震动的次数)。

ondraw中的代码:

@override
protected void ondraw(canvas canvas) {
 super.ondraw(canvas);
 final int width = getwidth();
 final int height = getheight();

 final int waveheight = (int) (getheight() * mquadrant);
 // 绘制背景
 canvas.drawcolor(mwavebkcolor);
 mwavepath.moveto(0, height);
 mwavepath.lineto(0, waveheight);
 for (int i = 1; i <= width; i++) {
  // 绘制正弦曲线 y = a sin(ωt+ ρ) = a sin(2πft + ρ)
  final float y = (float) (waveheight + mamplitude * math.sin(2 * math.pi * i * mfrequency + mshift));
  mwavepath.lineto(i, y);
 }
 // 将曲线闭合
 mwavepath.lineto(width, height);
 canvas.drawpath(mwavepath, mwavepaint);
}

波浪动画

这时波浪应该已经绘制完成了,下面使用handler中的周期任务实现动画效果.

// 创建一个周期任务,它的职责是改变正弦曲线的偏移量
 final class waveanimation implements runnable {

  @override
  public void run() {
   mwavepath.reset();
   mshift += mspeed;
   invalidate();
   wave.this.postdelayed(this, default_period);
  }
 }

在view被创建的时候让它进行执行

// 开始波浪动画
postdelayed(new waveanimation(), default_period);

完整代码

public class wave extends view {

 // 默认属性值
 private static final int default_amplitude = 200;
 private static final int default_period = 16;
 private static final float default_speed = .1f;
 private static final float default_quadrant = .33f;
 private static final float default_frequency = 1f / 360f;
 private static final int default_wave_color = color.parsecolor("#64b5f6");
 private static final int default_wave_bk_color = color.parsecolor("#eeeeee");

 @suppresswarnings("fieldcanbelocal")
 @colorint
 private int mwavecolor;
 @colorint
 private int mwavebkcolor;
 // 振幅
 private int mamplitude;
 // 波浪位于view的位置
 private float mquadrant;
 // 波浪的频率,这个值越大,波浪越密集
 private float mfrequency;

 // 速度
 private float mspeed;
 private float mshift;

 private final paint mwavepaint = new paint(paint.anti_alias_flag);
 private final path mwavepath = new path();



 public wave(context context) {
  this(context, null);
 }

 public wave(context context, attributeset attrs) {
  this(context, attrs, 0);
 }

 public wave(context context, attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  init(context, attrs);
 }

 private void init(context context, attributeset set) {
  final typedarray array = context.obtainstyledattributes(set, r.styleable.wave);
  mspeed = array.getfloat(r.styleable.wave_speed, default_speed);
  mwavecolor = array.getcolor(r.styleable.wave_wavecolor, default_wave_color);
  mwavebkcolor = array.getcolor(r.styleable.wave_wavebackgroundcolor, default_wave_bk_color);
  mamplitude = array.getint(r.styleable.wave_amplitude, default_amplitude);
  mquadrant = array.getfloat(r.styleable.wave_quadrant, default_quadrant);
  mfrequency = array.getfloat(r.styleable.wave_frequency, default_frequency);
  array.recycle();

  mwavepaint.setstrokewidth(2);
  mwavepaint.setcolor(mwavecolor);

  // 开始波浪动画
  postdelayed(new waveanimation(), default_period);
 }


 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);
  final int width = getwidth();
  final int height = getheight();

  final int waveheight = (int) (getheight() * mquadrant);
  // 绘制背景
  canvas.drawcolor(mwavebkcolor);
  mwavepath.moveto(0, height);
  mwavepath.lineto(0, waveheight);
  for (int i = 1; i <= width; i++) {
   // 绘制正弦曲线 y = a sin(ωt+ ρ) = a sin(2πft + ρ)
   final float y = (float) (waveheight + mamplitude * math.sin(2 * math.pi * i * mfrequency + mshift));
   mwavepath.lineto(i, y);
  }
  // 将曲线闭合
  mwavepath.lineto(width, height);
  canvas.drawpath(mwavepath, mwavepaint);
 }


 final class waveanimation implements runnable {

  @override
  public void run() {
   mwavepath.reset();
   mshift += mspeed;
   invalidate();
   wave.this.postdelayed(this, default_period);
  }
 }
}

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

相关标签: Android 波浪