Я создаю пользовательскую панель поиска, которая позволяет пользователю перетаскивать круг внутри кольца. Я закончил круг и кольцо, используя классы холста. Вы можете увидеть изображение этого ниже.
Чтобы соответствовать расположению круга внутри кольца (0 град = 0%, 90 град = 25%, 180 град = 50% и т. Д.), Я планирую использовать тригонометрическую инверсию (arcTan) и отображать этот процент в центре круга.
Я пытаюсь разрешить пользователю перетаскивать круг внутри кольца с помощью прикосновения пользователя, зафиксировав синюю линию в центре круга, а затем сделать круг прикосновением, когда маленький синий круг должен поворачиваться неподвижным Синяя линия). Я планирую в конце концов установить прозрачную синюю линию, чтобы синий круг казался неподвижным внутри синего кольца. Моя проблема в том, что событие касания для синего круга вообще не отвечает (перетаскивается в синее кольцо). Любые предложения, чтобы это произошло?
public class barSeeker extends View {
private Paint kCirclePaint; //Set ring color
Paint mPaint=new Paint(); //To make various colors
float startX; // to position line inside ring
float startY; // to position line ring
float stopX; // to position line ring
float stopY; // to position line ring
float mX; //Center of big yellow ring x-coordinate
float mY; //Center of big yellow ring y-coordinate
float mX2; //Center of blue ring x-coordinate
float mY2; //Center of blue ring y- coordinate
int radius = 250; //Large yellow ring to create highlite effect behind blue ring
int radius2 = 250; // Big blue ring
float radius_small=50; //Radius of small blue circle
public barSeeker(Context context) {
super(context);
}
public barSeeker(Context context, AttributeSet attrs) {
super(context, attrs);
Init(attrs);
}
public barSeeker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Init(attrs);
}
public barSeeker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
Init(attrs);
}
private void Init(AttributeSet set){
if(set==null)
return;
kCirclePaint = new Paint();
kCirclePaint.setAntiAlias(true);
kCirclePaint.setColor(Color.parseColor("#88bbff")); //YEllow Ring color
Paint mPaint=new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(50);
mPaint.setColor(Color.BLUE); //Blue ring color
}
protected void onDraw(Canvas canvas){
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(100);
// Setting the color of the circle
mPaint.setColor(Color.BLUE);
mX=getWidth()/2; //Coordinates for big circle x-axis
mY=getHeight()/2; // Coordinates for big circle y-axis
mPaint.setColor(Color.YELLOW); // Second yellow big circle to create highlite effect on big blue circle
mPaint.setDither(true); // set the dither to true
mPaint.setStyle(Paint.Style.STROKE); // set to STOKE
mPaint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
mPaint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too
mPaint.setPathEffect(new CornerPathEffect(50) ); // set the path effect when they join.
mPaint.setAntiAlias(true);
RectF oval = new RectF(mX - radius, mY - radius, mX + radius, mY + radius); //Draw big circle background yellow
canvas.drawArc(oval, -70, 320, false, mPaint);
mX2=getWidth()/2; // Center for Big Circle
mY2=getHeight()/2; //Center for Big Circle
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(80);
mPaint.setDither(true); // set the dither to true
mPaint.setStyle(Paint.Style.STROKE); // set to STOKE
mPaint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
mPaint.setStrokeCap(Paint.Cap.ROUND);
RectF oval2 = new RectF(mX2 - radius2, mY2 - radius2, mX2 + radius2, mY2 + radius2); //Big Blue Ring
canvas.drawArc(oval2, -70, 320, false, mPaint); //Big Blue Ring
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(10);
mPaint.setDither(true);
startX=mX2; //Coordinates for line start x-axis
startY=mY2; //Coordinates for line start y-axis
stopX=mX2; //Coordinates for line end x-axis
stopY=mY2 - radius2; //Coordinates for line end y-axis
canvas.drawLine(startX, startY, stopX, stopY, mPaint); // line attached to circle
canvas.drawCircle(stopX, stopY,radius_small, mPaint);// circle inside barseeker
canvas.rotate(360,startX, startY ); //Lock the line in place at center of circle so small circle can be dragged inside ring
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean value= super.onTouchEvent(event);
if(event.getAction()==event.ACTION_MOVE){
float x=event.getX();
float y=event.getY();
int endAngle=updateRotation(stopX, stopY);
double endAngleRadian = endAngle * (Math.PI / 180);
int pointX = (int) Math.round((startX + radius2 * Math.cos(endAngleRadian)));
int pointY = (int) Math.round((startY + radius2 * Math.sin(endAngleRadian)));
stopX = pointX;
stopY = pointX;
double dx=Math.pow(x - stopX,2);
double dy=Math.pow(y - stopY,2);
if(dx + dy<Math.pow(radius_small, 2)){ // if this is true, you are touching small circle
stopX=x;
stopX=y;
postInvalidate();
return true;
}
return value;
}
return true;
}
private int updateRotation(float x, float y){
double r=Math.atan2(x-stopX, y-stopY); //find angle of small circle
rotation=(int)Math.toDegrees(r); convert to degrees
return rotation;
}
}