У меня есть изображение, и я хочу сделать 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);
}
}
}
если кто-нибудь знает об этом типе представления или о каком-либо решении для него, помогите.
Заранее спасибо :)
Создайте пользовательский ImageView
, который расширяет класс androidx.appcompat.widget.AppCompatImageView
, который реализует OnTouchListener
с ArrayList<Dot>
, который будет отслеживать Dot
s.
Вы переопределяете onDraw(Canvas canvas)
пользовательского ImageView
и перебираете ArrayList
из Dot
s и рисуете каждый Dot
в списке, используя canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
.
Всякий раз, когда срабатывает MotionEvent.ACTION_DOWN
, вы проверяете, было ли касание внутри существующей точки.
Если бы вы установили это Dot
в глобальную переменную, то есть touchedDot
, когда пользователи перемещаются, OnTouchListener
срабатывает MotionEvent.ACTION_MOVE
, который вы затем проверяете, если touchedDot != null
, и если да, просто измените его x
и y
, чтобы они соответствовали событиям через touchedDot.x = event.getX()
и touchedDot.y = event.getY()
, а затем вызовите invalidate()
, который будет вызовите метод ImageView
s 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);
}
Что производит:
1. В методе setup()
довольно просто добавить начальные 8 точек к dots
ArrayList
. 2. Чтобы увеличить и уменьшить масштаб, см. здесь
вы можете отредактировать метод установки? я не понял, что вы говорите, и я хочу увеличить масштаб с помощью этого изображения Drawable dot.
Я уверен, что вы можете отредактировать его самостоятельно и добавить 8 строк dots.add(new Dot(x, y, 35));
в setup()
, где x и y — ваши координаты, которые вы хотите. Что касается ссылки, мой ответ расширяет ImageView
, поэтому любой пример с использованием ImageView
будет работать для DrawableDotImageView
Спасибо за вашу помощь, но я хочу, чтобы это представление с увеличением и уменьшением изображения не могли бы вы добавить это?
В этом представлении точка выходит за пределы поля зрения, так как я могу получить событие, когда точка перемещается за пределы поля зрения?
Также нужен текст над точкой, я отредактировал свой вопрос, можете ли вы проверить, пожалуйста?
Извини, чувак, я здесь не для того, чтобы делать за тебя всю твою работу, если только ты не заплатишь мне. На самом деле все это отдельные вопросы, на некоторые из которых я уже ответил, а вы не проявили интереса к попыткам самостоятельно. Я не буду помогать дальше, я думаю, что дал вам достаточно хорошую основу, чтобы взять ее оттуда.
Спасибо @David за вашу помощь, я новичок в этой области, так что у меня много знаний об этом типе пользовательского класса.
Это понятно, но если вы не будете пытаться понять, вы ничего не добьетесь в этой области. Желаю вам удачи и надеюсь, что вы сможете попытаться прочитать код, понять и реализовать некоторые идеи, которые я вам показал.
Также, пожалуйста, отметьте этот вопрос как решенный, а затем создайте новые вопросы, по одному на проблему, о том, что у вас возникает при попытке выполнить свои задачи.
Мне нужно уже добавить 8 точек на изображение, которое можно перемещать с увеличением и уменьшением изображения. Возможно?