Android实现水波纹特效
程序员文章站
2022-06-23 14:58:14
最近需要做个类似于水波纹动画的效果,思考了一下不需要ui切个动态图,android原生的技术利用动画或者自定义控件都可以实现,下面上个图类似于这样的效果
下面请看第一...
最近需要做个类似于水波纹动画的效果,思考了一下不需要ui切个动态图,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实现水波纹特效
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 开篇——从程序员到IT经理