2012-04-06 2 views
4

Je développe une application dans BlackBerry et j'ai beaucoup HorizontalFieldManager s remplis de composants comme le montre l'image ci-dessous:Comment rendre un HorizontalFieldManager cliquable dans BlackBerry?

My HorizontalFieldManager filled with components

Et je dois ajouter beaucoup HorizontalFieldManager s comme celles-ci dans une boucle qui for sont dynamiquement peuplés. Lorsque pris ensemble, il ressemble à une seule rangée dans une liste. Jusqu'à présent, j'ai été capable de le faire.

Mais le problème est, l'utilisateur devrait pouvoir cliquer sur une "rangée" comme ceci. Mais comme le HorizontalFieldManager n'est pas focalisable ou cliquable, et parce qu'il a 4 composants à l'intérieur et que les 4 sont tout aussi importants, je n'ai pas réussi à trouver un moyen de le faire.

Donc, quelqu'un peut-il s'il vous plaît suggérer un moyen de faire ce que je suis en train d'essayer? Fondamentalement, l'utilisateur devrait pouvoir cliquer sur une "rangée" qui est montrée dans l'image. Cette "rangée" est constituée de nombreux composants (2 HorizontalFieldManager s, 1 VerticalFieldManager, 1 BitmapField et 3 LabelFields).

Toute aide grandement appréciée!

Répondre

2

Le code ci-dessous rendra votre HorizontalFieldManager cliquable, et ajouter votre composant dans ce Hfm que vous voulez.

import net.rim.device.api.system.Display; 
import net.rim.device.api.ui.Color; 
import net.rim.device.api.ui.Field; 
import net.rim.device.api.ui.FieldChangeListener; 
import net.rim.device.api.ui.Graphics; 
import net.rim.device.api.ui.Manager; 
import net.rim.device.api.ui.TouchEvent; 
import net.rim.device.api.ui.Touchscreen; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 
import net.rim.device.api.ui.component.LabelField; 
import net.rim.device.api.ui.component.NullField; 
import net.rim.device.api.ui.container.HorizontalFieldManager; 
import net.rim.device.api.ui.container.MainScreen; 

public class sample extends MainScreen implements FieldChangeListener{ 

HorizontalFieldManager logInDetailManager=null; 
int background_color=0; 

public sample() { 

logInDetailManager = new HorizontalFieldManager(Manager.USE_ALL_WIDTH|Field.FOCUSABLE){ 
    protected void sublayout(int maxWidth, int maxHeight) { 
      int height=40; 
     super.sublayout(Display.getWidth(), height); 
     setExtent(Display.getWidth(), height); 
    } 
    protected void paint(Graphics graphics) { 

     graphics.setBackgroundColor(background_color); 
     graphics.clear(); 
     invalidate(); 
     super.paint(graphics); 
    } 
    protected void onFocus(int direction) { 
     super.onFocus(direction); 
     background_color=Color.RED; 
     invalidate(); 
    } 
    protected void onUnfocus() { 
     invalidate(); 
     background_color=Color.GREEN; 

    } 
    protected boolean navigationClick(int status, int time) { 

     if(Touchscreen.isSupported()){ 
      return false; 
     }else{ 
      fieldChangeNotify(1); 
      return true; 
     } 

    } 
    protected boolean touchEvent(TouchEvent message) 
    { 
     if (TouchEvent.CLICK == message.getEvent()) 
     { 
      FieldChangeListener listener = getChangeListener(); 
      if (null != listener) 
       this.setFocus(); 
       listener.fieldChanged(this, 1); 
     } 
     return super.touchEvent(message); 
    } 
}; 
logInDetailManager.setChangeListener(this); 
logInDetailManager.add(new LabelField("hello")); 
logInDetailManager.add(new NullField(Field.FOCUSABLE)); 
add(logInDetailManager); 
add(new LabelField("good",Field.FOCUSABLE));  
} 

    public void fieldChanged(Field field, int context) {    
if(field==logInDetailManager){     
    UiApplication.getUiApplication().invokeLater(new Runnable() {       
     public void run() {         
      Dialog.inform("Hi how are you?");       
     }      
    });   
} 
} 

} 

J'espère que cela vous aidera. Salutations :)

+0

Son fonctionne parfaitement! Merci beaucoup :) Pouvez-vous s'il vous plaît me dire quel est le but de la partie - UiApplication.getUiApplication(). InvokeLater (new Runnable() {}); 'et à l'intérieur, montrant un dialogue VS montrant une boîte de dialogue directement? – Roshnal

+0

Votre code fonctionne très bien, mais mon application est soudainement devenu très lent et laggy ... Une idée pourquoi c'est? Je pense que cela a quelque chose à voir avec mon application ayant environ 150+ 'HorizontalFieldManager's? – Roshnal

+0

si vous n'utilisez pas UiApplication.getUiApplication().invokeLater (new Runnable() {}); 'vous obtiendrez l'exception d'exécution. Parce que vous n'êtes pas sur le fil de l'événement. – BBdev

3

BBdev directement répondu à votre question, mais comme vous l'avez remarqué, la performance est assez lente. En effet, l'utilisation d'un gestionnaire pour supprimer des centaines de lignes comme celles-ci ajoute beaucoup de temps à l'étape de mise en page de l'interface utilisateur. La mise en page s'exécutera contre tous ces gestionnaires, chaque fois que quelque chose change à l'écran - y compris chaque fois que vous ajoutez une nouvelle ligne. C'est fondamentalement quadratique.

La manière d'accélérer cela est d'utiliser un ListField à la place. Le point de douleur d'un ListField est que vous devez faire le dessin directement, au lieu de vous fier aux champs du système d'exploitation standard. Mais l'avantage est que le ListField fonctionne très rapidement - chaque ligne a une hauteur fixe, donc le ListField peut rapidement déterminer quelles lignes sont visibles, puis appeler le code de peinture juste pour ces lignes.

Cela signifie que les échelles de travail avec la taille visible du champ, au lieu de la taille virtuelle du champ. C'est une propriété très souhaitable à maintenir lors de l'écriture de code UI, car la profondeur virtuelle d'une interface n'a pas de limites, mais l'écran physique a un nombre fixe de pixels, donc en mettant à l'échelle le travail avec la partie visible de l'interface utilisateur. bonne performance.

+0

Merci beaucoup pour l'explication! Je ne pensais pas que ça fonctionnait de cette façon .. Mais pouvez-vous s'il vous plaît me dire un moyen d'obtenir l'interface affichée dans l'image en utilisant un 'ListField'? Je veux dire, l'image sur la droite, et le multiple 'LabelField's, et ainsi de suite? – Roshnal

+0

Vous devrez faire votre propre dessin de ligne en utilisant toutes les méthodes de l'objet Graphics. Un LabelField appelle simplement Graphics.drawText, vous pouvez donc le faire dans le code de dessin de la ligne. –

0

Comment gérer la couleur de mise au point lorsque vous avez un tableau de champs horizontaux à la place?

for (int i = 0; i < listSize; i++) { 
     logInDetailManager[i] = new HorizontalFieldManager(
       Manager.USE_ALL_WIDTH | Field.FOCUSABLE) { 

Étant donné qu'un élément de la matrice est toujours focalisé, la liste entière est entièrement rouge.

Questions connexes