2010-11-03 3 views
24

Sur un seul téléphone que je suis en train de tester (HTC Incredible, Android 2.2, Logiciel 3.21.605.1), je rencontre le comportement suivant.OnEditorActionListener appelé deux fois avec le même événementTime sur le clavier SenseUI

Le gestionnaire d'événement onEditorAction est appelé deux fois (immédiatement) lorsque la touche Entrée du clavier de l'interface utilisateur est enfoncée.

Le KeyEvent.getEventTime() est la même pour les deux fois l'événement est appelé, me conduit à ce travail autour de:

protected void onCreate(Bundle savedInstanceState) { 
    [...] 

    EditText text = (EditText)findViewById(R.id.txtBox); 
    text.setOnEditorActionListener(new OnEditorActionListener() { 
     private long lastCalled = -1; 

     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
      if (event.getEventTime() == lastCalled) { 
       return false; 
      } else { 
       lastCalled = event.getEventTime(); 
       handleNextButton(v); 
       return true; 
      } 
     } 
    }); 

    [...] 
} 

Le EditText est défini comme:

<EditText 
    android:layout_width="150sp" 
    android:layout_height="wrap_content" 
    android:id="@+id/txtBox" 
    android:imeOptions="actionNext" 
    android:capitalize="characters" 
    android:singleLine="true" 
    android:inputType="textVisiblePassword|textCapCharacters|textNoSuggestions" 
    android:autoText="false" 
    android:editable="true" 
    android:maxLength="6" 
/> 

sur tous les autres appareils sur lesquels j'ai testé, le bouton d'action est correctement étiqueté "Suivant" et l'événement n'est appelé qu'une seule fois lorsque ce bouton est enfoncé.

Est-ce un bug dans le clavier de Sense UI, ou est-ce que je fais quelque chose de mal?

Nous vous remercions de votre aide.


Mise à jour - grâce aux réponses données, j'ai établi les éléments suivants comme mes chèques. Cela fonctionne très bien sur les deux téléphones dont je dispose à tester (Sense UI et CyanogenMod CM7)

  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { 
       return false; 
      } 

      if (actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL) { 
       return false; 
      } 
+2

Pas de réponse pour vous J'ai peur, je voulais juste dire que j'ai été frappé par ce problème aujourd'hui. Je n'avais jamais vu le clavier HTC Sense avant aujourd'hui.Et comment ont-ils réussi à ignorer le drapeau textNoSuggestions? Rend mon interface un peu moche, les pourrir. –

+0

J'ai remarqué que beaucoup d'applications ne fonctionnent pas correctement puisque leur clavier n'implémente pas le bouton par défaut (c'est toujours "Enter"). Cela inclut les applications fournies par Google (y compris, je pense, le processus d'enregistrement initial). Il semble que ce soit une très grande chose pour HTC. C'est dommage, car j'aime beaucoup SenseUI sur Motoblur. Merci pour la confirmation. – mbafford

Répondre

26

Comme mitch dit, vous devez vérifier l'action de l'événement:

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
    if (event.getAction() != KeyEvent.ACTION_DOWN) 
     return false; 

    // do your stuff 

    return true; 
} 

Cet extrait fonctionne aussi bien sur l'interface utilisateur Sense et l'émulateur.

+2

Cela semble être presque la réponse, bien que sur mon autre téléphone (en cours d'exécution CyanogenMod CM7), "événement" est nulle lorsque j'appuie sur "Suivant" sur le clavier, donc je dois vérifier pour cela aussi bien. – mbafford

+1

J'ai également ajouté un "if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED) return false;" à la méthode. – AlexVogel

0

au lieu d'envoyer une action ime et nul comme un événement, il envoie un événement touche donc si vous n'êtes pas obtenir la une action correcte, vous pouvez vérifier l'événement pour action_up ou action_down

+1

Je ne comprends pas ce que vous dites ici. Y a-t-il un événement qui fonctionne correctement sur l'interface utilisateur de détection de HTC et sur les autres claviers qui implémentent correctement l'action par défaut? – mbafford

3
(EditText) passwordView = (EditText) findViewById(R.id.password); 
passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); 
    passwordView.setOnEditorActionListener(new OnEditorActionListener() 
     { 
      @Override 
      public boolean onEditorAction(TextView v, int actionId, KeyEvent event) 
      { 
       String input; 
       if(actionId == EditorInfo.IME_ACTION_DONE) 
       { 
        input= v.getText().toString(); 
        Toast toast= Toast.makeText(LogIn.this,input, 
          Toast.LENGTH_LONG); 
        toast.setGravity(Gravity.CENTER, 0, 0); 
        toast.show(); 
        return true; 
       } 
       return false; 
      } 
     }); 
0

Retour vrai; après la manipulation ur cas et il ne sera appelé à nouveau

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 

       if (actionId == EditorInfo.IME_NULL) 
       { 
        Log.i("here","Add product "); 
        return true; //this does the trick 
       } 
       return false; 
      }  
1

Je pense que si vous revenez vrai, cela signifie que vous êtes intéressé par le reste des événements jusqu'à ce qu'il atteigne IME_ACTION_DONE. Donc, si vous renvoyez false, cela signifie que vous n'êtes pas intéressé par les événements et que les autres vues auront alors la possibilité de le gérer. Puisque vous avez seulement 1 vue, je vous suggère d'ignorer le contrôle actionId et de retourner juste false à chaque fois.

etMovieName = (EditText) view.findViewById(R.id.et_movie_name); 
etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { 
     System.out.println("actionId= "+ actionId); 
     performSearch(); 
     return false; 
    } 
}); 

Autre situation est si vous avez des vues qui se chevauchent ou une vue de frères et soeurs, vous pouvez utiliser actionID pour transmettre des informations autour. Dans cette situation, renvoyer true vous permettra de transmettre des informations à l'autre vue. Si vous êtes vraiment intéressé par l'événement/actionID (par exemple si vous avez une autre vue de frères et soeurs), alors vous pouvez le faire:

etMovieName = (EditText) view.findViewById(R.id.et_movie_name); 

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); 
etMovieName.setSingleLine(); 

etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { 
     System.out.println("actionId= "+ actionId); 
     return performSearch();  } 
}); 

Notez la valeur actionID a changé à 6 fois que j'ajouté:

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); 
etMovieName.setSingleLine(); 
+1

Comportement très étrange, mais il semble que vous ayez exactement raison. –

Questions connexes