简体   繁体   English

我如何在 android 中使用 xy position 在图像上制作可移动的小点?

[英]How i make movable perticuler dots on image with x y position in android?

I Have a image and i want to make a 8 dot on image, that dot are move when touch dot and drag to screen, is this possible to make that type of touch and movable dots on image?我有一个图像,我想在图像上制作一个 8 点,当触摸点并拖动到屏幕时,该点会移动,这可以在图像上制作那种类型的触摸和可移动点吗?

Show above image on 8 point, i want to result like this image and also that point are move when you touch that point and move on image and also want that point x,y coordinate.在 8 点上显示上面的图像,我想得到像这个图像一样的结果,当你触摸那个点并在图像上移动并且还想要那个点 x,y 坐标时,那个点也会移动。

在此处输入图像描述

i tried below code but its show dots are not in proper form, and all dots move at the same time.我尝试了下面的代码,但它的显示点格式不正确,并且所有点同时移动。

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);
            }
        }
    }

if anyone know about that type of view or any solution for it then help.如果有人知道这种类型的视图或任何解决方案,那么请提供帮助。

Thanks in advance:)提前致谢:)

  1. Create a custom ImageView which extends the androidx.appcompat.widget.AppCompatImageView class, which implements an OnTouchListener with an ArrayList<Dot> which will keep track of the Dot s.创建一个自定义ImageView ,它扩展了androidx.appcompat.widget.AppCompatImageView class,它实现了一个带有ArrayList<Dot>OnTouchListener ,它将跟踪Dot s。

  2. You override onDraw(Canvas canvas) of the custom ImageView and iterate through the ArrayList of Dot s and draw each Dot in the list using canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint) . You override onDraw(Canvas canvas) of the custom ImageView and iterate through the ArrayList of Dot s and draw each Dot in the list using canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint) .

  3. Whenever MotionEvent.ACTION_DOWN is fired you check if the touch was inside an existing dot.每当触发MotionEvent.ACTION_DOWN时,您都会检查触摸是否在现有点内。

    If it was you set that Dot to a global variable ie touchedDot , when the users moves OnTouchListener fires MotionEvent.ACTION_MOVE which you then check if touchedDot != null and if so simply change its x and y to match the events via touchedDot.x = event.getX() and touchedDot.y = event.getY() and then call invalidate() which will call the ImageView s onDraw method and the dot will be moved as the users finger moves.如果是您将Dot设置为全局变量,即touchedDot ,则当用户移动OnTouchListener时会触发MotionEvent.ACTION_MOVE ,然后您检查是否touchedDot != null如果是这样,只需更改其xy以通过touchedDot.x = event.getX()匹配事件touchedDot.x = event.getX()touchedDot.y = event.getY()然后调用invalidate() ,它将调用ImageViewonDraw方法,并且点将随着用户手指的移动而移动。 When the user lifts their finger either from a touch or a move, MotionEvent.ACTION_UP is fired, there you simply check if touchedDot == null and if so you then create a new Dot at the x and y they touched in, otherwise you set touchedDot = null to reset it for the next move or touch event.当用户从触摸或移动中抬起手指时, MotionEvent.ACTION_UP被触发,您只需检查是否touchedDot == null ,如果是,则在他们触摸的xy处创建一个新Dot ,否则您设置touchedDot = null为下一次移动或触摸事件重置它。

Here is an example I created using Picasso to load the image into the custom ImageView :这是我使用Picasso创建的一个示例,用于将图像加载到自定义ImageView

build.gradle: build.gradle:

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

AndroidManifest.xml: AndroidManifest.xml:

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

DrawableDotImageView.java: 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: (change package name according to your own) TestFrament.xml: (package名字改成自己的)

<?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>

TestFrament.java: TestFrament.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);
}

Which produces:产生:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Android应用程序开始时制作可移动幻灯片? - How to make movable slideshow at the start of android application? 如何在Android中获取图像的(x,y)坐标? - How to get (x,y) cordinates of image in android? 如何将多个对象的x,y,z坐标转换为显示这些对象位置的Android应用程序? - How could I turn coordinates x,y,z coordinates of several objects into an Android app that displays the position of these objects? Java Android:如何在 GLSurfaceView 的位置(X,Y)处获取像素颜色? - Java Android: how to get pixel color at position (X, Y) of GLSurfaceView? 如何使JFrame不可移动? - How to make a JFrame not movable? 如何使用“x <= y && x> = y && x!= y”使循环无限? - How to make loop infinite with “x <= y && x >= y && x != y”? 单击另一个Android应用程序中的x和y位置 - Click on an x and y position in another android application Android:如何从(x,y)坐标计算图像的纬度和经度? - Android:How to calculate latitude and longitude of an image from (x,y) coordinates? 如何在gxt中获取窗口的xy位置 - how to get x y position of a window in gxt 如何在JScrollPane中获取图像的X和Y位置 - How do I get the X and Y location of an image in a JScrollPane
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM