Как да начертая линия между точките и да издърпам тези точки?

Искам да начертая линиите между точките в изгледа и след това да издърпам тези точки до желаните позиции, дори формата да се промени.

знам как да начертая линията между две точки 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(), работи добре, как мога да плъзгам и пускам общия изглед в оформлението на рамката. bez, трябва да създам триъгълник, квадрат, линия и кръг в изгледа, зависи от щракването на потребителския бутон. и също така да постави тези създадени изгледи, където пожелае в изгледа..ако не сте разбрали това, уведомете ме... - 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(path, paint), запълнено или щрихирано (въз основа на стила на рисуването), или може да се използва за изрязване или за рисуване на текст върху път.

Вижте този урок за примери на 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