【问题标题】:How to justify LabelField in Blackberry如何在黑莓中证明 LabelField 的合理性
【发布时间】:2013-03-11 10:30:07
【问题描述】:

我有很长的文本内容,我想用justify alignment 或其他东西在屏幕上显示它。目前,我可以进行右/左/居中对齐但不能justify对齐。

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

【问题讨论】:

  • 请注意,在您接受我的回答后,我在我的博客上发布了一个更好版本的答案代码,链接到我的答案底部。它处理这里没有问到的问题,但更冗长,所以我把答案留在这里。

标签: blackberry


【解决方案1】:

这只是一个原型,所以可能有些事情它无法处理。但是,它应该是一个开始,你可以用它来做你想做的事。大多数重要的逻辑都在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() 方法。你可以找到one possible implementation here

然后,像这样使用类:

   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,但您可以轻松扩展它。
  • 我的班级仅将字符串拆分为空格 (' ')。您可能希望支持拆分其他字符,甚至插入破折号来打断非常长的单词。我会把它留给你。
  • 我没有测试任何边缘情况,比如长度超过字段宽度的单词。我只使用全屏宽度字段进行了测试,其中包含中小型字。
  • the page I link to 上查看 Eugen 的 cmets,了解所使用的 split() 方法

跟进

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多