问题
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?
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 .
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 theandroidx.appcompat.widget.AppCompatImageView
class, which implements anOnTouchListener
with anArrayList<Dot>
which will keep track of theDot
s.You override
onDraw(Canvas canvas)
of the customImageView
and iterate through theArrayList
ofDot
s and draw eachDot
in the list usingcanvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
.Whenever
MotionEvent.ACTION_DOWN
is fired you check if the touch was inside an existing dot.If it was you set that
Dot
to a global variable i.e.touchedDot
, when the users movesOnTouchListener
firesMotionEvent.ACTION_MOVE
which you then check iftouchedDot != null
and if so simply change itsx
andy
to match the events viatouchedDot.x = event.getX()
andtouchedDot.y = event.getY()
and then callinvalidate()
which will call theImageView
sonDraw
method and the dot will be moved as the users finger moves. When the user lifts their finger either from a touch or a move,MotionEvent.ACTION_UP
is fired, there you simply check iftouchedDot == null
and if so you then create a newDot
at thex
andy
they touched in, otherwise you settouchedDot = null
to reset it for the next move or touch event.
Here is an example I created using Picasso to load the image into the custom ImageView
:
build.gradle:
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: (change package name according to your own)
<?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:
@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:
来源:https://stackoverflow.com/questions/65387629/how-i-make-movable-perticuler-dots-on-image-with-x-y-position-in-android