【问题标题】:Custom layout in blackberry黑莓中的自定义布局
【发布时间】:2013-07-21 07:05:50
【问题描述】:

我需要在 BlackBerry 中进行如下自定义布局。

我在 Android 中做了同样的布局。现在我需要在 BlackBerry 中使用相同的布局。我是 BlackBerryapp 开发的新手。 BlackBerry 的 Fields 像 Android 中的 Views 对我来说似乎很混乱。

我尝试将VerticalFieldManagerHorizontalFieldManagerBitmapFieldLabelField 混合以生成我的布局。

我特别失败了将LabelField 放在屏幕底部。我用USE_ALL_HEIGHT & FIELD_BOTTOM 样式放在底部,但是滚动很长时间后才显示。

我的要求是当我的中间列表滚动时,页眉和页脚应该滚动。

【问题讨论】:

  • 您需要支持哪个最低操作系统级别? 5.0? 6.0?等等...

标签: blackberry java-me


【解决方案1】:

添加随着屏幕中间的内容滚动的页眉和页脚字段的最简单方法是使用MainScreen#setBanner()MainScreen#setStatus()。下面是一个示例:

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?
      }
   }
}

你没有具体说明你希望中间的列表如何工作,所以我只是做了一些猜测。我也不确定红色边框是你想要的,还是你用来描述布局的东西。如果您对列表有更多要求,请编辑您的问题或发布新问题。

字段概念

如果您来自 Android,并且不清楚 BlackBerry UI 类(例如 FieldsManagers)的作用,这里有一些资源:

结果

【讨论】:

  • 感谢您的回答,我的问题已经解决了 99%。还有一个我忘了告诉我的问题是,列表应该在页眉和页脚之间垂直居中对齐。
  • @YugandharBabu,如果列表已满(有足够的行填满屏幕),那么它基本上会在页眉和页脚之间居中。你是说如果它不满(例如,只有 3 行),你还希望列表垂直居中吗?我只是问,因为我不确定我是否见过这样的 UI。通常,至少在从上到下阅读的文化中,一个简短的列表将与屏幕顶部对齐(就在标题下方)。你能帮我验证一下这是你想要的吗?谢谢。
  • 是的。即使包含较少的元素,列表也应该垂直居中。我在android中做了这样的布局,但没能进入黑莓。无论如何感谢您的回答。如果可以使用垂直居中对齐的中间列表,请告诉我。
  • @YugandharBabu,请参阅我的更新答案。我在代码中添加了一个间隔字段,以在列表未填充可用空间时将其垂直居中。我不确定这是不是最简单的方法,但这些事情在 BlackBerry Java 中可能过于复杂。此外,我不确定您的 UI 是否支持设备旋转,但我在 sublayout() 中添加了代码来检测方向变化,并调整间隔字段,因为横向需要更小的间隔。希望这会有所帮助。
猜你喜欢
  • 2010-12-15
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多