自定义实现水波纹效果

package com.loaderman.mywave;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.loaderman.mywave.MainActivity">

    <com.loaderman.mywave.MyWave
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>

 

package com.loaderman.mywave;

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;

import java.util.ArrayList;

import static android.R.attr.radius;


public class MyWave extends View {

    private ArrayList<Wave> mList = new ArrayList<>();

    private int[] mColors = new int[]{Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN};

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            flushData();
            invalidate();

            if (!mList.isEmpty()) {//屏幕还有圆环显示, 就需要继续循环
                mHandler.sendEmptyMessageDelayed(0, 50);
            }
        }
    };

    public MyWave(Context context) {
        super(context);
    }

    public MyWave(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyWave(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void flushData() {
        //遍历集合, 修改所有对象的半径,宽度, 渐变
        //半径变大
        //宽度变大
        //颜色变淡
        ArrayList<Wave> killedList = new ArrayList<>();

        for (Wave wave : mList) {
            wave.radius += 5;
            wave.paint.setStrokeWidth(wave.radius / 3);
            int alpha = wave.paint.getAlpha();

            //如果圆环已经消失, 就需要从集合中移除, 避免OOM
            if (alpha == 0) {
                //mList.remove(wave);
                killedList.add(wave);
                continue;
            }

            alpha -= 8;
            if (alpha < 0) {
                alpha = 0;
            }

            wave.paint.setAlpha(alpha);
        }

        //移除待删除的圆环集合
        mList.removeAll(killedList);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                addPoint((int) event.getX(), (int) event.getY());

                break;

            default:
                break;
        }

        return true;//消费事件
    }

    //添加一个触摸点
    private void addPoint(int x, int y) {
        if (mList.isEmpty()) {
            addWave(x, y);
            //集合为空, 表示第一次触摸界面, 触发绘制圆环的机制
            mHandler.sendEmptyMessageDelayed(0, 50);
        } else {
            //确保两个相邻圆环的圆心位置保持一定距离
            //取出当前最后一个圆环
            Wave lastWave = mList.get(mList.size() - 1);
            if (Math.abs(lastWave.cx - x) > 10 || Math.abs(lastWave.cy - y) > 10) {
                addWave(x, y);
            }
        }
    }

    //添加波浪对象
    private void addWave(int x, int y) {
        Wave wave = new Wave();
        wave.cx = x;
        wave.cy = y;
        wave.radius = 0;

        Paint paint = new Paint();

        //随机颜色
        //Math.random();[0,1);
        int colorId = (int) (Math.random() * mColors.length);
        paint.setColor(mColors[colorId]);

        paint.setStyle(Paint.Style.STROKE);//空心
        paint.setAntiAlias(true);//去掉锯齿
        paint.setStrokeWidth(radius / 3);//设置圆环宽度, 为半径三分之一
        paint.setAlpha(255);//[0..255],设置透明度, 0表示完全透明

        wave.paint = paint;

        mList.add(wave);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制圆环
        for (Wave wave : mList) {
            canvas.drawCircle(wave.cx, wave.cy, wave.radius, wave.paint);
        }
    }

    //圆环对象
    class Wave {
        public Paint paint;
        public int cx;
        public int cy;
        public int radius;
    }
}

 效果图:



产生一个水波纹的实现

 

package com.loaderman.mywave;

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 SimpleWave extends View {
    private Paint paint;
    private int cx;
    private int cy;
    private int radius;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //半径变大
            //宽度变大
            //颜色变淡
            radius += 5;
            paint.setStrokeWidth(radius / 3);
            int alpha = paint.getAlpha();//当前透明度
            alpha -= 10;
            if (alpha < 0) {
                alpha = 0;
            }
            paint.setAlpha(alpha);
            invalidate();//重绘

            if (alpha > 0) {
                //如果圆环没有消失
                //继续发送消息, 形成循环
                mHandler.sendEmptyMessageDelayed(0, 50);
            }
        }
    };
    public SimpleWave(Context context) {
        this(context, null);
    }
    public SimpleWave(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }
    public SimpleWave(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    private void init() {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);//空心
        paint.setAntiAlias(true);//去掉锯齿
        paint.setStrokeWidth(radius / 3);//设置圆环宽度, 为半径三分之一
        paint.setAlpha(255);//[0..255],设置透明度, 0表示完全透明
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //产生一个水波纹
                cx = (int) event.getX();
                cy = (int) event.getY();
                //重新初始化画笔和半径
                init();
                radius = 0;
                mHandler.sendEmptyMessageDelayed(0, 50);
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制圆环: 参1,2: 圆心坐标; 参3:半径
        canvas.drawCircle(cx, cy, radius, paint);
    }
}

 

posted on 2017-03-07 14:43  LoaderMan  阅读(237)  评论(0编辑  收藏  举报

导航