[英]OnTouchListener not working on canvas
我需要:
我的手指触摸视图的位置。
Fragment
..
mPaintSurface = (PaintSurface) view.findViewById(R.id.image_body);
// Paint a circle when touched
mPaintSurface.setOnTouchListener(mPaintSurface);
// Get coordinates when touched
mPaintSurface.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
// Do what you want
Log.d("Fragment_Point", "X: "+mPaintSurface.getRelativeXpos()+" Y: "+mPaintSurface.getRelativeYpos());
return true;
}
return false;
}
});
..
PaintSurface
public class PaintSurface extends SurfaceView implements Runnable, OnTouchListener{
// Surface holder allows to control and monitor the surface
private SurfaceHolder mHolder;
// A thread where the painting activities are taking place
private Thread mThread;
// A flag which controls the start and stop of the repainting of the SurfaceView
private boolean mFlag = false;
// X coordinate of the touched position
private float mX;
// Y Coordinate of the touched position
private float mY;
// Paint
private Paint mPaint;
// Widths and Heights
private int mWidth;
private int mHeight;
public PaintSurface(Context context, AttributeSet attrs) {
super(context, attrs);
// Getting the holder
mHolder = getHolder();
// Initializing the X position
mX = -100;
// Initializing the Y position
mY = -100;
// Initializing the paint object mPaint
mPaint = new Paint();
// Setting the color for the paint object
mPaint.setColor(Color.RED);
}
public void resume(){
// Instantiating the thread
mThread = new Thread(this);
// setting the mFlag to true for start repainting
mFlag = true;
// Start repaint the SurfaceView
mThread.start();
}
public void pause(){
mFlag = false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
// Getting the X-Coordinate of the touched position
mX = event.getX();
// Getting the Y-Coordinate of the touched position
mY = event.getY();
Log.d("PaintSurface", "getWidth(): " + getWidth() + " getHeight(): " + getHeight());
Log.d("PaintSurface", "X: " + mX/getWidth() + " Y: " + mY/getHeight());
break;
}
return true;
}
@Override
public void run() {
while(mFlag){
// Check whether the object holds a valid surface
if(!mHolder.getSurface().isValid())
continue;
// Start editing the surface
Canvas canvas = mHolder.lockCanvas();
// Draw a body image from Drawables
Bitmap b=BitmapFactory.decodeResource(getResources(), R.drawable.body_50);
b = getResizedBitmap(b, getWidth(), getHeight());
Paint p=new Paint();
canvas.drawBitmap(b, 0, 0, p);
// Draw a circle at (mX,mY) with radius 5
canvas.drawCircle(mX, mY, 10, mPaint);
// Finish editing the canvas and show to the user
mHolder.unlockCanvasAndPost(canvas);
}
}
public float getRelativeXpos(){
return mX/getWidth();
}
public float getRelativeYpos(){
return mX/getHeight();
}
private Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
有2个触摸监听器可以执行此操作。 第一个触摸侦听器正在工作(在我触摸的点上绘制圆圈)。 但是,尝试在自定义视图上监听触摸事件的第二个触摸监听器不起作用(触摸时不记录日志)。 OnTouch仅在Paint Surface自定义视图中起作用,而在我的片段中不再起作用。
*我需要一种将画布上接触的坐标提取到片段的方法。
我也尝试过onClickListeners,结果相同。 也许我听错了触摸监听器,但是为什么一个触摸监听器正在工作而另一个却不能呢? 感谢您的任何提示。 (:
更新我试图包装整个视图并将其设置为onclick侦听器。 除了画布,其他所有内容都可以监听onclick。 为什么画布忽略onclick事件? 有没有办法绕过这个?
我想过一种作弊的方法,就是使用SharedPref在两个类之间传递信息。 但是我希望这将是最终的选择。
接下来:
/**
* @author Sergey Shustikov (pandarium.shustikov@gmail.com)
*/
public class PaintSurface implements View.OnTouchListener {
private List<View.OnTouchListener> mOnTouchListenerList = new ArrayList<>();
public void addOnTouchListener(View.OnTouchListener listener) {
mOnTouchListenerList.add(listener);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
for (View.OnTouchListener listener : mOnTouchListenerList) {
listener.onTouch(v, event);
}
return true;
}
}
用法:
// Paint a circle when touched
mPaintSurface.addOnTouchListener(mPaintSurface);
// Get coordinates when touched
mPaintSurface.addOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
// Do what you want
Log.d("Fragment_Point", "X: "+mPaintSurface.getRelativeXpos()+" Y: "+mPaintSurface.getRelativeYpos());
return true;
}
return false;
}
});
如果您想拒绝触摸更换
@Override
public boolean onTouch(View v, MotionEvent event) {
for (View.OnTouchListener listener : mOnTouchListenerList) {
listener.onTouch(v, event);
}
return true;
}
至
@Override
public boolean onTouch(View v, MotionEvent event) {
for (View.OnTouchListener listener : mOnTouchListenerList) {
if(!listener.onTouch(v, event))return false;
}
return true;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.