天天看點

android自定義控件 水波紋效果

效果圖: 

android自定義控件 水波紋效果

這是今天我們要實作的一個效果:  一個自定義的VIEW .

要知道 我們畫圓需要重寫 父類的 onDraw(Canvas canvas) 方法, 用 canvas 來畫圓, 然而畫圓需要 cx,cy,radio,paint.(圓心x,圓心y,半徑,畫筆)..

首先我們要重寫 父類 onDraw()  和onTouchEvent()事件, 在onTouch 裡判斷 Action_DOWN 和 Action_MOVE, 記錄 X,Y點. (X,Y點就是圓心的坐标.)    還需要聲明一個集合, 用于存放點 然後實作裡面邏輯去動态重新整理圓點的 資訊狀态, 下面貼代碼...

public class WaterWaveEnergyView extends View {

    private int startX;
    private int startY;

    private Paint paint;

    private int paintWidth;

    private int alpha;

    private List<Wave> pointList;
    // 如果間隔小于10 那麼不畫圓
    private static final int POINT_SPACE = 10;
    // if pointList.size()>0  than true;
    private boolean isRunning = false;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            flushState();

            // notification refresh circle
            invalidate();
            // 動态重新整理
            if (isRunning) {
                handler.sendEmptyMessageDelayed(0, 50);
            }
        }
    };

    public WaterWaveEnergyView(Context context) {
        this(context, null);
    }

    public WaterWaveEnergyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WaterWaveEnergyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // init list
        pointList = new ArrayList<Wave>();
    }


    /**
     * refresh state
     */
    private void flushState() {
        for (int i = 0; i < pointList.size(); i++) {
            Wave w = pointList.get(i);

            alpha = w.p.getAlpha();
            //圓的透明度為0
            if (alpha == 0) {
                pointList.remove(i); //when transparency is 0,remove circlr  當透明度為0 移除圓
                continue;
            }
            paintWidth = w.r / 4;
            alpha -= 5;
            if (alpha < 5) {
                alpha = 0;
            }
            w.p.setAlpha(alpha);
            w.p.setStrokeWidth(paintWidth);
            w.r += 3;

        }

        if (pointList.size() == 0) {
            isRunning = false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                startX = (int) event.getX();
                startY = (int) event.getY();

                addPoint(startX, startY);

                break;

        }
        return true;
    }

    /**
     * stroage point
     *
     * @param startX
     * @param startY
     */
    private void addPoint(int startX, int startY) {
        // if list size is zero no need judge spacing
        if (pointList.size() == 0) {
            addPoint2(startX, startY);
            // first running
            isRunning = true;
            //send a message, notification refresh state and cirle發送消息 通知重新整理狀态,更新圓
            handler.sendEmptyMessage(0);
        } else {
            // determing wheter the spacing is satisfied
            // take out on one point
            Wave w = pointList.get(pointList.size() - 1);
            if (Math.abs(w.cx - startX) > POINT_SPACE
                    || Math.abs(w.cy - startY) > POINT_SPACE) {
                addPoint2(startX, startY);
            }
        }
    }

    /**
     * random circle color
     */
    private int[] colorsId = {Color.RED, Color.GREEN, Color.YELLOW, Color.BLUE};

    /**
     * add point to gather
     *
     * @param startX
     * @param startY
     */
    private void addPoint2(int startX, int startY) {
        Wave w = new Wave();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(colorsId[(int) (Math.random() * 4)]);
        w.cx = startX;
        w.cy = startY;
        w.p = paint;
        pointList.add(w);
    }

    /**
     * initialization view
     */
    private void initView() {

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        if(pointList.size()!=0) {
        for (int i = 0; i < pointList.size(); i++) {
            Wave w = pointList.get(i);
            canvas.drawCircle(w.cx, w.cy, w.r, w.p);
        }
//        }
    }

    /**
     * Storage circle
     */
    private class Wave {
        public int cx; //  圓心 x
        public int cy;
        public int r;  // radio
        public Paint p; // paint
    }
}
           

寫的不好 忘見諒