Как сделать подвижные точки пертикулера на изображении с позицией x y в Android?

У меня есть изображение, и я хочу сделать 8 точек на изображении, эта точка перемещается при касании точки и перетаскивании на экран, возможно ли сделать такой тип касания и подвижные точки на изображении?

Покажите изображение выше в 8 точках, я хочу, чтобы результат был похож на это изображение, а также эта точка перемещается, когда вы касаетесь этой точки и перемещаетесь по изображению, а также хотите, чтобы эта точка была координатой x, y.

я попробовал код ниже, но его точки отображения не в надлежащей форме, и все точки перемещаются одновременно.

class DrawingView extends View {
        Bitmap bitmap;

        float x, y;

        public DrawingView(Context context) {
            super(context);
            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_dot);
        }


        public boolean onTouchEvent(MotionEvent event) {

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {

                }
                break;

                case MotionEvent.ACTION_MOVE: {
                    x = (int) event.getX();
                    y = (int) event.getY();

                    invalidate();
                }

                break;
                case MotionEvent.ACTION_UP:

                    x = (int) event.getX();
                    y = (int) event.getY();
                    System.out.println(".................." + x + "......" + y); //x= 345 y=530
                    invalidate();
                    break;
            }
            return true;
        }

        @Override
        public void onDraw(Canvas canvas) {
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.WHITE);
           // canvas.drawBitmap(bitmap, x, y, paint);  //originally bitmap draw at x=o and y=0
            for (int i = 0; i < 8; i++) {
                canvas.drawBitmap(bitmap, x++, y++,  null);
            }
        }
    }

если кто-нибудь знает об этом типе представления или о каком-либо решении для него, помогите.

Заранее спасибо :)

Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Управление транзакциями JDBC - это мощная функция, которая позволяет рассматривать группу операций с базой данных как единую единицу работы. Оно...
Выполнение HTTP-запроса с помощью Spring WebClient: GET
Выполнение HTTP-запроса с помощью Spring WebClient: GET
WebClient - это реактивный веб-клиент, представленный в Spring 5. Это реактивное, неблокирующее решение, работающее по протоколу HTTP/1.1.
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
2
0
717
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Создайте пользовательский ImageView, который расширяет класс androidx.appcompat.widget.AppCompatImageView, который реализует OnTouchListener с ArrayList<Dot>, который будет отслеживать Dots.

  2. Вы переопределяете onDraw(Canvas canvas) пользовательского ImageView и перебираете ArrayList из Dots и рисуете каждый Dot в списке, используя canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint).

  3. Всякий раз, когда срабатывает MotionEvent.ACTION_DOWN, вы проверяете, было ли касание внутри существующей точки.

    Если бы вы установили это Dot в глобальную переменную, то есть touchedDot, когда пользователи перемещаются, OnTouchListener срабатывает MotionEvent.ACTION_MOVE, который вы затем проверяете, если touchedDot != null, и если да, просто измените его x и y, чтобы они соответствовали событиям через touchedDot.x = event.getX() и touchedDot.y = event.getY(), а затем вызовите invalidate(), который будет вызовите метод ImageViews onDraw, и точка будет перемещаться по мере движения пальца пользователя. Когда пользователь поднимает палец либо от прикосновения, либо от движения, MotionEvent.ACTION_UP срабатывает, там вы просто проверяете, есть ли touchedDot == null, и если да, то вы создаете новый Dot в x и y, к которому он прикоснулся, в противном случае вы устанавливаете touchedDot = null, чтобы сбросить его для следующее событие перемещения или касания.

Вот пример, который я создал с помощью Picasso для загрузки изображения в пользовательский ImageView:

построить.градле:

dependencies {
    ...
    implementation 'com.squareup.picasso:picasso:2.71828'
}

AndroidManifest.xml:

<uses-permission android:name = "android.permission.INTERNET" />

DrawableDotImageView.java:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;

public class DrawableDotImageView extends androidx.appcompat.widget.AppCompatImageView implements View.OnTouchListener {

    private final ArrayList<Dot> dots = new ArrayList<>();
    private Paint dotPaint;
    private Dot touchedDot;

    public DrawableDotImageView(@NonNull Context context) {
        super(context);
        setup();
    }

    public DrawableDotImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    public DrawableDotImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setup();
    }

    private void setup() {
        setOnTouchListener(this);
        dotPaint = new Paint();
        dotPaint.setColor(Color.WHITE);
        dotPaint.setAlpha(100);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        dots.forEach((dot) -> {
            canvas.drawCircle(dot.getX(), dot.getY(), dot.getRadius(), dotPaint);
            Log.d("ImageView", "Drawing X: " + dot.x + " Y: " + dot.y);
        });
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                dots.forEach((dot) -> {
                    if (dot.isInside(event.getX(), event.getY())) {
                        touchedDot = dot;
                        Log.d("ImageView", "Dot touched");
                    }
                });
                break;
            case MotionEvent.ACTION_MOVE:
                if (touchedDot != null) {
                    touchedDot.x = event.getX();
                    touchedDot.y = event.getY();
                    invalidate();
                    Log.d("ImageView", "Dot moving X: " + touchedDot.x + " Y: " + touchedDot.y);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (touchedDot != null) {
                    touchedDot = null;
                } else {
                    dots.add(new Dot(event.getX(), event.getY(), 35));
                    invalidate();
                    Log.d("ImageView", "Dot created X: " + event.getX() + " Y: " + event.getY());
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
            default:
                break;
        }
        return true;
    }

    private static class Dot {
        private float x;
        private float y;
        private final float radius;

        public Dot(float x, float y, float radius) {
            this.x = x;
            this.y = y;
            this.radius = radius;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }

        public float getRadius() {
            return radius;
        }

        //https://www.geeksforgeeks.org/find-if-a-point-lies-inside-or-on-circle/
        public boolean isInside(float x, float y) {
            return (getX() - x) * (getX() - x) + (getY() - y) * (getY() - y) <= radius * radius;
        }
    }
}

TestFrament.xml: (измените имя пакета на свое собственное)

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">

    <com.example.myapplicationjava.DrawableDotImageView
        android:id = "@+id/imageView"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:scaleType = "fitXY" />

</androidx.constraintlayout.widget.ConstraintLayout>

ТестФрамент.java:

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    DrawableDotImageView imageView = view.findViewById(R.id.imageView);
    Picasso.get().load("https://i.pinimg.com/originals/d4/d8/a0/d4d8a016155f00165411066bb9a0ab42.jpg").into(imageView);
}

Что производит:

Мне нужно уже добавить 8 точек на изображение, которое можно перемещать с увеличением и уменьшением изображения. Возможно?

Praful Korat 21.12.2020 13:29

1. В методе setup() довольно просто добавить начальные 8 точек к dotsArrayList. 2. Чтобы увеличить и уменьшить масштаб, см. здесь

David Kroukamp 21.12.2020 14:22

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

Praful Korat 21.12.2020 14:31

Я уверен, что вы можете отредактировать его самостоятельно и добавить 8 строк dots.add(new Dot(x, y, 35)); в setup(), где x и y — ваши координаты, которые вы хотите. Что касается ссылки, мой ответ расширяет ImageView, поэтому любой пример с использованием ImageView будет работать для DrawableDotImageView

David Kroukamp 21.12.2020 14:47

Спасибо за вашу помощь, но я хочу, чтобы это представление с увеличением и уменьшением изображения не могли бы вы добавить это?

Praful Korat 22.12.2020 05:58

В этом представлении точка выходит за пределы поля зрения, так как я могу получить событие, когда точка перемещается за пределы поля зрения?

Praful Korat 22.12.2020 06:35

Также нужен текст над точкой, я отредактировал свой вопрос, можете ли вы проверить, пожалуйста?

Praful Korat 22.12.2020 07:29

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

David Kroukamp 22.12.2020 07:35

Спасибо @David за вашу помощь, я новичок в этой области, так что у меня много знаний об этом типе пользовательского класса.

Praful Korat 22.12.2020 07:42

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

David Kroukamp 22.12.2020 07:47

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

David Kroukamp 22.12.2020 07:57

Другие вопросы по теме