Как провести линию между точками и потянуть за эти точки?

Я хочу нарисовать линии между точками на виде, а затем подтянуть эти точки в нужное положение, даже если форма изменится.

Я знаю, как провести линию между двумя точками canvas.drawLine(10, 10, 90, 10, paint);, используя это, я могу провести линии между точками.

EDIT: здесь я прилагаю изображение для ясного объяснения, из ответа Пола теперь я могу рисовать линии между точками, все еще есть проблема с вытягиванием точек ...

введите описание изображения здесь


person RajaReddy PolamReddy    schedule 02.06.2012    source источник
comment
Можете ли вы опубликовать весь код, пожалуйста? потому что мне очень нужен этот код .... заранее спасибо   -  person Suleman Khan    schedule 09.11.2012
comment
пожалуйста, дайте мне знать, по крайней мере, как реализовать это в методе onDraw ().   -  person Suleman Khan    schedule 09.11.2012


Ответы (4)


Вот как это делается. Предположим, у вас есть свои очки, сделайте их глобальными:

PointF topLeft = new PointF(10,10);
PointF topRight = new PointF(90,10);
PointF bottomLeft = new PointF(10,90);
PointF bottomRight = new PointF(90,90);

Что вам нужно сделать, так это создать RectF вокруг каждой точки. Чем больше RectF, тем больше зона касания точки.

float sizeOfRect = 5f;
RectF topLeftTouchArea = new RectF(topLeft.x - sizeOfRect, topLeft.y - sizeOfRect, topLeft.x + sizeOfRect, topLeft.y + sizeOfRect);
//Do this for the other points too

Определите несколько глобальных объектов, чтобы отслеживать, что пользователь делает в onTouch. Один int - это касающийся угла, а четыре других - идентификаторы углов.

private final int NONE = -1, TOUCH_TOP_LEFT = 0, TOUCH_TOP_RIGHT = 1, TOUCH_BOT_LEFT = 2, TOUCH_BOT_RIGHT = 3;
int currentTouch = NONE;

Теперь в событии onTouch вы можете проверить, к какой точке прикасается ваш пользователь, вот так:

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    //The user just put their finger down.
    //We check to see which corner the user is touching
    //And set our global, currentTouch, to the appropriate constant.
    case MotionEvent.ACTION_DOWN:
        if (topLeftTouchArea.contains(event.getX(), event.getY()) {
            currentTouch = TOUCH_TOP_LEFT;
        } else if (topRightTouchArea.contains(event.getX(),event.getY()) {
            currentTouch = TOUCH_TOP_RIGHT;
        } else if (botLeftTouchArea.contains(event.getX(),event.getY()) {
            currentTouch = TOUCH_BOT_LEFT;
        } else if (botRightTouchArea.contains(event.getX(), event.getY()) {
            currentTouch = TOUCH_BOT_RIGHT;
        } else {
            return false; //Return false if user touches none of the corners
        }
        return true; //Return true if the user touches one of the corners
    //Now we know which corner the user is touching.
    //When the user moves their finger, we update the point to the user position and invalidate.
    case MotionEvent.ACTION_MOVE:
        switch (currentTouch) {
        case TOUCH_TOP_LEFT:
             topLeft.x = event.getX();
             topLeft.y = event.getY();
             //The bottom left x position has to move with the top left corner
             bottomLeft.x = topLeft.x;
             //The top right y position has to move with the top left corner
             topRight.y = topLeft.y;
             invalidate();
             return true;
        case TOUCH_TOP_RIGHT:
             topRight.x = event.getX();
             topRight.y = event.getY();
             //The top left y position has to move with the top right corner
             topLeft.y = topRight.y;
             //The bottom right x position has to move with the top right corner
             bottomRight.x = topRight.x;
             invalidate();
             return true;
        case TOUCH_BOT_LEFT:
             bottomLeft.x = event.getX();
             bottomLeft.y = event.getY();
             bottomRight.y = bottomLeft.y;
             topLeft.x = bottomLeft.x;
             invalidate();
             return true;
        case TOUCH_BOT_RIGHT:
             bottomRight.x = event.getX();
             bottomRight.y = event.getY();
             topRight.x = bottomRight.x;
             bottomLeft.y = bottomRight.y;
             invalidate();
             return true;
        }
        //We returned true for all of the above cases, because we used the event
        return false; //If currentTouch is none of the above cases, return false

    //Here the user lifts up their finger.
    //We update the points one last time, and set currentTouch to NONE.
    case MotionEvent.ACTION_UP:
        switch (currentTouch) {
        case TOUCH_TOP_LEFT:
             topLeft.x = event.getX();
             topLeft.y = event.getY();
             //The bottom left x position has to move with the top left corner
             bottomLeft.x = topLeft.x;
             //The top right y position has to move with the top left corner
             topRight.y = topLeft.y;
             invalidate();
             currentTouch = NONE;
             return true;
        case TOUCH_TOP_RIGHT:
             topRight.x = event.getX();
             topRight.y = event.getY();
             //The top left y position has to move with the top right corner
             topLeft.y = topRight.y;
             //The bottom right x position has to move with the top right corner
             bottomRight.x = topRight.x;
             invalidate();
             currentTouch = NONE;
             return true;
        case TOUCH_BOT_LEFT:
             bottomLeft.x = event.getX();
             bottomLeft.y = event.getY();
             bottomRight.y = bottomLeft.y;
             topLeft.x = bottomLeft.x;
             invalidate();
             currentTouch = NONE;
             return true;
        case TOUCH_BOT_RIGHT:
             bottomRight.x = event.getX();
             bottomRight.y = event.getY();
             topRight.x = bottomRight.x;
             bottomLeft.y = bottomRight.y;
             invalidate();
             currentTouch = NONE;
             return true;
        }
        return false;
    }
}

Это делает прямоугольник вокруг вашей точки. Представьте себе, что вокруг ваших точек на картинке нарисованы рамки. Это «сенсорные панели», созданные объектами Rect. Размер прямоугольника устанавливается sizeOfRect. В onTouchEvent он проверяет каждый объект прямоугольника, чтобы увидеть, находится ли прикосновение пользователя внутри прямоугольника, сигнализируя пользователю о попытке прикоснуться к этой точке.

person Zaid Daghestani    schedule 05.06.2012
comment
Я пробовал это, но все еще не могу понять это должным образом. Вы можете поделиться любым учебником по этому поводу .. - person RajaReddy PolamReddy; 05.06.2012
comment
на самом деле я использую одно основное действие из того, что я вызываю функцию drwaSquare () для рисования квадрата, я не могу вызвать сенсорных слушателей для этого представления .. - person RajaReddy PolamReddy; 05.06.2012
comment
если вы создаете собственный объект View, вы можете просто переопределить метод onTouchEvent - person Zaid Daghestani; 05.06.2012
comment
Я рисую квадрат с 4 точками (это 4 разные точки) для прикосновения, теперь я не могу коснуться этих точек ... - person RajaReddy PolamReddy; 05.06.2012
comment
я могу переместить линию в первый раз, второй раз она не работает, а также эти RecF не будут изменены ... - person RajaReddy PolamReddy; 09.06.2012
comment
и я рисую на макете кадра, правильный это процесс или нет. - person RajaReddy PolamReddy; 09.06.2012
comment
FrameLayout в порядке. Вам нужно обновить RectF в методе onDraw. - person Zaid Daghestani; 09.06.2012
comment
да, я обновил RectF в onDraw (), он работает нормально, как я могу перетащить общий вид в макете кадра. Без, я должен создать треугольник, квадрат, линию и круг в представлении, в зависимости от нажатия кнопки пользователя. а также размещать созданные просмотры там, где он хочет ... если не понял этого, дайте мне знать ... - person RajaReddy PolamReddy; 09.06.2012
comment
Это совсем другая работа. Задайте еще один вопрос, чтобы помочь с этим. - person Zaid Daghestani; 09.06.2012
comment
@RajaReddyPolamReddy не могли бы вы опубликовать весь код ?? потому что мне очень нужен этот код .... заранее спасибо - person Suleman Khan; 09.11.2012
comment
@ZedScio, пожалуйста, помогите мне ... мой вопрос: stackoverflow.com/questions/13302566/, который похож на ваш ответ выше, но немного отличается. - person Suleman Khan; 12.11.2012

Думаю, вы ищете класс Path:

Класс Path инкапсулирует составные (многоконтурные) геометрические пути, состоящие из отрезков прямых линий, квадратичных кривых и кубических кривых. Его можно нарисовать с помощью canvas.drawPath (путь, краска), либо с заливкой, либо с обводкой (в зависимости от стиля краски), либо его можно использовать для обрезки или рисования текста по контуру.

Примеры canvas.drawPath см. В этом руководстве

person Paul Sasik    schedule 02.06.2012
comment
Я не думаю, что они существуют, но их легко создать. Просто нарисуйте маленькие квадратики там, где точки находятся в середине квадратов, а затем выполните проверку попадания, чтобы увидеть, в какой из них попадут, и выполните операции перетаскивания на точку. На самом деле, лол, это немного сложно, но на самом деле не так уж и сложно сделать правильно. - person Paul Sasik; 02.06.2012
comment
Я отредактировал свой вопрос с изображением, я могу рисовать линии, используя путь, проблема с сенсорными слушателями ... - person RajaReddy PolamReddy; 02.06.2012

РЕДАКТИРОВАТЬ:

Вам действительно нужно использовать класс Path в Android. Извините, я не смог придумать фрагмент кода. Но вот кое-что, что поможет вам начать.

Когда вы рисуете линию - canvas.drawLine(x1, y1, x2, y2, paint);, ваша отправная точка - (x1,y1). теперь, если вам нужно протянуть леску с любого конца, вам нужно сначала закрепить другой конец. Скажем, вы тянете из (x2,y2). Итак, (x1,y1) становится постоянным, и вы тянете с другого конца. При использовании класса Path сначала вызовите moveTo() для этой фиксированной точки. Что он делает, так это то, что он дает точку, относительно которой необходимо переместить линию. Затем вы можете использовать вызов lineTo() для событий касания, чтобы соответствующим образом растянуть линию. Потребуется много настроек. Но это то, с чего можно начать. Извините, я не смог придумать отрывок, времени мало. См. Документацию класса Path. Вы можете найти еще несколько полезных вещей.


РЕДАКТИРОВАТЬ:

О добавлении слушателей касания в баллы:

Предположим, у вас есть строка от (x1,y1) до (x2,y2).

Теперь, чтобы получить сенсорный слушатель для точки, вы можете добавить onTouchListener ко всему вашему представлению.

final View touchView = findViewById(R.id.touchView);
    touchView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
               if(event.getX() == x2 && event.getY() == y2)
               {
                  //you know that you have clicked on the rear end of the line,so now you can do your dragging stuff.
                  if(event.getAction() == MotionEvent.ACTION_DOWN){
                       //you know user has clicked in order to draw
                       //redraw the existing line with black color to remove it
                       paint.setColor(Color.BLACK);
                       canvas.drawLine(x1, y1, x2, y2, paint);
                       //reset the paint object
                       paint.setColor(Color.WHITE); 
                       //now use moveTo() and lineTo() to attain the functionality of dragging on your Path object
                       path.moveTo(x1,y1);
                       path.lineTo(event.getX(),event.getY());
                  }else if(event.getAction() == MotionEvent.ACTION_MOVE){
                       path.lineTo(event.getX(),event.getY());
                  }else if(event.getAction() == MotionEvent.ACTION_UP){
                  }
       }  
               return true;
        }
    });

Это всего лишь идея, у меня все еще не было возможности ее протестировать. Я надеюсь, что это помогает.

person Kazekage Gaara    schedule 02.06.2012
comment
это просто для рисования пальцем, прочтите мой вопрос, если вы не догадались, дайте мне знать. - person RajaReddy PolamReddy; 02.06.2012
comment
ох..ок .. вы хотите, чтобы сначала пользователь нажимал на точку, затем нажимал на другую точку, а затем между этими точками была линия, верно? - person Kazekage Gaara; 02.06.2012
comment
нет, у меня уже есть линия между двумя точками, теперь я хочу перетащить одну точку, чтобы удлинить линию, не меняя другую точку .. например, изменение размера треугольника .. - person RajaReddy PolamReddy; 02.06.2012
comment
позвольте мне немного подправить это и сообщить вам через некоторое время. - person Kazekage Gaara; 02.06.2012
comment
@RajaReddyP, пожалуйста, посмотрите правки. Я что-то пробовал, на самом деле не знаю, получится ли. - person Kazekage Gaara; 07.06.2012
comment
На самом деле я использую настраиваемый класс для создания рисунка из активности в этот настраиваемый вид, я не могу вызвать слушателей касания. невозможно передать функции рисования, если я использую то, что вы сказали .. - person RajaReddy PolamReddy; 07.06.2012
comment
Я закончил до создания точек и рисования линий между точками под вашим руководством, ожидающая часть - это только сенсорные слушатели ... - person RajaReddy PolamReddy; 07.06.2012

person    schedule
comment
ваш код работает как перерисовка линии, из которой вы хотите перетащить, я не хочу перерисовывать, просто расширяя строку с другой линией, оставаясь в предыдущей точке .. - person RajaReddy PolamReddy; 02.06.2012