我创建了一个可拖动圈子。我希望仅当使用 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中)?