2010-06-07 4 views
3

Merci à Max en this post, j'ai fait un menu horizontal. Mais maintenant j'essaye de faire un menu de superposition, je ne trouve pas comment faire ça ... Voyons ce que j'ai en premier.Blackberry menu horizontal OVERLAY personnalisé

Donc, j'ai un MapScreen de classe qui affiche ma carte:

public class MapScreen extends MenuScreen 

Ensuite, j'ai dans le même fichier la classe écran MENU comme celui-ci qui permet d'afficher le menu horizontal lorsque j'appuie sur la touche MENU:

abstract class MenuScreen extends MainScreen { 
boolean mMenuEnabled = false; 
CyclicHFManager mMenuManager = null; 

public MenuScreen() { 
    mMenuManager = new CyclicHFManager(); 
    mMenuManager.setBorder(BorderFactory.createBevelBorder(new XYEdges(4, 
      0, 0, 0), new XYEdges(Color.DARKBLUE, 0, 0, 0), new XYEdges(
      Color.WHITE, 0, 0, 0))); 
    mMenuManager.setBackground(BackgroundFactory 
      .createLinearGradientBackground(Color.DARKBLUE, Color.DARKBLUE, 
        Color.LIGHTBLUE, Color.LIGHTBLUE)); 


    for (int i = 0; i < 10; i++) { 
     Bitmap nBitmap = new Bitmap(60, 60); 
     Graphics g = new Graphics(nBitmap); 
     g.setColor(Color.DARKBLUE); 
     g.fillRect(0, 0, 60, 60); 
     g.setColor(Color.WHITE); 
     g.drawRect(0, 0, 60, 60); 
     Font f = g.getFont().derive(Font.BOLD, 40); 
     g.setFont(f); 
     String text = String.valueOf(i); 
     g.drawText(text, (60 - f.getAdvance(text)) >> 1, (60 - f 
       .getHeight()) >> 1); 

     Bitmap fBitmap = new Bitmap(60, 60); 
     g = new Graphics(fBitmap); 
     g.setColor(Color.DARKBLUE); 
     g.fillRect(0, 0, 60, 60); 
     g.setColor(Color.GOLD); 
     g.drawRect(0, 0, 60, 60); 
     g.setFont(f); 
     g.drawText(text, (60 - f.getAdvance(text)) >> 1, (60 - f 
       .getHeight()) >> 1); 

     BitmapButtonField button = new BitmapButtonField(nBitmap, fBitmap); 
     button.setCookie(String.valueOf(i)); 
     button.setPadding(new XYEdges(0, 18, 0, 18)); 

     button.setChangeListener(new FieldChangeListener() { 
      public void fieldChanged(Field field, int context) { 
       Dialog.inform("Button # " + (String) field.getCookie()); 
      } 
     }); 

     mMenuManager.add(button); 
    } 
} 

protected boolean keyDown(int keycode, int time) { 
    if (Keypad.KEY_MENU == Keypad.key(keycode)) { 
     if (mMenuManager.getManager() != null) { 
      delete(mMenuManager); 
      mMenuManager.mCyclicTurnedOn = false; 
     } else { 
      add(mMenuManager); 
      mMenuManager.getField(2).setFocus(); 
      mMenuManager.mCyclicTurnedOn = true; 
     } 
     return true; 
    } else { 
     return super.keyDown(keycode, time); 
    } 
}} 

Et enfin mon manager de menu:

public class CyclicHFManager extends HorizontalFieldManager { 
int mFocusedFieldIndex = 0; 
public boolean mCyclicTurnedOn = false; 

public void focusChangeNotify(int arg0) { 
    super.focusChangeNotify(arg0); 
    if (mCyclicTurnedOn) { 
     int focusedFieldIndexNew = getFieldWithFocusIndex(); 
     if (focusedFieldIndexNew != mFocusedFieldIndex) { 
      if (focusedFieldIndexNew - mFocusedFieldIndex > 0) 
       switchField(0, getFieldCount() - 1); 
      else 
       switchField(getFieldCount() - 1, 0); 
     } 
    } else { 
     mFocusedFieldIndex = getFieldWithFocusIndex(); 
    } 
} 

private void switchField(int prevIndex, int newIndex) { 
    Field field = getField(prevIndex); 
    delete(field); 
    insert(field, newIndex); 
}} 

Alors qu'il est comme ça, il fonctionne: lorsque j'appuie sur la touche MENU, le menu apparaît, je peux naviguer entre les boutons, et il disparaît quand j'appuie à nouveau sur la même touche. Le seul problème est que mon menu ne recouvre pas ma carte, il pousse le contenu vers le haut. J'ai essayé avec le gestionnaire de menu comme dans votre première réponse, redimensionnant le gestionnaire de contenu mais c'est le même résultat.

Max m'a donné le lien Blackberry - fields layout animation de le faire, mais je ne sais vraiment pas comment l'utiliser pour le faire fonctionner dans mon projet ...

Merci pour votre aide!

MISE À JOUR

Cela fonctionne très bien, il est ce que je voulais. Cependant, j'ai toujours un problème parce que je suis sous 4.5. Alors d'abord dans le constructeur MenuHostManager, je supprimé le

USE_ALL_HEIGHT 

et changer

setPositionChild(mMenuManager, 0, 
    Display.getHeight() - mMenuManager.getPreferredHeight()); 

comme celui-ci pour avoir le menu en bas de l'écran. Ça a marché.

Puis, au lieu de dessiner mes bitmaps, je l'ai fait:

Bitmap nBitmap = EncodedImage.getEncodedImageResource("menu" + 
    i + ".png").getBitmap(); 
BitmapButtonField button = new BitmapButtonField(nBitmap, nBitmap); 

Et cela a fonctionné trop (pas capotage pour l'instant, plus tard). Donc c'est génial!
Je remplace également la méthode Paint de mon CyclicHFManager pour avoir une couleur d'arrière-plan, car je ne peux pas utiliser BorderFactory et BackgroundFactory ... Ma barre de menu a une couleur pour le moment, donc c'est ok.
Ensuite, en raison de l'absence de ces 2 classes, dans mon BitmapButtonField, j'ai dû supprimer les 2 fonctions setBorder qui modifient les bordures. Et maintenant j'ai mes boutons assez gros comme des boutons normaux avec des bordures ...
Comment puis-je faire le même effet que les fonctions setBorder sous 4.5? (BTW, setBorder ne fonctionne pas sous 4.5 aussi ...).
Merci!

MISE À JOUR 2

Voir l'écran 5.0 avec ce code:

public BitmapButtonField(Bitmap normal, Bitmap focused) { 
    super(CONSUME_CLICK); 
    mNormal = normal; 
    mFocused = focused; 
    mWidth = mNormal.getWidth(); 
    mHeight = mNormal.getHeight(); 
    setMargin(0, 0, 0, 0); 
    setPadding(0, 0, 0, 0); 
    setBorder(BorderFactory 
      .createSimpleBorder(new XYEdges(0, 0, 0, 0))); 
    setBorder(VISUAL_STATE_ACTIVE, BorderFactory 
      .createSimpleBorder(new XYEdges(0, 0, 0, 0))); 
} 

Screenshot: i45.tinypic.com/4sz85u.jpg

Et sous 4.5 avec les 2 fonctions setBorder supprimées (car non disponible):

public BitmapButtonField(Bitmap normal, Bitmap focused) { 
    super(CONSUME_CLICK); 
    mNormal = normal; 
    mFocused = focused; 
    mWidth = mNormal.getWidth(); 
    mHeight = mNormal.getHeight(); 
    setMargin(0, 0, 0, 0); 
    setPadding(0, 0, 0, 0); 
} 

Screenshot: i49.tinypic.com/rartz5.jpg

Et je voudrais la première capture d'écran sous 5.0 mais 4.5!

MISE À JOUR 3

Je résolu le problème en ajoutant

protected void applyTheme() { 

} 

Il n'y a pas plus de frontières et il semble grand!

Je dois me concentrer sur mon rollover maintenant, puis sur l'action click (je n'ai pas de boîte de dialogue quand je clique dessus sur le simulateur). Je réussis aussi à changer l'arrière-plan de mon gestionnaire de menu, je dessine une image car je ne peux pas utiliser BackgroundFactory.createLinearGradientBackground.

Comment puis-je gérer mon rollover lorsque vous avez la fonction getVisualState()?

UPDATE 4

I modifier le BitmapButtonField un peu pour le rendre roulement sans utiliser getVisualState(). Je ne sais pas si c'est vraiment bon de le faire, mais il fonctionne (j'ai utilisé un bitmap temporaire mCurrent):

public class BitmapButtonField extends ButtonField { 
Bitmap mNormal; 
Bitmap mFocused; 
Bitmap mCurrent; 

int mWidth; 
int mHeight; 

public BitmapButtonField(Bitmap normal, Bitmap focused) { 
    super(CONSUME_CLICK); 
    mNormal = normal; 
    mFocused = focused; 
    mCurrent = normal; 
    mWidth = mNormal.getWidth(); 
    mHeight = mNormal.getHeight(); 
    setMargin(0, 0, 0, 0); 
    setPadding(0, 0, 0, 0); 
} 

protected void onFocus(int direction) { 
    mCurrent = mFocused; 
    invalidate(); 
} 

protected void onUnfocus() { 
    mCurrent = mNormal; 
    invalidate(); 
} 

protected void paint(Graphics graphics) { 
    Bitmap bitmap = mCurrent; 
    graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(), 
      bitmap, 0, 0); 
} 

protected void applyTheme() { 

} 

public int getPreferredWidth() { 
    return mWidth; 
} 

public int getPreferredHeight() { 
    return mHeight; 
} 

protected void layout(int width, int height) { 
    setExtent(mWidth, mHeight); 
} 
} 

MISE A JOUR 5

J'ai trouvé la solution. Mon menu fonctionne maintenant! Merci pour votre aide à propos de tout sur ce sujet! Je pourrais ouvrir un nouveau sujet pour le menu lui-même, car je ne suis pas sûr d'en faire un cyclique (compliqué en raison de la taille de l'écran et de la résolution à centrer et de l'icône au milieu). .java

protected boolean navigationMovement(int dx, int dy, int status, int time) { 
    if (mMenuHostManager.isActive()) { 
     return super.navigationMovement(dx, dy, status, time); 
    } 
    return mapField.navigationMovement(dx, dy, status, time); 
} 

protected boolean navigationClick(int status, int time) { 
    if (mMenuHostManager.isActive()) { 
     return super.navigationClick(status, time); 
    } 
    return true; 
} 

protected boolean navigationUnclick(int status, int time) { 
    if (mMenuHostManager.isActive()) { 
     return super.navigationUnclick(status, time); 
    } 
    return true; 
} 
+0

merci pour le Update4 BitmapButtonField a sauvé mon temps –

Répondre

0

alt text http://img534.imageshack.us/img534/9679/overlay1o.jpgalt text http://img243.imageshack.us/img243/4176/overlay2.jpg

Salut! L'écran a son propre gestionnaire de contenu et malheureusement nous ne pouvons pas faire de sublayout personnalisé au niveau de l'écran. Vous devrez déplacer le menu dans un gestionnaire séparé.

Voir code complet:

class Scr extends MenuScreen { 
    public Scr() { 
     mMenuHostManager.add(new LabelField(
       "Lorem ipsum dolor sit amet, consectetur " 
         + "adipiscing elit. Vestibulum egestas eleifend " 
         + "urna, in dictum erat auctor ac. Integer " 
         + "volutpat ultricies mauris eu accumsan. " 
         + "Quisque at euismod dui. Phasellus " 
         + "faucibus orci id libero interdum a " 
         + "feugiat lacus sodales. Nullam " 
         + "pulvinar vestibulum dolor " 
         + "rhoncus tristique.")); 
    } 
} 

class MenuScreen extends MainScreen { 
    MenuHostManager mMenuHostManager; 

    public MenuScreen() { 
     mMenuHostManager = new MenuHostManager(); 
     add(mMenuHostManager); 
    } 

    protected boolean keyDown(int keycode, int time) { 
     if (Keypad.KEY_MENU == Keypad.key(keycode)) { 
      mMenuHostManager.toggleMenu(); 
      return true; 
     } else { 
      return super.keyDown(keycode, time); 
     } 
    } 
} 

class MenuHostManager extends HorizontalFieldManager { 
    CyclicHFManager mMenuManager = null; 

    public MenuHostManager() { 
     super(USE_ALL_WIDTH | USE_ALL_HEIGHT); 
     mMenuManager = new CyclicHFManager(); 
     mMenuManager.setBorder(BorderFactory.createBevelBorder(
       new XYEdges(4, 0, 0, 0), new XYEdges(Color.DARKBLUE, 0, 0, 
         0), new XYEdges(Color.WHITE, 0, 0, 0))); 
     mMenuManager.setBackground(BackgroundFactory 
       .createSolidTransparentBackground(Color.DARKBLUE, 100)); 

     for (int i = 0; i < 10; i++) { 
      Bitmap nBitmap = new Bitmap(60, 60); 
      Graphics g = new Graphics(nBitmap); 
      g.setColor(Color.DARKBLUE); 
      g.fillRect(0, 0, 60, 60); 
      g.setColor(Color.WHITE); 
      g.drawRect(0, 0, 60, 60); 
      Font f = g.getFont().derive(Font.BOLD, 40); 
      g.setFont(f); 
      String text = String.valueOf(i); 
      g.drawText(text, (60 - f.getAdvance(text)) >> 1, (60 - f 
        .getHeight()) >> 1); 

      Bitmap fBitmap = new Bitmap(60, 60); 
      g = new Graphics(fBitmap); 
      g.setColor(Color.DARKBLUE); 
      g.fillRect(0, 0, 60, 60); 
      g.setColor(Color.GOLD); 
      g.drawRect(0, 0, 60, 60); 
      g.setFont(f); 
      g.drawText(text, (60 - f.getAdvance(text)) >> 1, (60 - f 
        .getHeight()) >> 1); 

      BitmapButtonField button = new BitmapButtonField(nBitmap, 
        fBitmap); 
      button.setCookie(String.valueOf(i)); 
      button.setPadding(new XYEdges(0, 18, 0, 18)); 

      button.setChangeListener(new FieldChangeListener() { 
       public void fieldChanged(Field field, int context) { 
        Dialog 
          .inform("Button # " 
            + (String) field.getCookie()); 
       } 
      }); 

      mMenuManager.add(button); 
     } 
    } 

    protected void sublayout(int width, int height) { 
     super.sublayout(width, height); 
     if (mMenuManager.getManager() != null) { 
      layoutChild(mMenuManager, mMenuManager.getPreferredWidth(), 
        mMenuManager.getPreferredHeight()); 
      setPositionChild(mMenuManager, 0, 0); 
     } 

    } 

    public void toggleMenu() { 
     if (mMenuManager.getManager() != null) { 
      delete(mMenuManager); 
      mMenuManager.mCyclicTurnedOn = false; 
     } else { 
      add(mMenuManager); 
      updateLayout(); 
      mMenuManager.getField(2).setFocus(); 
      mMenuManager.mCyclicTurnedOn = true; 
     } 
    } 
} 

class CyclicHFManager extends HorizontalFieldManager { 
    int mFocusedFieldIndex = 0; 
    public boolean mCyclicTurnedOn = false; 

    public void focusChangeNotify(int arg0) { 
     super.focusChangeNotify(arg0); 
     if (mCyclicTurnedOn) { 
      int focusedFieldIndexNew = getFieldWithFocusIndex(); 
      if (focusedFieldIndexNew != mFocusedFieldIndex) { 
       if (focusedFieldIndexNew - mFocusedFieldIndex > 0) 
        switchField(0, getFieldCount() - 1); 
       else 
        switchField(getFieldCount() - 1, 0); 
      } 
     } else { 
      mFocusedFieldIndex = getFieldWithFocusIndex(); 
     } 
    } 

    private void switchField(int prevIndex, int newIndex) { 
     Field field = getField(prevIndex); 
     delete(field); 
     insert(field, newIndex); 
    } 
} 

class BitmapButtonField extends ButtonField { 
    Bitmap mNormal; 
    Bitmap mFocused; 
    Bitmap mActive; 

    int mWidth; 
    int mHeight; 

    public BitmapButtonField(Bitmap normal, Bitmap focused) { 
     super(CONSUME_CLICK); 
     mNormal = normal; 
     mFocused = focused; 
     mWidth = mNormal.getWidth(); 
     mHeight = mNormal.getHeight(); 
     setMargin(0, 0, 0, 0); 
     setPadding(0, 0, 0, 0); 
     setBorder(BorderFactory 
       .createSimpleBorder(new XYEdges(0, 0, 0, 0))); 
     setBorder(VISUAL_STATE_ACTIVE, BorderFactory 
       .createSimpleBorder(new XYEdges(0, 0, 0, 0))); 
    } 

    protected void paint(Graphics graphics) { 
     Bitmap bitmap = null; 
     switch (getVisualState()) { 
     case VISUAL_STATE_NORMAL: 
      bitmap = mNormal; 
      break; 
     case VISUAL_STATE_FOCUS: 
      bitmap = mFocused; 
      break; 
     case VISUAL_STATE_ACTIVE: 
      bitmap = mFocused; 
      break; 
     default: 
      bitmap = mNormal; 
     } 
     graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(), 
       bitmap, 0, 0); 
    } 

    public int getPreferredWidth() { 
     return mWidth; 
    } 

    public int getPreferredHeight() { 
     return mHeight; 
    } 

    protected void layout(int width, int height) { 
     setExtent(mWidth, mHeight); 
    } 
} 
+0

Max, encore une fois, je vous remercie! Cela fonctionne très bien, c'est ce que je voulais. Cependant, j'ai toujours un problème parce que je suis sous 4.5. Donc d'abord dans le constructeur MenuHostManager, j'ai supprimé le USE_ALL_HEIGHT et change setPositionChild (mMenuManager, 0, Display.getHeight() - mMenuManager.getPreferredHeight()); comme ceci pour avoir le menu en bas de l'écran. Ça a marché. Ensuite, au lieu de dessiner mes bitmaps, j'ai fait ceci: Bitmap nBitmap = EncodedImage.getEncodedImageResource ("menu" + i + ".png"). GetBitmap(); BitmapButtonField button = nouveau BitmapButtonField (nBitmap, nBitmap); – Dachmt

+0

Et ça a marché aussi (pas de rollover pour l'instant, plus tard). Donc c'est génial! Je remplace aussi la méthode Paint de mon CyclicHFManager pour avoir une couleur d'arrière-plan, parce que je ne peux pas utiliser BorderFactory et BackgroundFactory ... Ma barre de menu a une couleur pour l'instant, donc c'est ok. Puis, à cause de ces 2 classes manquantes, dans mon BitmapButtonField j'ai dû supprimer les 2 fonctions setBorder qui changent les frontières.Et maintenant j'ai mes boutons assez gros comme des boutons normaux avec des bordures ... Comment puis-je faire le même effet que les fonctions setBorder sous 4.5? (BTW, setBorder ne fonctionne pas sous 4.5 aussi ...). Je vous remercie! – Dachmt

+0

De rien! :) Pour un texte volumineux, mieux vaut mettre à jour la question ou même en créer une nouvelle. Cependant, ce serait dupliquer dans ce cas: pour la frontière dans 4.5 regarder http://stackoverflow.com/questions/1135349/blackberry-how-to-add-border-to-basiceditfield –