2011-03-29 14 views

Respuesta

9

Registre LongCLickListener. Si se reconoce un clic largo, establezca un indicador en verdadero.

En el método OnTouch, permite escalar y mover solo si el indicador se establece en verdadero. Después de mover y escalar establecer la bandera a falso nuevamente.

Aquí es un poco de pseudocódigo:

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; 
    } 
} 
+0

Im tratando de hacer esto en un ImageView. Entonces, ¿qué oyente le puse? onLongClick o onTouch? –

+0

Ambos. En onLongClick, comprueba si un clic prolongado era anterior y en onTouch realiza su movimiento y escala como lo hace ahora. – RoflcoptrException

+0

Sí, lo entiendo. Pero digamos que estoy implementando hacer clic para una 'vista de ImageView', ¿entonces debería escribir' view.setOnLongClickListener() '? y configurar mi clase para implementar 'onLongClickListener' y' onTouchListener'? –

2

idea principal de Roflcoptr es correcto, pero incluso si usted se moverá el puntero sin pulsación larga, onLongClick se llamará. Para evitar esto, puede utilizar este código:

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); 
} 

esperan que ayude a alguien)

+0

código brillante, me ayudó! Gracias un montón –

2

Se pueden crear dos View.ontouchlistener una para el trabajo y otro vacío, y establecer el oyente a ver sólo en 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; 
     } 
    }); 
Cuestiones relacionadas