1

我有很长的文本内容,我想在屏幕上显示它,并使用或其他方式对齐对齐。LabelField目前,我可以做右/左/中心对齐,但不能证明对齐。

是否有任何自定义控件可以帮助我做到这一点?

4

1 回答 1

2

这只是一个原型,所以可能有些事情它无法处理。但是,它应该是一个开始,你可以用它来做你想做的事。大多数重要的逻辑都在paint()方法中。

我不知道有任何内置(RIM 库)方法可以做到这一点。

public class JustifiedLabelField extends LabelField {

   /** a cache of the label's words, to avoid having to recalculate every
       time paint() is called */
   private String[] _words;
   /** the dynamic field height */
   private int _height = 0;

   public JustifiedLabelField(Object text, long style){
      super(text, style);
      setText(text);
   }

   public void setText(Object text) {
      // update the words cache when text changes
      _words = split((String)text, " ");  // NOTE: this only supports String type!
      super.setText(text);
   }

   public int getPreferredHeight() {
      // I believe overriding this method is necessary because the 
      //  justification might produce a different total number of lines, 
      //  depending on the algorithm used
      return (_height > 0) ? _height : super.getPreferredHeight();
   }

   protected void paint(Graphics g) {
      Font font = g.getFont();
      int space = font.getAdvance(' ');
      int fontHeight = font.getHeight();
      int fieldWidth = getWidth();         
      int word = 0;
      int y = 0;
      while (word < _words.length) {
         // each iteration of this loop handles one line
         int wordsInLine = 0;
         int lineWordWidths = 0;
         // first loop over all words that fit on this line, to measure
         while (word < _words.length) {
            int wordWidth = font.getAdvance(_words[word]);
            if (lineWordWidths + wordWidth <= fieldWidth) {
               lineWordWidths += (wordWidth + space);
               word++;
               wordsInLine++;
            } else {
               break;
            }
         }

         // how much total space (gap) should be placed between every two words?
         int gapSpacing = 0;
         if (word == _words.length) {
            // don't justify at all on last line
            gapSpacing = space;
         } else if (wordsInLine != 1) {
            gapSpacing = (fieldWidth - (lineWordWidths - wordsInLine * space)) / (wordsInLine - 1);
         }

         int x = 0;
         // now actually draw the words, with added spacing
         for (int j = word - wordsInLine; j < word; j++) {
            int span = g.drawText(_words[j], x, y);
            x += span + gapSpacing;            
         }

         y += fontHeight;
      }
      _height = y;
   }
}

上面的代码使用了一个String split()方法。您可以在此处找到一种可能的实现方式

然后,像这样使用类:

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

      String loremIpsum = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam cursus. Morbi ut mi. Nullam enim leo, egestas id, condimentum at, laoreet mattis, massa. Sed eleifend nonummy diam. Praesent mauris ante, elementum et, bibendum at, posuere sit amet, nibh. Duis tincidunt lectus quis dui viverra vestibulum. Suspendisse vulputate aliquam dui. Nulla elementum dui ut augue. Aliquam vehicula mi at mauris. Maecenas placerat, nisl at consequat rhoncus, sem nunc gravida justo, quis eleifend arcu velit quis lacus. Morbi magna magna, tincidunt a, mattis non, imperdiet vitae, tellus. Sed odio est, auctor ac, sollicitudin in, consequat vitae, orci. Fusce id felis. Vivamus sollicitudin metus eget eros.";
      JustifiedLabelField label = new JustifiedLabelField(loremIpsum, Field.NON_FOCUSABLE);
      add(label);
   }

产生这个:

在此处输入图像描述

限制

  • 我没有做任何事情来解释这个领域中的填充之类的事情
  • LabelField允许您使用其他类型调用setText()或构造函数,而不仅仅是String. 我的班级只支持String,但您可以轻松扩展它。
  • ' '我的班级仅在空格 ( )上拆分字符串。您可能希望支持拆分其他字符,甚至插入破折号来打断非常长的单词。我会把它留给你。
  • 我没有测试任何边缘情况,比如长度超过字段宽度的单词。我只用全屏宽度字段测试了这个,用中小字。
  • 请参阅 Eugen 在我链接到的页面上的评论以了解所使用的split()方法

跟进

我对上面发布的代码进行了一些改进,并在此处在线发布。较新的版本应该处理填充,而这个版本没有。LabelField如果您选择一个字符串拆分算法来更改超类认为该字段应该有多少行,它还应该处理垂直大小问题。更多评论,也是。

于 2013-03-03T06:52:49.930 回答