Android原路线返回的小球

前言

最近一直忙,没空写博客,也不知道写一些啥,突然想起之前挺有意思的一个小功能,实现一下。大致如下图,大家可以看一下,很简单也很有意思。其实我想写这个的仿QQ未读消息拖动。写着写着感觉这个效果也挺好玩。。。觉得有意思的就看看吧,没啥实用性。
这里写图片描述

实现思路

就是记录小球的运动轨迹就行了,一个小球看成一个对象,然后让它从哪来滚哪去。

实现主要代码

package com.maxi.slidepoint.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
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 java.util.List;

/**
 * Created by Mao Jiqing on 2016/5/3.
 */
public class SlidePointView extends View {
    private Paint paint = new Paint();
    private final float radius = 60;
    private ArrayList<Circle> circlePaths = new ArrayList<>();

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

    private void init() {
        paint.setColor(0xffff0000);
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
    }

    private class Circle {
        float[] center;
        float radius;
        private List<Float> roadX = new ArrayList<Float>();
        private List<Float> roadY = new ArrayList<Float>();
        private boolean isSlide = false;
    }

    private void initMetaballs() {
        Circle circlePath = new Circle();
        circlePath.center = new float[]{(radius), radius};
        circlePath.radius = radius;
        circlePath.roadX.add(radius);
        circlePath.roadY.add(radius);
        circlePaths.add(circlePath);

        circlePath = new Circle();
        circlePath.center = new float[]{this.getMeasuredWidth() / 2, this.getMeasuredHeight() / 3};
        circlePath.radius = radius;
        circlePath.roadX.add(this.getMeasuredWidth() / 2f);
        circlePath.roadY.add(this.getMeasuredHeight() / 3f);
        circlePaths.add(circlePath);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (circlePaths.size() == 0) {
            initMetaballs();
        }

        final Circle circle1 = circlePaths.get(0);
        RectF ball1 = new RectF();
        ball1.left = circle1.center[0] - circle1.radius;
        ball1.top = circle1.center[1] - circle1.radius;
        ball1.right = ball1.left + circle1.radius * 2;
        ball1.bottom = ball1.top + circle1.radius * 2;
        canvas.drawCircle(ball1.centerX(), ball1.centerY(), circle1.radius, paint);

        final Circle circle2 = circlePaths.get(1);
        RectF ball2 = new RectF();
        ball2.left = circle2.center[0] - circle2.radius;
        ball2.top = circle2.center[1] - circle2.radius;
        ball2.right = ball2.left + circle2.radius * 2;
        ball2.bottom = ball2.top + circle2.radius * 2;
        canvas.drawCircle(ball2.centerX(), ball2.centerY(), circle2.radius, paint);
    }

    private Circle touchCircle;
    private int backPosition = -1;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float slideX, slideY;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                int circlePosition = getCircle(event.getX(),event.getY());
                if (circlePosition != -1) {
                    touchCircle = circlePaths.get(circlePosition);
                    backPosition = circlePosition;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(touchCircle != null && !touchCircle.isSlide) {
                    slideX = event.getX();
                    slideY = event.getY();
                    touchCircle.roadX.add(slideX);
                    touchCircle.roadY.add(slideY);
                    touchCircle.center[0] = slideX;
                    touchCircle.center[1] = slideY;
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if(touchCircle != null && backPosition != -1 && !touchCircle.isSlide) {
                    back(backPosition);
                }
                break;
        }
        return true;
    }

    private void back(final int position) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Circle circle = circlePaths.get(position);
                circle.isSlide = true;
                for (int i = circle.roadX.size() - 1; i >= 0; i--) {
                    circle.center[0] = circle.roadX.get(i);
                    circle.center[1] = circle.roadY.get(i);
                    try {
                        Thread.sleep(10);
                        handler.sendEmptyMessage(0);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                float startX = circle.roadX.get(0);
                float startY = circle.roadY.get(0);
                circle.roadX.clear();
                circle.roadY.clear();
                circle.roadX.add(startX);
                circle.roadY.add(startY);
                circle.isSlide = false;
            }
        }).start();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                invalidate();
            }
        }
    };

    private int getCircle(float x, float y) {
        int i = 0;
        for (Circle circle : circlePaths){
            if(isOnPoint(circle,x,y)){
                return i;
            }
            i++;
        }
        return -1;
    }

    private boolean isOnPoint(Circle circle,float x, float y){
        return (x > circle.center[0] - radius && x < circle.center[0] + radius
                && y > circle.center[1] - radius && y < circle.center[1] + radius);
    }
}

后续

代码很简单,就不做介绍了,写着玩也就没注意太多,大家可以看一下为后期自定义动画做铺垫。
点此下载:下载地址
有疑问或者更好地实现方式的话 请加QQ群:135451435。共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值