黑莓菜单项问题

时间:2010-11-23 18:04:00

标签: java blackberry

我正在尝试在我的应用程序中实现一个菜单项。代码在这里用于BaseScreen类

package com.kcrw.ui;


import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.MainScreen;



public class BaseScreen extends MainScreen {

/*BaseScreen(){
super();
}*/
class NextQuesMenu extends MenuItem {

    public NextQuesMenu() {
        super("Live", 40, 10);
    }

    public void run() {

            UiApplication.getUiApplication().pushScreen(new LiveScreen());
            UiApplication.getUiApplication().popScreen(getScreen());

        }
    }

protected void makeMenu(Menu menu, int instance) {
       menu.add(new NextQuesMenu());
       super.makeMenu(menu, instance);
    }

}

现在我从LiveScreen类扩​​展此类

package com.kcrw.ui;
import net.rim.device.api.system.Bitmap;  
import net.rim.device.api.system.Display;  
import net.rim.device.api.ui.*;  
import net.rim.device.api.ui.component.*;  
import net.rim.device.api.ui.container.*;  
import com.kcrw.model.LiveStream;
import java.util.Vector;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import com.kcrw.model.LiveStream;
import com.kcrw.util.Constants;
import java.util.Vector;      

   public class LiveScreen extends BaseScreen {  

   private static final String NOT_FOUND = "Not Found";
    private static final String NEWS_CHANNEL = "NEWS CHANNEL";
    private static final String MUSIC_CHANNEL = "MUSIC CHANNEL";
    private static final String ON_AIR_NOW = "ON AIR NOW";
    public static LiveStream liveStream;
    public static LiveStream musicStream;
    public static LiveStream newsStream;
    public static DrawStyle topLive;
    public static DrawStyle bottomLive;
    MainScreen mainScreen; 
    /*switch (position) {
    case 0:
        if (liveStream.getProgram() == null)
            return;
        pid = "kcrwlive";
        url = liveStream.getProgram().getMobilePlayingImage()
                .getImageUrl();
        showUrl = liveStream.getProgram().getPageUrl();
        title = ON_AIR_NOW;
        desc = liveStream.getProgram().getDescription();
        if(bitRate==0) {
            audioUrl = Constants.liveAudioUrl_64k;
        } else {
            audioUrl = Constants.liveAudioUrl_128k;                     
        }
        break;
    case 1:
        if (musicStream.getProgram() == null)
            return;
        pid = "kcrwmusic";                  
        url = musicStream.getProgram().getMobilePlayingImage()
                .getImageUrl();
        showUrl = musicStream.getProgram().getPageUrl();
        title = MUSIC_CHANNEL;
        desc = musicStream.getProgram().getDescription();
        if(bitRate==0) {
            audioUrl = Constants.musicAudioUrl_64k;
        } else {
            audioUrl = Constants.musicAudioUrl_128k;                        
        }
        break;
    case 2:
        if (newsStream.getProgram() == null)
            return;
        pid = "kcrwnews";   
        url = newsStream.getProgram().getMobilePlayingImage()
                .getImageUrl();
        showUrl = newsStream.getProgram().getPageUrl();
        title = NEWS_CHANNEL;
        desc = newsStream.getProgram().getDescription();
        if(bitRate==0) {
            audioUrl = Constants.newsAudioUrl_64k;
        } else {
            audioUrl = Constants.newsAudioUrl_128k;                     
        }
        break;
    }

    intent.putExtra(PlayerActivity.ALBUM_ID, pid);
    intent.putExtra(PlayerActivity.ALBUM_TITLE, title);
    intent.putExtra(PlayerActivity.ALBUM_IMAGE_URL, url);
    intent.putExtra(PlayerActivity.ALBUM_AUDIO_URL, audioUrl);
    intent.putExtra(PlayerActivity.ALBUM_SHOW_URL, showUrl);                
    intent.putExtra(PlayerActivity.ALBUM_DESCRIPTION, desc);
    intent.putExtra(PlayerActivity.IS_PROGRAM, true);

    LiveActivity.this.startActivity(intent);
}
});

}*/

    public LiveScreen(){  
   //super();
  HorizontalFieldManager _hfm;  

  //The _vfm will hold the ListField and we'll add it to the _hfm  
 VerticalFieldManager _vfm;  

//Create the vars for ListField creation  
final ListField myList;  
ListCallback myCallback;  


   //Get the device width and height  
     final int width = Display.getWidth();  
    final int height = Display.getHeight();



//Create the mainScreen - this holds the _hfm and _vfm managers  
//MainScreen mainScreen;  
 mainScreen = new MainScreen();  

     //Private class that we will create in a minute  
   myCallback = new ListCallback();  
    myCallback.erase();  

myList = new MyListField();  
 myList.setCallback(myCallback);  

 //Populate the list with sample elements  
 for(int i=0;i<3;i++){  
      myList.insert(i);  
      myCallback.insert(ON_AIR_NOW , 0); 
      myCallback.insert(MUSIC_CHANNEL , 1);
      myCallback.insert(NEWS_CHANNEL , 2);

}  



 //Draw background gradient on this manager and add VerticalFieldManager for scrolling.  
    _hfm = new HorizontalFieldManager() {  

     public void paint(Graphics g)  
      {  


      //Variables for drawing the gradient  
     int[] X_PTS_MAIN = { 0, width, width, 0};   
       int[] Y_PTS_MAIN = { 0, 0, height, height };   
       int[] drawColors_MAIN = { Color.BLACK, Color.BLACK, Color.DARKBLUE, Color.DARKBLUE};  


      try {  
        //Draw the gradients     
          g.drawShadedFilledPath(X_PTS_MAIN, Y_PTS_MAIN, null, drawColors_MAIN, null);  

       } catch (IllegalArgumentException iae) {  
          System.out.println("Bad arguments.");   
       }  



       //Call super to paint the graphics on the inherited window   
       super.paint(g);  


      }  

    //Sublayout is passed the width and height of the parent window and will tell the window manager  
     //how to layout the buttons, images, etc.  
     protected void sublayout(int w, int h) {    

     //GetFieldCount returns the number of fields attached to the instance of this manager.  
    //and lays out the position  
             if (getFieldCount() >0) {                   

                    Field searchRes = getField(0);  
                   layoutChild(searchRes, width, height);  
                     setPositionChild(searchRes,0,0);  

               }  



              setExtent(width,height);  

        }  


  };  

   _vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL|Manager.USE_ALL_HEIGHT|Manager.USE_ALL_WIDTH) {  

          /*public void paint(Graphics g)  
            {  
                 g.setColor(Color.GRAY);    
                super.paint(g);  

             }  

         protected boolean navigationMovement(int dx, int dy, int status, int time){  
                this.invalidate();  
                return super.navigationMovement(dx,dy,status,time);  
                }  */

       protected void sublayout(int maxWidth, int maxHeight) {



            layoutChild(myList, maxWidth, maxHeight);
            setPositionChild(myList, 5, 385);

            setExtent(maxWidth, maxHeight);
        }
        };  




             //Add the list to the verticalFieldManager  
              _vfm.add(myList);  

              //Add the verticalFieldManager to the HorizontalFieldManager  
             _hfm.add(_vfm);  
            //Finally, add the HorizontalFieldManager to the MainScreen and push it to the stack   
             mainScreen.add(_hfm);  
              //pushScreen(mainScreen);  
             UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    UiApplication.getUiApplication().pushScreen(mainScreen);
                    //UiApplication.getUiApplication().popScreen(getActiveScreen());
                }
            });

       }//End Ctor  

 private class MyListField extends ListField{  


        //0,ListField.MULTI_SELECT  
         private boolean hasFocus = false;  

         public  void onFocus(int direction){  
           hasFocus = true;    
         }  

          public void onUnfocus()   
             {  
                    hasFocus = false;  
                     super.onUnfocus();  
                    invalidate();  
              }  

          public void paint(Graphics graphics)   
               {   int width = Display.getWidth();  
                    //Get the current clipping region   
                   XYRect redrawRect = graphics.getClippingRect();  
                    if(redrawRect.y < 0)  
                   {  
                      throw new IllegalStateException("Error with clipping rect.");  
                   }  

              //Determine the start location of the clipping region and end.  
                   int rowHeight = getRowHeight();  

                    int curSelected;  

                   //If the ListeField has focus determine the selected row.  
                   if (hasFocus)   
                 {  
                        curSelected = getSelectedIndex();  

                    }   
                  else   
                 {  
                  curSelected = -1;  
                 }  

                    int startLine = redrawRect.y / rowHeight;  
                    int endLine = (redrawRect.y + redrawRect.height - 1) / rowHeight;  
                   endLine = Math.min(endLine, getSize() - 1);  
                   int y = startLine * rowHeight;  

                    //Setup the data used for drawing.  
                   int[] yInds = new int[]{y, y, y + rowHeight, y + rowHeight};  
                    int[] xInds = new int[]{0, width, width, 0};  

                    //Set the callback - assuming String values.  
                  ListFieldCallback callBack = this.getCallback();  

                    //Draw each row  
                   for(; startLine <= endLine; ++startLine)   
                   {                 
                   //If the line we're drawing is the currentlySelected line then draw the fill path in LIGHTYELLOW and the   
                     //font text in Black.    
                 if(startLine == curSelected){  

                          graphics.setColor(Color.LIGHTYELLOW);  
                           graphics.drawFilledPath(xInds, yInds, null, null);  
                           graphics.setColor(Color.BLACK);  
                          graphics.drawText((String)callBack.get(this, startLine), 0, yInds[0]);  

                   }  
                  else{  
                          //Draw the odd or selected rows.  
                         graphics.setColor(Color.LIGHTGREY);  
                          graphics.drawText((String)callBack.get(this, startLine), 0, yInds[0]);  
                   }  

                   //Assign new values to the y axis moving one row down.  
                      y += rowHeight;  
                      yInds[0] = y;  
                      yInds[1] = yInds[0];  
                      yInds[2] = y + rowHeight;  
                      yInds[3] = yInds[2];  
                    }  

                   //super.paint(graphics);  
               }  
       }  

  //Private class to populate the ListField private variable  
   private class ListCallback implements ListFieldCallback{  


    private Vector listElements = new Vector();  

       public void drawListRow(ListField list, Graphics g,   
                           int index, int y, int w) {    

          String text = (String)listElements.elementAt(index);  
         g.setColor(Color.LIGHTGREY);  
          g.drawText(text, 0, y, 0, w);    
       }  

      public Object get(ListField list, int index) {    
         return listElements.elementAt(index);   
     }       

       public int indexOfList(ListField list, String p, int s) {    
          //return listElements.getSelectedIndex();  
         return listElements.indexOf(p, s);    
      }  


       public void insert(String toInsert, int index) {    
         listElements.insertElementAt(toInsert, index);    
       }  

      public void add(String toInsert){  
        listElements.addElement(toInsert);  
       }  

      public void erase() {    
          listElements.removeAllElements();    
       }  

   public int getPreferredWidth(ListField listField) {  

     return 0;  
    }     
   }
   }

然后我从SplashScreen&amp;中调用LiveScreen(显示列表项)类。推动LiveScreen

但是当我运行应用程序时,以及控件进入LiveScreen时。我点击菜单,但菜单项没有显示。任何人都可以指导我在哪里犯错误。

2 个答案:

答案 0 :(得分:2)

希望您会发现以下内容有帮助,如果您的问题没有得到解答,请随时回复并澄清您的问题。

当从BaseScreen启动菜单选项时,我会更新代码,使其包含对当前屏幕的引用,而不是使用getScreen()。这是因为pushScreen方法立即返回,对我来说,看起来你已经要求代码将屏幕推到堆栈上然后立即将其弹出。

以下是BaseScreen的变化:

    public void run() {
        UiApplication.getUiApplication().pushScreen(new LiveScreen());
        UiApplication.getUiApplication().popScreen(BaseScreen.this);
    }

在实时屏幕上查看用户选择的内容,您可以使用主屏幕中的navigatorClick方法。编码的示例使用内联MainScreen(我通常会把它放在自己的类中)。

如果您创建myList和myListCallback类变量或重新排列它们在构造函数中创建的顺序,那么您可以扩充mainScreen实例化以包含一个新的navigationClick方法,该方法可以找出所点击的内容。

以下是LiveScreen中的内容:

    final ListField myList;
    final ListCallback myCallback;

    ...

    // MainScreen mainScreen;
    mainScreen = new MainScreen(){
        protected boolean navigationClick(int status, int time) {
            int selected = myList.getSelectedIndex();
            if (selected != -1) {
                final Object o = myCallback.get(myList, selected);
                UiApplication.getUiApplication().invokeLater(new Runnable() {
                    public void run() {
                        Status.show("Clicked on "+o);
                    }
                });
            }
            return true;
        }
    };

答案 1 :(得分:0)

您确定要与LiveScreen交互吗?看起来像LiveScreen调用

UiApplication.getUiApplication().pushScreen(mainScreen);

所以我的猜测(猜测因为很难读取如此格式化的代码)你在顶部有一个主屏幕,这就是为什么它不能保存你的“实时”菜单项。