水波纹效果

创建自定义View
1、针对所有水波纹圆圈共享参数的问题:

方法就是新建一个内部类Wave,用于存放每个圆圈的参数,每一个圆圈都对应一个Wave对象,然后在onDraw方法里面,同时重绘所有的圆圈视图;
那么这里就还需要一个List集合waveList,用于存放所有的wave对象,
方便遍历。

2、针对handler.sendEmptyMessageDelayed方法在后续点击的时候不断被调用,导致刷新越来越快的问题。

这里可以设置一个成员变量 boolean isStart;来标志是不是第一次按下;因为我们在第一次按下的时候,肯定是希望开始定时刷新,调用handler.sendEmptyMessageDelayed,让圆环的状态不断变化。但是对于之后的点击,我们其实只希望它立刻被刷新一次,并被加入到waveList集合中,而并不需要发送一个handler的信息来调用handler.sendEmptyMessageDelayed。所以在一开始的时候我们将其设置为true,而在第一次点击时候将其设置为false,那么在什么时候将其设置为false呢,这里牵涉到第三个问题:

3、对于waveList集合而言,如果一直点击往集合里面添加Wave对象,那么无疑会让这个集合越来越大,这个是我们不希望看到的。

我们希望在圆环的透明度值alpha变为0,也就是完全透明的时候,让其从waveList中remove掉,让其能被垃圾回收回收掉,这样如果
点击几个点之后停止,点都会自动消失(alpha值减到0),那么对应的Wave对象也会从waveList被移除,waveList的大小也会变成0,这个时候我们就可以停止handler.sendEmptyMessageDelayed方法继续被调用,同时可以将isStart重新设为true。那么isStart何时设为false呢?我们可以在flushState刷新状态的时候将其设为false,因为刷新状态的时候表明第一次点击已经按下了。然后在onTouchEvent方法的ACTION_DWON条件下,如果isStart为true才发送handler的消息,这代表第一次点击,之后再点击也不会发送而只是将wave对象添加到waveList中,因为第一次的时候调用flushState已经将isStart置为false了。**

package com.example.test_wather;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class WaterView extends View {

    /**
     * 波形的List
     */
    private ArrayList<Wave> waveList = new ArrayList<Wave>();

    /**
     * 最大的不透明度,完全不透明
     */
    private static final int MAX_ALPHA = 255;

    protected static final int FLUSH_ALL = -1;

    private boolean isStart = true;

    /**
     * 设置颜色
     */
    private int[] colors = new int[] { Color.RED, Color.GREEN, Color.BLUE,
            Color.YELLOW, Color.LTGRAY, Color.WHITE };

    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 0:

                // 刷新
                flushState();

                // 重置画布

                invalidate();

                if (waveList != null && waveList.size() > 0) {
                    handler.sendEmptyMessageDelayed(0, 50);
                }

                break;

            default:
                break;
            }
        }

    };

    /*
     * 1、两参构造函数
     */
    public WaterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public WaterView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public WaterView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    /**
     * onMeasure方法,确定控件大小,这里使用默认的
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    /**
     * 画出需要的图形的方法,这个方法比较关键
     */
    protected void onDraw(Canvas canvas) {
        // 重绘所有圆环
        for (int i = 0; i < waveList.size(); i++) {
            Wave wave = waveList.get(i);
            canvas.drawCircle(wave.xDown, wave.yDown, wave.radius, wave.paint);
        }

    }

    /**
     * 初始化paint
     */
    private Paint initPaint(int alpha, float width) {
        /*
         * 新建一个画笔
         */
        Paint paint = new Paint();

        // 消除据齿
        paint.setAntiAlias(true);

        // 设置圆环厚度
        paint.setStrokeWidth(width);

        // 设置是环形方式绘制
        paint.setStyle(Paint.Style.STROKE);

        // 设置透明度
        paint.setAlpha(alpha);

        // 设置颜色
        paint.setColor(colors[(int) (Math.random() * (colors.length - 1))]);
        return paint;
    }

    /**
     * 刷新状态
     */
    private void flushState() {
        for (int i = 0; i < waveList.size(); i++) {
            Wave wave = waveList.get(i);
            if (isStart == false && wave.alpha == 0) {
                waveList.remove(i);
                wave.paint = null;
                wave = null;
                continue;
            } else if (isStart == true) {
                isStart = false;
            }
            wave.radius += 15;
            wave.alpha -= 10;
            if (wave.alpha <= 10) {
                wave.alpha = 0;
            }
            wave.width = wave.radius / 4;
            wave.paint.setAlpha(wave.alpha);
            wave.paint.setStrokeWidth(wave.width);
        }

    }

    @Override
    /**
     * 触摸事件的方法
     */
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
        case MotionEvent.ACTION_DOWN:
            Wave wave = new Wave();
            wave.radius = 0;
            wave.alpha = MAX_ALPHA;
            wave.width = wave.radius / 4;
            wave.xDown = (int) event.getX();
            wave.yDown = (int) event.getY();

            wave.paint = initPaint(wave.alpha, wave.width);

            if (waveList.size() == 0) {
                isStart = true;
            }
            waveList.add(wave);

            if (isStart) {
                handler.sendEmptyMessage(0);
            }

            break;
        case MotionEvent.ACTION_UP:

            break;

        default:
            break;
        }

        return true;
    }

    private class Wave {

        /**
         * 用来表示圆环的半径
         */
        float radius;
        Paint paint;
        /**
         * 按下的时候x坐标
         */
        int xDown;
        /**
         * 按下的时候y的坐标
         */
        int yDown;
        float width;
        int alpha;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值