问题
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
ImageViewwhich extends theandroidx.appcompat.widget.AppCompatImageViewclass, which implements anOnTouchListenerwith anArrayList<Dot>which will keep track of theDots.You override
onDraw(Canvas canvas)of the customImageViewand iterate through theArrayListofDots and draw eachDotin the list usingcanvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint).Whenever
MotionEvent.ACTION_DOWNis fired you check if the touch was inside an existing dot.If it was you set that
Dotto a global variable i.e.touchedDot, when the users movesOnTouchListenerfiresMotionEvent.ACTION_MOVEwhich you then check iftouchedDot != nulland if so simply change itsxandyto match the events viatouchedDot.x = event.getX()andtouchedDot.y = event.getY()and then callinvalidate()which will call theImageViewsonDrawmethod 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_UPis fired, there you simply check iftouchedDot == nulland if so you then create a newDotat thexandythey touched in, otherwise you settouchedDot = nullto 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