android:从触摸屏中心平滑流畅地移动视图(ACTION_MOVE)

时间:2018-08-17 05:39:22

标签: android touch ontouchlistener ontouchevent

  

我创建了一个可拖动圈子。我希望仅当使用 ACTION_DOWN 在内部单击并使用 ACTION_MOVE 将其拖动时,才将​​圈子设为draggable

but not perfect运行正常。在圆内的某些地方它是不可拖动的。我该如何改善 isPointInside 方法,还有什么改进或建议。

public class CircleDraggingView extends View {

    private static final String TAG = "CustomDrawing";
    private float circleRadius = 180;
    boolean isDrawCalledFirstTime = true;
    boolean isAllowedToDrag = false;

    private float center_circle_X = 0;
    private float center_circle_Y = 0;

    private Paint circlePaint;

    public CircleDraggingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setupPaint();
    }

    private void setupPaint() {
        circlePaint = new Paint();
        circlePaint.setColor(Color.BLACK);
        circlePaint.setAntiAlias(true);
        circlePaint.setStrokeWidth(4);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeJoin(Paint.Join.ROUND);
        circlePaint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        ///super.onDraw(canvas);
        if (isDrawCalledFirstTime) {
            center_circle_X = canvas.getWidth() / 2;
            center_circle_Y = canvas.getHeight() / 2;

            isDrawCalledFirstTime = false;
        }

        //Center Circle
        circlePaint.setColor(Color.BLACK);
        canvas.drawCircle(center_circle_X, center_circle_Y, circleRadius, circlePaint);

        Log.d(TAG, "onDraw:centerX= " + center_circle_X + " centerY= " + center_circle_Y );
    }

    private int getyPositionOfText(float yPositionOfText, Paint mPaint) {
        return (int) ((yPositionOfText) - ((mPaint.descent() + mPaint.ascent()) / 2));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                if(isPointInside(event.getRawX(),event.getRawY()))
                    isAllowedToDrag = true;
                Log.d(TAG, "ACTION_DOWN:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
                        + event.getX() + " getY= " + event.getY());

                break;
                ///return true;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "ACTION_MOVE:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
                        + event.getX() + " getY= " + event.getY());
                if(isAllowedToDrag){
                    center_circle_X = event.getRawX() ;
                    center_circle_Y = event.getRawY();
                    }/*this.animate().x(event.getRawX()).y(event.getRawY())
                            .setDuration(50).start();*/
                break;
            case MotionEvent.ACTION_UP:
                if(isAllowedToDrag)
                    isAllowedToDrag = false;
                break;
            default:
                return false;
        }
        // Force a view to draw again
        ///postInvalidate();
        invalidate();
        return true;
    }

    private boolean isPointInside(float pointX, float pointY) {
        float circleX = center_circle_X, circleY = center_circle_Y;

        //Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
        Double distance = Math.sqrt(Math.pow((pointX - circleX), 2) + Math.pow((pointY - circleY), 2));
        ////Double distance2 = Math.hypot(pointX-circleX, pointY-circleY);

        boolean isPointInside = true;
        if ((distance * distance) > (circleRadius * circleRadius))
            isPointInside = false;
        return isPointInside;
    }
}

是否需要将lastX位置保存在Action_Down中并动画化或平滑地转换为newX,newY位置(在Action_move中)?

0 个答案:

没有答案