Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: How to call onTouch only after an onLongClick?

I have an image, which can be moved around and scaled with pinch gesture.. All this is done inside onTouch(). I want to restrict this and make it movable(and scalable) only after the user has done a longclick on the image.. How do I do this?

like image 798
Rohith Nandakumar Avatar asked Mar 29 '11 11:03

Rohith Nandakumar


3 Answers

Register a LongCLickListener. If a long click is recognized set a flag to true.

In the OnTouch method allow scaling and moving only if the flag is set to true. After the moving and scaling set the flag to false again.

Here is some pseudocode:

public class MyActivity extends Activity {

   private boolean longClick = false;

   public boolean onTouch(View v, MotionEvent event) {
      if (longClick) {
         // do scaling and moving ...
         longClick = false;
      }
      return false;
   }

   public boolean onLongClick(View v) {
      longClick = true;
      return false;
   }
}
like image 181
RoflcoptrException Avatar answered Oct 31 '22 10:10

RoflcoptrException


You can create two View.ontouchlistener one for work and one empty, and set the listener to view only on onlongpress

    LinearLayout.LayoutParams longpressLP = new LinearLayout.LayoutParams(100,100);
    LinearLayout longpress = new LinearLayout(this);
    longpress.setBackgroundColor(Color.GREEN);
    mainlayout.addView(longpress,longpressLP);



    final View.OnTouchListener buttontouch=new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            if(event.getAction()==MotionEvent.ACTION_DOWN)
                v.setOnTouchListener(buttontouchnone);
            else
                Toast.makeText(getApplicationContext(), "Touched", Toast.LENGTH_SHORT).show();
            return false;
        }
    };
    final View.OnTouchListener buttontouchnone=new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), "None Touch", Toast.LENGTH_SHORT).show();
            return false;
        }
    };
    longpress.setOnTouchListener(buttontouch);
    longpress.setOnLongClickListener(new View.OnLongClickListener() {

        public boolean onLongClick(View v) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), "LongClick", Toast.LENGTH_SHORT).show();
            v.setOnTouchListener(buttontouch);
            return true;
        }
    });
like image 21
Diljeet Avatar answered Oct 31 '22 11:10

Diljeet


Main idea of Roflcoptr is right, but even if you'll move your pointer without long click, onLongClick will be called. To avoid this, you can use this code:

final int NONE=0;
final int DRAG=1;
final int LONG_PRESS=2;
int mode=NONE;

PointF start=new PointF();

public boolean onLongClick(View v) {
    if(mode==NONE) mode=LONG_PRESS; //it helps to avoid unwanted onLongClick
    return false;
}

public boolean onTouch(View v, MotionEvent event){
    switch(event.getAction() & MotionEvent.ACTION_MASK){
        case MotionEvent.ACTION_DOWN:
            start.set(event.getX(),event.getY()); //point where we started from
            break;
        case MotionEvent.ACTION_UP:
            mode=NONE;
            break;
        case MotionEvent.ACTION_MOVE:
            if(mode==NONE && getDistance(event.getX(),event.getY(),start.x,start.y)>30d) mode=DRAG; //if we really move our pointer, then start the drag mode.
            //it helps to avoid unwanted moving

            if(mode==DRAG){
            //do your stuff
            }
            if(mode==LONG_PRESS){
            //do your stuff
            }
            break;
    }
}

//returns distance between 2 points
private double getDistance(float x1,float y1,float x2,float y2){
    float dx=Math.abs(x1-x2);
    float dy=Math.abs(y1-y2);
    return Math.sqrt(dx*dx+dy*dy);
}

Hope it will help someone )

like image 2
Dmitry Zaytsev Avatar answered Oct 31 '22 10:10

Dmitry Zaytsev