[英]OnTouchListener not working on canvas
I need to: 我需要:
where my finger is touching the view. 我的手指触摸视图的位置。
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;
}
}
There are 2 on touch listeners to perform this action. 有2个触摸监听器可以执行此操作。 The first touchlistener is working (paints the circle on the point I touch).
第一个触摸侦听器正在工作(在我触摸的点上绘制圆圈)。 However, the second touch listeners that tries to listen to touch events on the custom view doesn't work (No logging when touched).
但是,尝试在自定义视图上监听触摸事件的第二个触摸监听器不起作用(触摸时不记录日志)。 OnTouch only works inside Paint Surface custom view but not inside my fragment anymore.
OnTouch仅在Paint Surface自定义视图中起作用,而在我的片段中不再起作用。
*I need a way to extract the coordinates that is touching on the canvas to my fragments. *我需要一种将画布上接触的坐标提取到片段的方法。
I've also tried onClickListeners, same results. 我也尝试过onClickListeners,结果相同。 Maybe I've understood touchlisteners wrongly, but why is it that one touchlistener is working but the other isn't?
也许我听错了触摸监听器,但是为什么一个触摸监听器正在工作而另一个却不能呢? Thanks for any hints.
感谢您的任何提示。 (:
(:
UPDATE I've tried to wrap the entire view and setting it to an onclick listener. 更新我试图包装整个视图并将其设置为onclick侦听器。 Everything else is able to listen for onclick, except for the canvas.
除了画布,其他所有内容都可以监听onclick。 Why is the canvas ignoring onclick events?
为什么画布忽略onclick事件? Is there a way to bypass this?
有没有办法绕过这个?
I've thought a way to cheat this, which is to use SharedPref to pass information between both classes. 我想过一种作弊的方法,就是使用SharedPref在两个类之间传递信息。 But I hope that this would be the final alternative.
但是我希望这将是最终的选择。
Make next : 接下来:
/**
* @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;
}
}
Usage : 用法:
// 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;
}
});
if you want to reject some touch replace 如果您想拒绝触摸更换
@Override
public boolean onTouch(View v, MotionEvent event) {
for (View.OnTouchListener listener : mOnTouchListenerList) {
listener.onTouch(v, event);
}
return true;
}
to 至
@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.