自定义SurfaceView实现跳动的泡泡

先看下效果图

QQ20170410-214631-HD.gif

不记得从哪里看到的这样的效果了,今天想起来了,觉得挺好玩就随便实现了一下。

大致的步骤如下:
1、继承SurfaceView 并实现SurfaceHolder.Callback,和Runnable接口。至于为什么使用SurfaceView而不用View,大家可以读一下下面这个文章:http://blog.csdn.net/tianfeng701/article/details/7601627

2、画四个球球(很简单吧~)透明度随喜好调一下。

3、四个球,那么以圆心为起点,定义四个轨迹线。(轨迹线方向随意)

4、通过子线程不断移动小球(移动球球圆心)

代码是最好的老师,我就不啰嗦了。

public class BreatheView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    /**
     * 是否处于绘制状态
     */
    private boolean mIsDrawing;
    /**
     * 帮助类
     */
    private SurfaceHolder mHolder;
    /**
     * 画布
     */
    private Canvas mCanvas;
    /**
     * 画笔
     */
    private Paint mPaint;
    private Paint mPaintTwo;
    private Paint mPaintThree;
    private Paint mPaintFour;
    /**
     * 宽高
     */
    private float width;
    private float height;

    private final int ALPHA = 50;
    private final int SLEEP_TIME = 100;
    /**
     * 坐标
     */
    PointF oneStartPoint;
    PointF twoStartPoint;
    PointF threeStartPoint;
    PointF fourStartPoint;
    /**
     * 判断是否绘制
     */
    boolean isDraw = true;
    boolean isDrawTwo = true;
    boolean isDrawThree = true;
    boolean isDrawFour = true;

    public BreatheView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

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

    public BreatheView(Context context) {
        super(context);
        initView();
    }

    private void initView() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.CYAN);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAlpha(ALPHA);

        mPaintTwo = new Paint();
        mPaintTwo.setAntiAlias(true);
        mPaintTwo.setColor(Color.BLUE);
        mPaintTwo.setStyle(Paint.Style.FILL);
        mPaintTwo.setAlpha(ALPHA);

        mPaintThree = new Paint(mPaint);
        mPaintThree.setAntiAlias(true);
        mPaintThree.setColor(Color.RED);
        mPaintThree.setStyle(Paint.Style.FILL);
        mPaintThree.setAlpha(ALPHA);

        mPaintFour = new Paint();
        mPaintFour.setAntiAlias(true);
        mPaintFour.setColor(Color.GREEN);
        mPaintFour.setStyle(Paint.Style.FILL);
        mPaintFour.setAlpha(ALPHA);

        oneStartPoint = new PointF(300, 220);
        twoStartPoint = new PointF(20, 250);
        threeStartPoint = new PointF(500, 90);
        fourStartPoint = new PointF(0, 0);
    }

    private Canvas getCanvas(){
        return mCanvas;
    }

    private void setCanvas(Canvas aCanvas){
        this.mCanvas = aCanvas;
    }

    @Override
    public void run() {
        long start = System.currentTimeMillis();
        while (mIsDrawing) {
            try {
                Thread.sleep(SLEEP_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            draw();
        }
        long end = System.currentTimeMillis();
        if (end - start < SLEEP_TIME) {
            try {
                Thread.sleep(SLEEP_TIME - (end - start));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        mIsDrawing = true;
        new Thread(this).start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        mIsDrawing = false;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    private synchronized void draw() {
        try {
            lockCanvas();
            drawOne();
            drawTwo();
            drawThree();
            drawFour();
            unlockCanvas();
        } catch (Exception e) {
        }
    }

    private void drawOne() {
        getCanvas().drawColor(Color.WHITE);
        if (oneStartPoint.x == 300 || oneStartPoint.y == 220) {
            isDraw = true;
        } else if (oneStartPoint.x == 330 || oneStartPoint.y == 250) {
            isDraw = false;
        }
        if (isDraw) {
            getCanvas().drawCircle(oneStartPoint.x++, oneStartPoint.y++, 180, mPaint);
        } else {
            getCanvas().drawCircle(oneStartPoint.x--, oneStartPoint.y--, 180, mPaint);
        }
    }

    private void lockCanvas() {
        setCanvas(mHolder.lockCanvas());
    }

    private void unlockCanvas() {
        if (getCanvas() != null) {
            mHolder.unlockCanvasAndPost(getCanvas());
        }
    }

    private void drawFour() {
        //第四个泡泡
        if (fourStartPoint.x == 0 || fourStartPoint.y == 0) {
            isDrawFour = true;
        } else if (fourStartPoint.x == 20 || fourStartPoint.y == 20) {
            isDrawFour = false;
        }
        if (isDrawFour) {
            getCanvas().drawCircle(fourStartPoint.x++, fourStartPoint.y++, 220, mPaintFour);
        } else {
            getCanvas().drawCircle(fourStartPoint.x--, fourStartPoint.y--, 220, mPaintFour);
        }
    }

    private void drawThree() {
        //第三个泡泡
        if (threeStartPoint.x == 500 || threeStartPoint.y == 200) {
            isDrawThree = true;
        } else if (threeStartPoint.x == 520 || threeStartPoint.y == 520) {
            isDrawThree = false;
        }
        if (isDrawThree) {
            getCanvas().drawCircle(threeStartPoint.x++, threeStartPoint.y++, 220, mPaintThree);
        } else {
            getCanvas().drawCircle(threeStartPoint.x--, threeStartPoint.y--, 220, mPaintThree);
        }
    }

    private void drawTwo() {
        //第二个泡泡
        if (twoStartPoint.x == 20 || twoStartPoint.y == 250) {
            isDrawTwo = true;
        } else if (twoStartPoint.x == 35 || twoStartPoint.y == 265) {
            isDrawTwo = false;
        }
        if (isDrawTwo) {
            getCanvas().drawCircle(twoStartPoint.x++, twoStartPoint.y++, 240, mPaintTwo);
        } else {
            getCanvas().drawCircle(twoStartPoint.x--, twoStartPoint.y--, 240, mPaintTwo);
        }
    }
}

github地址:https://github.com/519401502/-SurfaceView-

笔者能力有限,不足之处欢迎指出!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,639评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,093评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,079评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,329评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,343评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,047评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,645评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,565评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,201评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,338评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,014评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,701评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,194评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,685评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,345评论 2 358

推荐阅读更多精彩内容