Android开发之2两种方式实现类似水波扩散效果
白羽 2018-06-27 来源 :网络 阅读 1032 评论 0

摘要:本文将带你了解Android开发之2两种方式实现类似水波扩散效果,希望本文对大家学Android有所帮助。


两种方式实现类似水波扩散效果

1. 自定义view实现

2. 动画实现

 Android开发之2两种方式实现类似水波扩散效果

自定义view实现

思路分析:通过canvas画圆,每次改变圆半径和透明度,当半径达到一定程度,再次从中心开始绘圆,达到不同层级的效果,通过不断绘制达到view扩散效果

private Paint centerPaint; //中心圆paintprivate int radius = 100; //中心圆半径private Paint spreadPaint; //扩散圆paintprivate float centerX;//圆心xprivate float centerY;//圆心yprivate 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);

}

确定圆心位置

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {

    super.onSizeChanged(w, h, oldw, oldh);

    //圆心位置

    centerX = w / 2;

    centerY = h / 2;

}

自定义view的绘制

 

@Overrideprotected 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="//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>

中间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);

}

效果图

Android开发之2两种方式实现类似水波扩散效果

相比较而言,自定义view的效果更好点,动画实现起来更方便点。

两种方式实现的扩散效果介绍完毕,具体项目里还是要按需变动的。

 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程