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. 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.
*I need a way to extract the coordinates that is touching on the canvas to my fragments.
I've also tried onClickListeners, same results. 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. Everything else is able to listen for onclick, except for the canvas. Why is the canvas ignoring onclick events? 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. 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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.