2010-03-29 8 views
11

Meine Klasse erweitert View und ich muss kontinuierliche Berührungsereignisse darauf erhalten.Wie bekomme ich ein kontinuierliches Touch Event?

Wenn ich benutze:

public boolean onTouchEvent(MotionEvent me) { 

    if(me.getAction()==MotionEvent.ACTION_DOWN) { 
     myAction(); 
    } 
    return true; 
} 

... das Berührungsereignis einmal erfasst wird.

Was ist, wenn ich kontinuierliche Berührungen brauche, ohne den Finger zu bewegen? Bitte sagen Sie mir, dass ich keine Threads oder Timer verwenden muss. Meine App ist schon zu schwer.

Danke.

Antwort

15

Verwenden Sie if(me.getAction() == MotionEvent.ACTION_MOVE). Es ist unmöglich, einen Finger 100% vollständig auf dem Bildschirm zu halten, so dass Action_Move immer dann aufgerufen wird, wenn sich der Finger bewegt, auch wenn es nur ein oder zwei Pixel sind.

Sie könnten auch nach me.getAction() == MotionEvent.ACTION_UP hören - bis das passiert, muss der Benutzer immer noch ihren Finger auf dem Bildschirm haben.

+2

Richtig, ich würde die Lösung vorziehen, eine Flagge auf ACTION_DOWN zu setzen und verwenden, dass bis das Flag gesetzt ist zu falsch auf ACTION_UP – WarrenFaith

+0

Wirklich danke. – daliz

+0

Ich sehe das überall erwähnt, aber es scheint nicht der Fall für mich zu sein. Wenn ich berühre und halte und still bleibe, erhalte ich keine ACTION_MOVE-Ereignisse. ACTION_MOVE scheint nur auszulösen, wenn ich meinen Finger in die eine oder andere Richtung lehne. Könnte es eine Einstellung auf meinem Telefon sein, die es weniger empfindlich hält? – clusterflux

3

Sie ist das einfache Code-Snippet, das zeigt, wie Sie mit dem Touch-Ereignis fortfahren können. Wenn Sie das Gerät berühren und die Berührung halten und Ihren Finder bewegen, wird die Aktion "Berührung bewegen" ausgeführt.

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 
    if(isTsunami){ 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      // Write your code to perform an action on down 
      break; 
     case MotionEvent.ACTION_MOVE: 
      // Write your code to perform an action on contineus touch move 
      break; 
     case MotionEvent.ACTION_UP: 
      // Write your code to perform an action on touch up 
      break; 
    } 
    } 
    return true; 
} 
1

Versuchen Sie es. Es funktioniert für mich:

public static OnTouchListener loadContainerOnTouchListener() { 
    OnTouchListener listener = new OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     LinearLayout layout = (LinearLayout)v; 
     for(int i =0; i< layout.getChildCount(); i++) 
     { 
      View view = layout.getChildAt(i); 
      Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 
      if(outRect.contains((int)event.getX(), (int)event.getY())) 
      { 
       Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId())); 
      } 
     } 

    } 

Denken Sie daran: der Hörer ich wird Satz ein Container-Layout (Gitter, Relative, Linear) sein muss.

LinearLayout layout = findViewById(R.id.yourlayoutid); 
layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener()); 
5

Sie benötigen diese Eigenschaften für das Element android einzustellen: fokussierbarem = "true" android: anklickbare = "true" wenn nicht, nur die nach unten Aktion zu erzeugen.

0

Ich machte ein Spiel mit einer benutzerdefinierten Ansicht als Daumensteuerung verwendet. . . hier ist das, was ich tat, aber

float x = 0, y = 0; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    x = event.getX(); 
    y = event.getY(); 

    // handle touch events with 
    switch(event.getActionMasked()) { 
     case MotionEvent.ACTION_DOWN : 
      if(cont) 
      { 
       // remove any previous callbacks 
       removeCallbacks(contin); 

       // post new runnable 
       postDelayed(contin, 10); 
      } 
      invalidate(); 
      return true; 
     case MotionEvent.ACTION_MOVE : 
      if(!cont && thumbing != null) 
      { 
       // do non-continuous operations here 
      } 
      invalidate();  
      return true; 
     case MotionEvent.ACTION_UP : 

      // set runnable condition to false 
      x = 0; 

      // remove the callbacks to the thread 
      removeCallbacks(contin); 
      invalidate(); 
      return true; 
     default : 
      return super.onTouchEvent(event); 
    } 
} 

public boolean cont = false; 

// sets input to continuous 
public void set_continuous(boolean b) { cont = b; } 


public Runnable contin = new Runnable() 
{ 

    @Override 
    public void run() { 
     if(x != 0) 
     { 
      // do continuous operations here 
      postDelayed(this, 10); 
     } 
    } 

}; 

Eine kurze Notiz, in Ihrer Haupttätigkeit stellen Sie sicher, dass diese Ansicht ruft entfernt die Rückrufe manuell über das Verfahren onPause als

@Override 
protected void onPause() { 
    if(left.cont) left.removeCallbacks(left.contin); 
    if(right.cont) right.removeCallbacks(left.contin); 
    super.onPause(); 
} 

Auf diese Weise folgt, wenn Sie anhalten und zurück Touch-Ereignisse werden nicht zweimal behandelt und die Ansicht ist frei von Overhead des Threads.

** getestet auf dem Samsung Galaxy S3 mit Hardware-Beschleunigung auf **

0

diese Antwort sind alle teilweise richtig, aber sie lösen nicht das Problem in der richtigen Weise.

Zunächst einmal für alle da draußen, die entscheiden, zu verfolgen, wenn das Ereignis ACTION_MOVE ist. Nun, das funktioniert nur raten wann? Wenn der Benutzer seinen Finger bewegt, könnte dies, wenn Sie sich entscheiden, ein benutzerdefiniertes Daumensteuerelement zu implementieren, in Ordnung sein, aber für eine normale benutzerdefinierte Schaltfläche ist dies nicht der Fall.

Zweitens eine Flagge innerhalb ACTION_DOWN und überprüfen sie in ACTION_UP die Logik Art und Weise scheint es zu tun, aber als Clusterfux herauszufinden, ob Sie eine while(!up_flag) Logik implementieren Sie in Schwierigkeiten stecken;)

So ist der richtige Weg zu tun, ist es hier erwähnt:

Continuous "Action_DOWN" in Android

Denken Sie daran, dass, wenn die Logik wirst du während der kontinuierlichen Presse schreiben hat die Benutzeroberfläche in irgendeiner Weise zu ändern, es von Ihnen zu tun haben, die Haupt-Thread in allen anderen Fällen ist es besser, einen anderen Thread zu verwenden.

0

Dies könnte helfen,

requestDisallowInterceptTouchEvent(true); 

auf der übergeordneten Ansicht, wie diese -

 @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      view.getParent().requestDisallowInterceptTouchEvent(true); 
      switch(motionEvent.getActio){ 
      } 

      return false; 

     }