2012-04-03 5 views
5

Nehmen wir an, Sie haben eine TextView, die eine Zahl wie 0 anzeigt, und Sie haben eine Button. Nun, wenn der Benutzer die Taste drückt, wird die Zahl in der TextView um eins erhöht (das weiß ich), aber wenn der Benutzer die Taste drückt und sie nicht loslässt, sollte die Zahl in TextView erhöht werden und dies sollte Wiederholen Sie es selbst, solange der Benutzer die Button nicht freigibt. Mit anderen Worten: Wie erhöht man die Anzahl immer wieder, solange der Benutzer den Button gedrückt hält?Eine Aktion wiederholen, solange die Taste gedrückt wird

Antwort

6

Ein allgemeiner Ansatz (nicht Android-spezifisch) wäre, das Ereignis "Presse" und "Release" separat zu erkennen. Das Pressereignis startet eine periodische Aufgabe (Runnable oder Thread), die zum Zähler addiert (sagen wir mal 5 mal pro Sekunde oder einmal alle 200 ms). Das Release-Ereignis stoppt die periodische Aufgabe.

1
  1. eine View.OnLongClickListener für den Button
  2. Geben Sie Ihre Aktivität ein Runnable, Einstellungen und initialisiert werden (aber starten es nicht), wenn Sie die Aktivität
  3. die OnLongClickListener Aufgabe, eine Modernisierung seiner regelmäßigen async Haben laden das Textfeld und die Zeit seit dem ersten Klicken
  4. Erstellen Sie eine OnTouchListener, die die Runnable pausiert, wenn das Touch-Ereignis erneut veröffentlicht wird.

Ich weiß, das ist eine Rohfassung, aber dies ist ein wirklich nützliches Muster der Lage sein, wieder zu verwenden und zu ändern, so dass es lohnt Krallen in sie versinken ...

+0

+1 Das klingt nach dem spezifischen Android-Prozess, den ich generischer beschrieben habe. –

2

Sie werden ein Zeitplan müssen asynchrones wiederholendes Ereignis, wenn Sie ein mousePressed Ereignis erhalten und wenn Sie ein Ereignis mouseReleased erhalten, beenden Sie es.

Es gibt viele Möglichkeiten, dies in Java zu handhaben. Ich verwende gerne die java.util.concurrent Klassen, die ziemlich flexibel sind. Es gibt jedoch ein paar Dinge zu beachten:

Wenn Ihre asynchronen Ereignisse nicht auf dem Event Dispatch Thread auftreten, müssen Sie den JButton Text mit SwingUtilities.invokeLater() festlegen.

import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.TimeUnit; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

public class Frame 
{ 
    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame(); 
     final JButton button = new JButton("0"); 

     final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 

     button.addMouseListener(new MouseAdapter() 
     { 
      int counter = 0; 
      ScheduledFuture<?> future; 

      @Override 
      public void mousePressed(MouseEvent e) 
      { 
       Runnable runnable = new Runnable() 
       { 
        public void run() 
        { 
         SwingUtilities.invokeLater(new Runnable() 
         { 
          public void run() 
          { 
           button.setText(String.valueOf(counter++)); 
          } 
         }); 
        } 
       }; 

       future = executor.scheduleAtFixedRate(runnable, 0, 200, TimeUnit.MILLISECONDS); 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) 
      { 
       if (future != null) 
       { 
        future.cancel(true); 
       } 
      } 

     }); 

     frame.add(button); 
     frame.setSize(400, 400); 
     frame.setVisible(true); 
    } 
}