Пользовательский нарисованный объект не будет реагировать на событие касания - PullRequest
0 голосов
/ 31 мая 2019

Я создаю пользовательскую панель поиска, которая позволяет пользователю перетаскивать круг внутри кольца. Я закончил круг и кольцо, используя классы холста. Вы можете увидеть изображение этого ниже.

enter image description here

Чтобы соответствовать расположению круга внутри кольца (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;
    }
    }

1 Ответ

1 голос
/ 18 июня 2019

Для решения проблемы необходимо создать класс, который фиксирует угол от радиуса круга относительно оси x.

public int updateRotation(float x, float y) {
    r = Math.atan2(x - startX, y - startY);
    rotation = -(int) Math.toDegrees(r)+70;
    //radiusConverter.setPercent(rotation);
    //notifyAll();
    return rotation;
}

Затем в случае переключателя Motion Event, восстанавливая этот угол и сообщая о нем как о новой точке x, y.

    endAngle = Float.valueOf(updateRotation(x, y));

    endAngleRadian = endAngle *((float)Math.PI / 180);
rotationUpdate.setRotation(endAngleRadian);

    pointX = (int) Math.round((startX + radius2 * Math.cos(endAngleRadian)));
    pointY = (int) Math.round((startY + radius2 * Math.sin(endAngleRadian)));
...