笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述Android 两种方式实现类似水波扩散效果相关的知识,希望能为你提供帮助。
原文链接 https://mp.weixin.qq.com/s/M19tp_ShOO6esKdozi7Nlg两种方式实现类似水波扩散效果,先上图为敬
- 自定义view实现
- 动画实现
文章图片
自定义view实现思路分析:通过canvas画圆,每次改变圆半径和透明度,当半径达到一定程度,再次从中心开始绘圆,达到不同层级的效果,通过不断绘制达到view扩散效果
private Paint centerPaint;
//中心圆paint
private int radius = 100;
//中心圆半径
private Paint spreadPaint;
//扩散圆paint
private float centerX;
//圆心x
private float centerY;
//圆心y
private int distance = 5;
//每次圆递增间距
private int maxRadius = 80;
//最大圆半径
private int delayMilliseconds = 33;
//扩散延迟间隔,越大扩散越慢
private List<
Integer>
spreadRadius = new ArrayList<
>
();
//扩散圆层级数,元素为扩散的距离
private List<
Integer>
alphas = new ArrayList<
>
();
//对应每层圆的透明度
style文件里自定义属性
<
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>
初始化
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);
}
确定圆心位置
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//圆心位置
centerX = w / 2;
centerY = h / 2;
}
自定义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);
//TODO 可以在中间圆绘制文字或者图片//延迟更新,达到扩散视觉差效果
postInvalidateDelayed(delayMilliseconds);
}
xml样式
<
com.airsaid.diffuseview.widget.SpreadView
android:id="@+id/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="100"
app:spread_spread_color="@color/colorAccent" />
效果图
文章图片
中心圆处可以自定义写文字,画图片等等...
动画实现思路分析:通过动画实现,
imageView
不停做动画缩放+渐变最中心的
imageView
保持不变中间一层
imageView
从原始放大到1.4倍,同时从不透明变为半透明最外层的
imageView
从1.4倍放大到1.8倍,同时从半透明变为全透明利用shape画一个圆,作为动画基础视图
<
?xml version="1.0" encoding="utf-8"?>
<
shape xmlns:android="http://schemas.android.com/apk/res/android">
<
corners android:radius="65dp"/>
<
solid android:color="@color/colorAccent"/>
<
/shape>
布局视图
<
FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<
!--中心imageView-->
<
ImageView
android:id="@+id/iv_wave"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
<
!--中间的imageView-->
<
ImageView
android:id="@+id/iv_wave_1"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
<
!--最外层imageView-->
<
ImageView
android:id="@+id/iv_wave_2"
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_gravity="center"
android:background="@drawable/shape_circle" />
<
/FrameLayout>
【Android 两种方式实现类似水波扩散效果】中间
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);
}
最外层
imageView
的动画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);
}
效果图
文章图片
相比较而言,自定义view的效果更好点,动画实现起来更方便点。
两种方式实现的扩散效果介绍完毕,具体项目里还是要按需变动的。
欢迎关注我的博客:https://blog.manjiexiang.cn/
同时欢迎关注微信公众号
文章图片
推荐阅读
- Entity FrameWork和Dapper的使用
- AndroidManifest 配置主活动
- android studio 模拟器不能使用的解决方案
- 英语背单词app
- Android_(控件)使用自定义控件在屏幕中绘制一条虚线
- UWP(使用Composition实现类似安卓的水波纹Ripple效果)
- AndroidManifest.xml
- Android应用架构分析
- 小度wifi官网地址介绍:百度小度WiFi预订官网