2011-06-18 1 views
4

J'ai un problème lorsque j'appuie sur/touchez en dehors d'un champ pour déclencher l'événement fieldChanged() pour le champ qui a le focus.BlackBerry touchEvent outside Champ déclencheurs fieldChanged

La mise en page pour mon MainScreen est assez simple, quelque chose comme ceci:

public class myMainScreen extends MainScreen implements FieldChangeListener{ 

    public myMainScreen(){ 
     CustomFM1 fm1 = new CustomFM1(); 
     CustomFM2 fm2 = new CustomFM2(); 

     add(fm1); 
     add(fm2); 
    } 

} 

Si je presse un bouton/champ à l'intérieur de l'une ou l'autre FieldManager il fonctionne très bien. Le problème est quand j'appuie sur l'espace vide. Donc, si je devais appuyer à l'intérieur de l'espace vide dans fm2 et un Field à l'intérieur fm1 avait focus, son événement fieldchanged serait déclenché.

Pour l'instant, mon remède est d'attraper le touchEvent et de le passer au FieldManager approprié. Le touchEvent pour mon CustomFM serait alors gérer obtenir le terrain et appeler fieldChanged, si un champ a été effectivement pressé

Ainsi, dans myMainScreen TouchEvent ressemble:

protected boolean touchEvent(TouchEvent message){ 

    int index = this.getFieldAtLocation(message.getX(1), message.getY(1)); 

    switch(index){ 

     case 0: 
      fm1.touchEvent(message); 
      break;  

     case 1: 
      fm2.touchEvent(message); 
      break; 

    } 

    return true; 
} 

Et mon touchEvent pour mon CustomFM2 est. OFFSET est la première position de fm2, par rapport à l'écran.

protected boolean touchEvent(TouchEvent message){ 

    switch(message.getEvent()){ 

    ... 

     case TouchEvent.UP: 
      int index = this.getFieldAtLocation(message.getGlobalX(1), message.getGlobalY(1) - OFFSET); 
      if(index != -1){ 
       Field field = getField(index); 
       field.getChangeListener().fieldChanged(field, 0); 

      } 

      break; 

    } 

    return true; 

} 

Ce que je me demande est que s'il y a une solution plus facile à cela? Est-ce que je manque quelque chose?

+0

Impossible de le reproduire avec le simulateur 5.0 9550: 2 gestionnaires de champs horizontaux, avec un champ de bouton click-consum dans chacun. Fonctionne bien. cliquer sur l'espace vide du gestionnaire ne déclenche pas l'événement FieldChangeListener. Quelle version/appareil vous utilisez? –

+0

@Max torche OS6. Je pense que je l'ai compris maintenant. la réponse à ce message a aidé [http://stackoverflow.com/questions/5948222/blackberry-click-outside-field]. Je vais poster une réponse dans un peu. Ce que je faisais au-dessus était un peu faux. –

+0

J'ai eu le même problème. Veuillez cocher la case [BlackBerry click outside Field] (http://stackoverflow.com/questions/5948222/blackberry-click-outside-field). – aeracode

Répondre

2

On dirait que ce que je faisais était un peu éteint. Je n'avais pas besoin de passer l'événement. Cela est fait naturellement (ou anormalement, car le Field qui a le focus semble recevoir l'événement TouchEvents s'il n'a pas été touché). Ce qui semble se produire est qu'après un TouchEvent.Click un navigationClick est envoyé sur le terrain. En navigationClick j'ai appelé fieldChangeNotify(0)

Pour résoudre ce problème mes Field « s touchEvent et navigationClick ressemble maintenant à ceci:

private boolean touchEventInside; 
    ... 

    protected boolean touchEvent(TouchEvent message) { 

     if(message.getX(1) < 0 || message.getX(1) > getWidth() || message.getY(1) < 0 || message.getY(1) > getHeight()) { 

      touchEventInside = false; 
      return false; 

     }else{ 

      touchEventInside = true; 
      return true; 

     } 

    } 

    protected boolean navigationClick(int status, int time) { 

     if(((myMainScreen)this.getScreen()).touchStarted){ 

      if(touchEventInside){ 
       fieldChangeNotify(0); 
      } 

     }else{ 

      fieldChangeNotify(0); 

     } 

     return true; 
    } 

Je garde aussi la trace des événements tactiles étant commencé à myMainScreen, comme ceci:

protected boolean touchStarted; 
    ... 
    protected boolean touchEvent(TouchEvent message){ 

     if(message.getEvent() == TouchEvent.UP){ 
      touchStarted = false; 
     }else if(message.getEvent() == TouchEvent.DOWN){ 
      touchStarted = true; 
     } 
     super.touchEvent(message); 
     return false; 

    } 
1

L'astuce consiste à ne pas surcharger touchEvent(TouchEvent message) du tout. :)

Il suffit de remplacer navigationClick(int status, int time) pour le champ que vous voulez gérer le clic (juste pour être clair - pas besoin de faire cela pour ButtonField - il fonctionne bien comme est). Le cadre BB UI appellera navigationClick(int status, int time) lorsque l'utilisateur clique sur votre champ sur un écran tactile. De plus, cela fonctionnera pour les appareils à écran non tactile.

+0

ouais j'ai essayé ça. Ce qui se passe est que lorsque je touche l'écran en dehors d'un champ, j'obtiens un 'TouchEvent.Click' suivi de' navigationClick', qui à son tour appelle 'fieldChangeNotify'. Je suppose que ça ne se passe pas sur OS5 mais c'est sur OS6 pour moi, sur l'appareil. –

3

Juste eu le même problème. Le problème principal est que navigationClick et trackwheelClick sont appelés si l'événement tactile n'est pas consommé dans touchEvent.

La solution est d'appeler fieldChangeNotify dans les méthodes *Clickque si le clic a été déclenché par un non tactile événement.événements tactiles sont donnés un statut de 0 afin que vous puissiez vérifier que comme suit:

protected boolean navigationClick(int status, int time){ 

    if (status != 0) fieldChangeNotify(0); 
    return true; 
} 

protected boolean trackwheelClick(int status, int time){   

    if (status != 0) fieldChangeNotify(0); 
    return true; 
} 

Cette méthode signifie que vous n'avez pas besoin de suivre si l'événement touche était dans les limites du champ.