Java 我如何在android中用x y位置在图像上制作可移动的圆点?
我有一个图像,我想在图像上画一个8点,当触摸点并拖动到屏幕上时,这个点会移动,这能在图像上画出这种类型的触摸点和可移动的点吗 在8点上显示上面的图像,我想得到这样的结果,当你们触摸那个点时,那个点是移动的,在图像上移动,也要那个点的x,y坐标 我尝试了下面的代码,但它的显示点的形式不正确,并且所有的点同时移动Java 我如何在android中用x y位置在图像上制作可移动的圆点?,java,android,canvas,Java,Android,Canvas,我有一个图像,我想在图像上画一个8点,当触摸点并拖动到屏幕上时,这个点会移动,这能在图像上画出这种类型的触摸点和可移动的点吗 在8点上显示上面的图像,我想得到这样的结果,当你们触摸那个点时,那个点是移动的,在图像上移动,也要那个点的x,y坐标 我尝试了下面的代码,但它的显示点的形式不正确,并且所有的点同时移动 class DrawingView extends View { Bitmap bitmap; float x, y; public
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);
}
}
}
类DrawingView扩展视图{
位图;
浮动x,y;
公共绘图视图(上下文上下文){
超级(上下文);
位图=BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_点);
}
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:{
}
打破
case MotionEvent.ACTION\u移动:{
x=(int)event.getX();
y=(int)event.getY();
使无效();
}
打破
case MotionEvent.ACTION\u UP:
x=(int)event.getX();
y=(int)event.getY();
System.out.println(“…”+x+“…”+y);//x=345 y=530
使无效();
打破
}
返回true;
}
@凌驾
公共空白onDraw(画布){
油漆=新油漆();
绘制.设置样式(绘制.样式.填充);
油漆。设置颜色(颜色。白色);
//drawBitmap(位图,x,y,paint);//最初在x=o和y=0处绘制位图
对于(int i=0;i<8;i++){
drawBitmap(位图,x++,y++,null);
}
}
}
如果有人知道这种类型的视图或解决方案,请提供帮助
提前感谢:)
ImageView
,它扩展了androidx.appcompat.widget.AppCompatImageView
类,该类使用ArrayList
实现了一个OnTouchListener
,该列表将跟踪Dot
s
ImageView
的onDraw(画布画布)
,并迭代Dot
s的ArrayList
,使用Canvas.drawCircle(float-cx,float-cy,float-radius,@NonNull-Paint-Paint)绘制列表中的每个Dot
MotionEvent.ACTION\u DOWN
时,检查触摸是否在现有点内
如果您将Dot
设置为全局变量,即touchedDot
,则当用户将移动到TouchListener
上时,将触发MotionEvent.ACTION\u MOVE
然后检查touchedDot!=null
如果是,只需更改其x
和y
即可,通过touchedDot.x=event.getX()
和touchedDot.y=event.getY()
方法匹配事件,然后调用invalidate()
调用ImageView
sonDraw
方法,点将随着用户手指的移动而移动。当用户从触摸或移动中抬起手指时,MotionEvent.ACTION\u UP
被触发,您只需检查touchedDot==null
,如果是,则在他们触摸的x
和y
处创建一个新的点,否则,您将设置touchedDot=null
,以便在下一个移动或触摸事件中重置它
ImageView
:
build.gradle:
dependencies {
...
implementation 'com.squareup.picasso:picasso:2.71828'
}
<uses-permission android:name="android.permission.INTERNET" />
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;
}
}
}
@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);
}
AndroidManifest.xml:
dependencies {
...
implementation 'com.squareup.picasso:picasso:2.71828'
}
<uses-permission android:name="android.permission.INTERNET" />
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;
}
}
}
@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个点,可以通过图像缩放和缩放移动。有可能吗。这在
setup()
方法中非常简单,将初始的8个点添加到点
数组列表
。2.若要放大和缩小,请参见能否编辑设置方法?我不明白你说的,我想要这个可绘制的点图像视图的缩放视图。我相信你可以自己编辑它并添加8行点。添加(新点(x,y,35))
在setup()
中,其中x和y是您想要的坐标。至于链接,我的答案扩展了ImageView
,因此任何使用ImageView
的示例都适用于DrawableDotImageView
好的,谢谢您的帮助