1

I need a custom layout as below in BlackBerry.

enter image description here

I did same layout in Android. Now I need same layout in BlackBerry. I am new to BlackBerryapp development. The Fields of BlackBerry like Views in Android seem to be very confusing things to me.

I tried with VerticalFieldManager & HorizontalFieldManager by mixing these with BitmapField & LabelField to produce my layout.

I failed particularly in placing LabelField at bottom of screen. I used USE_ALL_HEIGHT & FIELD_BOTTOM style to put at bottom, but it is showing after scrolling long time.

My requirement is the header and footer should not scroll when my middle list is scrolling.

Nate
  • 31,017
  • 13
  • 83
  • 207
Yugandhar Babu
  • 10,311
  • 9
  • 42
  • 67

1 Answers1

2

The easiest way to add header and footer fields that don't scroll with the content in the middle of the screen is to use MainScreen#setBanner() and MainScreen#setStatus().Here's an example:

public class HeaderFooterListScreen extends MainScreen {

   private static final int BG_COLOR = Color.BLACK;
   private static final int HIGHLIGHT_COLOR = Color.BLUE;
   private static final int FONT_COLOR = Color.WHITE;
   private static final int ROW_HEIGHT = 60;

   private Object[] _rowData;
   private Field _header;
   private Field _footer;
   private Field _spacer;
   private int _orientation;

   public HeaderFooterListScreen() {
      super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

      Background bg = BackgroundFactory.createSolidBackground(BG_COLOR);
      setBackground(bg);
      getMainManager().setBackground(bg);

      // header
      Bitmap headerImg = Bitmap.getBitmapResource("header.png");
      _header = new BitmapField(headerImg);
      setBanner(_header);

      // list
      _rowData = new Object[] { "row one", "row two", "row three" }; //, "row four", "row five", "row six", "row seven", "row eight", "row nine", "row ten" };
      ListField list = new ListField();
      int c = Color.RED;
      XYEdges edgeColors = new XYEdges(c, c, c, c);
      XYEdges edgeThicknesses = new XYEdges(5, 5, 5, 5);
      list.setBorder(BorderFactory.createSimpleBorder(edgeThicknesses, edgeColors, Border.STYLE_SOLID));
      list.setCallback(new CustomListFieldCallback());
      list.setRowHeight(ROW_HEIGHT);
      list.setSize(_rowData.length);

      add(list);

      // footer
      _footer = new LabelField("Footer Showing Status As Text", Field.USE_ALL_WIDTH | DrawStyle.HCENTER) {
         public void paint(Graphics g) {
            // change font color
            int oldColor = g.getColor();
            g.setColor(FONT_COLOR);
            super.paint(g);
            g.setColor(oldColor);
         }
      };
      _footer.setFont(_footer.getFont().derive(Font.PLAIN, 24));
      setStatus(_footer);
   }    

   private void centerList() {
      if (_spacer != null && _spacer.getManager() != null) {
         // delete the old spacer field, if there was one      
         delete(_spacer);     
      }
      int listHeight = _rowData.length * ROW_HEIGHT;
      int availableHeight = getHeight() - _footer.getHeight() - _header.getHeight(); 
      if (availableHeight > listHeight) {
         boolean firstRun = (_spacer == null);
         // add a spacer above the list to force it down enough to be centered
         final int SPACE = (availableHeight - listHeight) / 2;         
         _spacer = new Field() {
            protected void layout(int width, int height) {
               setExtent(width, SPACE);              
            }
            protected void paint(Graphics graphics) {            
            }            
         };
         insert(_spacer, 0); 
         if (firstRun) {
            getMainManager().setVerticalScroll(0);
         }
      }
   }   

   // called when device orientation changes
   protected void sublayout(int width, int height) {
      super.sublayout(width, height);

      if (_orientation != Display.getOrientation()) {
         _orientation = Display.getOrientation();

         // run with invokeLater() to avoid recursive sublayout() calls
         UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
               // TODO: may have to adjust header, too?
               centerList();
            }
         });
      }
   }

   private class CustomListFieldCallback implements ListFieldCallback {

      private final int PAD = 10;

      public void drawListRow(ListField listField, Graphics graphics,
            int index, int y, int width) {

         int oldColor = graphics.getColor();
         if (listField.getSelectedIndex() == index) {
            graphics.setColor(HIGHLIGHT_COLOR);
         } else {
            graphics.setColor(BG_COLOR);
         }
         graphics.fillRect(0, y, width, listField.getRowHeight());

         graphics.setColor(FONT_COLOR);
         String text = (String)get(listField, index);               
         graphics.drawText(text, PAD, y + PAD, DrawStyle.LEFT);

         graphics.setColor(oldColor);
      }

      public Object get(ListField listField, int index) {
         return _rowData[index];
      }

      public int getPreferredWidth(ListField listField) {         
         return Display.getWidth();
      }

      public int indexOfList(ListField listField, String prefix, int start) {         
         return -1;  // TODO?
      }
   }
}

You didn't specify how you wanted the list in the middle to work, so I just made some guesses. I also wasn't sure if the red border was something you wanted, or just something you used to describe your layout. Edit your question, or post a new question, if you have more requirements for the list.

Field Concepts

If you're coming from Android, and are unclear about the role of BlackBerry UI classes, like Fields and Managers, here's some resources:

Results

enter image description here

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
  • Thanks for your answer, it is 99% solved my problem. And one more i forgot to tell in my question is, the list should be aligned vertically center between header and footer. – Yugandhar Babu Jul 19 '13 at 08:10
  • @YugandharBabu, if the list is full (enough rows to fill the screen), then it will essentially be centered between the header and footer. Are you saying that if it's not full (for example, has only 3 rows), you still want the list to be vertically centered? I just ask, because I'm not sure I've ever seen a UI like that. Normally, at least in cultures that read top-to-bottom, a short list would be aligned with the top of the screen (just under the header). Can you just verify for me that this is what you want? Thanks. – Nate Jul 19 '13 at 09:22
  • Yes. The list should be vertically centered even it contains less elements. I made such layout in android, but failed to get in blackberry. Anyway thanks for your answer. If the middle list with vertically center alignment is possible please tell me. – Yugandhar Babu Jul 19 '13 at 09:35
  • @YugandharBabu, see my updated answer. I added in code to put a spacer field above the list to center it vertically when the list does not fill the available space. I'm not sure this is the **easiest** way to do it, but these things can be overly complicated in BlackBerry Java. Also, I wasn't sure if your UI supports device rotation, but I added code in `sublayout()` to detect an orientation change, and adjust the spacer field, since a landscape orientation would need a smaller spacer. Hope this helps. – Nate Jul 20 '13 at 23:09