我正在学习自定义视图,所以我决定在中心创建一个圆圈。它工作正常。
现在,我希望此圆圈像 chatHead(如facebook)一样拖动。我已经使用onTouchEvent实现了拖动功能。但是我在屏幕上触摸过的地方都开始拖动。正如我将侦听器添加到整个视图中一样。我想使其在接触到圆圈内后拖动。据我认为,我必须检测Action_Down中的x,y位置是否该点在圆内,然后允许它拖动。但无法实现。
public class CircleDraggingView extends View {
///float dX, dY;
private static final String TAG = "CustomDrawing";
private float circleRadius = 180;
boolean isDrawCalledFirstTime = true;
boolean isAllowedToDrag = true;
private float center_circle_X = 180;
private float center_circle_Y = 180;
private Paint circlePaint;
private Paint linePaint;
private Paint textPaint;
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(10);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.ROUND);
circlePaint.setStrokeCap(Paint.Cap.ROUND);
linePaint = new Paint();
linePaint.setColor(Color.WHITE);
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth((float) 1.5);
textPaint = new Paint();
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(60);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setFakeBoldText(true);
}
@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);
canvas.drawText("CC", center_circle_X, getyPositionOfText(center_circle_Y, textPaint), textPaint);
Log.d(TAG, "onDraw:centerX= " + center_circle_X + " centerY= " + center_circle_Y + " Width= "
+ canvas.getWidth() + " Height= " + canvas.getHeight());
}
private int getyPositionOfText(float yPositionOfText, Paint mPaint) {
return (int) ((yPositionOfText) - ((mPaint.descent() + mPaint.ascent()) / 2));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int initialX = 0;
int initialY = 0;
float initialTouchX = 0;
float initialTouchY = 0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
Log.d(TAG, "ACTION_DOWN:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
+ event.getX() + " getY= " + event.getY());
///path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "ACTION_MOVE:getRawX= " + event.getRawX() + " getRawY= " + event.getRawY() + " getX= "
+ event.getX() + " getY= " + event.getY());
center_circle_X = initialX + (int) (event.getRawX()- initialTouchX);
center_circle_Y = initialY + (int) (event.getRawY() - initialTouchY);
break;
default:
return false;
}
// Force a view to draw again
///postInvalidate();
invalidate();
return true;
}
private boolean isPointInside(float pointX, float pointY) {
float circleX = getX(), circleY = getY();
//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 = false;
if ((distance * distance) < (circleRadius * circleRadius))
isPointInside = true;
return isPointInside;
}
}
我也尝试了其他一些技巧,但无法实现。