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

Android实现水波纹特效

程序员文章站 2022-03-23 13:39:55
最近需要做个类似于水波纹动画的效果,思考了一下不需要ui切个动态图,android原生的技术利用动画或者自定义控件都可以实现,下面上个图类似于这样的效果 下面请看第一...

最近需要做个类似于水波纹动画的效果,思考了一下不需要ui切个动态图,android原生的技术利用动画或者自定义控件都可以实现,下面上个图类似于这样的效果

Android实现水波纹特效

下面请看第一种动画实现,这种方式较为简单些,就是利用3个imageview不断地做缩放和渐变的动画。

布局文件定义一下

<relativelayout
  android:id="@+id/rl"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  android:layout_marginbottom="160dp">
  <!--中心imageview-->
  <imageview
    android:id="@+id/iv_wave"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_centerhorizontal="true"
    android:background="@drawable/shape_circle" />
  <!--中间的imageview-->
  <imageview
    android:id="@+id/iv_wave_1"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_centerhorizontal="true"
    android:background="@drawable/shape_circle" />
  <!--最外层imageview-->
  <imageview
    android:id="@+id/iv_wave_2"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_centerhorizontal="true"
    android:background="@drawable/shape_circle" />
</relativelayout>

接下来中间的imageview保持不变,通过操作另外两个imageview达到效果

private void setanim1() {
  animationset as = new animationset(true);
  //缩放动画,以中心从原始放大到1.4倍
  scaleanimation scaleanimation = new scaleanimation(1.0f, 1.4f, 1.0f, 1.4f,
      scaleanimation.relative_to_self, 0.5f,
      scaleanimation.relative_to_self, 0.5f);
  //渐变动画
  alphaanimation alphaanimation = new alphaanimation(1.0f, 0.5f);
  scaleanimation.setduration(800);
  scaleanimation.setrepeatcount(animation.infinite);
  alphaanimation.setrepeatcount(animation.infinite);
  as.setduration(800);
  as.addanimation(scaleanimation);
  as.addanimation(alphaanimation);
  iv1.startanimation(as);
}
private void setanim2() {
  animationset as = new animationset(true);
  //缩放动画,以中心从1.4倍放大到1.8倍
  scaleanimation scaleanimation = new scaleanimation(1.4f, 1.8f, 1.4f, 1.8f,
      scaleanimation.relative_to_self, 0.5f,
      scaleanimation.relative_to_self, 0.5f);
  //渐变动画
  alphaanimation alphaanimation = new alphaanimation(0.5f, 0.1f);
  scaleanimation.setduration(800);
  scaleanimation.setrepeatcount(animation.infinite);
  alphaanimation.setrepeatcount(animation.infinite);
  as.setduration(800);
  as.addanimation(scaleanimation);
  as.addanimation(alphaanimation);
  iv2.startanimation(as);
}

接下来就是第二种自定义动画实现

首先定义style文件自定义属性--在values下创建attrs.xml文件

<declare-styleable name="spreadview">
  <!--中心圆颜色-->
  <attr name="spread_center_color" format="color" />
  <!--中心圆半径-->
  <attr name="spread_radius" format="integer" />
  <!--扩散圆颜色-->
  <attr name="spread_spread_color" format="color" />
  <!--扩散间距-->
  <attr name="spread_distance" format="integer" />
  <!--扩散最大半径-->
  <attr name="spread_max_radius" format="integer" />
  <!--扩散延迟间隔-->
  <attr name="spread_delay_milliseconds" format="integer" />
</declare-styleable>

接下来创建spreadview继承view,初始化构造方法

public spreadview(context context) {
  this(context,null,0);
}
 
public spreadview(context context, @nullable attributeset attrs) {
  this(context, attrs,0);
}
 
public spreadview(context context, @nullable attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  typedarray a = context.obtainstyledattributes(attrs, r.styleable.spreadview, defstyleattr, 0);
  radius = a.getint(r.styleable.spreadview_spread_radius, radius);
  maxradius = a.getint(r.styleable.spreadview_spread_max_radius, maxradius);
  int centercolor = a.getcolor(r.styleable.spreadview_spread_center_color, contextcompat.getcolor(context, r.color.coloraccent));
  int spreadcolor = a.getcolor(r.styleable.spreadview_spread_spread_color, contextcompat.getcolor(context, r.color.coloraccent));
  distance = a.getint(r.styleable.spreadview_spread_distance, distance);
  a.recycle();
  centerpaint = new paint();
  centerpaint.setcolor(centercolor);
  centerpaint.setantialias(true);
  //最开始不透明且扩散距离为0
  alphas.add(255);
  spreadradius.add(0);
  spreadpaint = new paint();
  spreadpaint.setantialias(true);
  spreadpaint.setalpha(255);
  spreadpaint.setcolor(spreadcolor);
}

自定义view的绘制:

@override
protected void ondraw(canvas canvas) {
  super.ondraw(canvas);
  for (int i = 0; i < spreadradius.size(); i++) {
    int alpha = alphas.get(i);
    spreadpaint.setalpha(alpha);
    int width = spreadradius.get(i);
    //绘制扩散的圆
    canvas.drawcircle(centerx, centery, radius + width, spreadpaint);
    //每次扩散圆半径递增,圆透明度递减
    if (alpha > 0 && width < 300) {
      alpha = alpha - distance > 0 ? alpha - distance : 1;
      alphas.set(i, alpha);
      spreadradius.set(i, width + distance);
    }
  }
  //当最外层扩散圆半径达到最大半径时添加新扩散圆
  if (spreadradius.get(spreadradius.size() - 1) > maxradius) {
    spreadradius.add(0);
    alphas.add(255);
  }
  //超过8个扩散圆,删除最先绘制的圆,即最外层的圆
  if (spreadradius.size() >= 8) {
    alphas.remove(0);
    spreadradius.remove(0);
  }
  //中间的圆
  canvas.drawcircle(centerx, centery, radius, centerpaint);
  //延迟更新,达到扩散视觉差效果
  postinvalidatedelayed(delaymilliseconds);
}

最后在activity的布局文件中引用自定义属性:

<com.example.louliang.spread.spreadview
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  app:spread_center_color="@color/coloraccent"
  app:spread_delay_milliseconds="35"
  app:spread_distance="5"
  app:spread_max_radius="90"
  app:spread_radius="150"
  app:spread_spread_color="@color/coloraccent" />

以上两种方法就实现了水波纹的效果,下载完整的demo请点击链接,希望对大家有所帮助。

源码下载:android实现水波纹特效

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