2011-05-17 94 views
3

我想移动an app从使用KeywordFilterField到ListField,我挣扎了几个小时才发现,为什么drawListRow()被调用不同ÿ值 - 这取决于这两个ListField的使用:黑莓:为什么drawListRow()调用不同的y为ListField和KeywordFilterField

如果getRowHeight()返回40,则ÿ值将是 -

对于KeywordFilterField是:0; 40; 80; 120; ...(即按预期)

但是对于列表字段我看到:9; 49; 89; 129; ...(即由于某种原因偏移)

9从哪里来? ListField或ListFieldCallback中是否有方法可以调用以获取此值?我只是试图在列表项之间画一条浅灰色的线。

listfield

下面是我的测试代码和border.png(用作BasicEditField边界)被附接:

border.png

package mypackage; 

import java.util.*; 
import net.rim.device.api.collection.*; 
import net.rim.device.api.collection.util.*; 
import net.rim.device.api.system.*; 
import net.rim.device.api.ui.*; 
import net.rim.device.api.ui.component.*; 
import net.rim.device.api.ui.container.*; 
import net.rim.device.api.ui.decor.*; 
import net.rim.device.api.util.*; 


public class MyList extends UiApplication { 
    public static void main(String args[]) { 
     MyList app = new MyList(); 
     app.enterEventDispatcher(); 
    } 

    public MyList() { 
     pushScreen(new MyScreen()); 
    } 
} 

class MyScreen extends MainScreen { 
    static final int EXTRA_ROWS = 2; 

    MyItemList myItems = new MyItemList(); 
    ListField myList = new ListField(EXTRA_ROWS); 

    Border myBorder = BorderFactory.createBitmapBorder(
     new XYEdges(12, 12, 12, 12), 
     Bitmap.getBitmapResource("border.png")); 

    Background myBg = BackgroundFactory.createSolidBackground(0x111111); 
    StringProvider myProvider = new StringProvider("Search"); 

    BasicEditField myFind = new BasicEditField(USE_ALL_WIDTH) { 
     protected void paint(Graphics g) { 
      if (getTextLength() == 0) { 
       g.setColor(Color.LIGHTGRAY); 
       g.drawText(myProvider.toString(), 0, 0); 
      } 

      g.setColor(Color.BLACK); 
      super.paint(g); 
     } 
    }; 

    public MyScreen() { 
     getMainManager().setBackground(myBg); 

     myFind.setBorder(myBorder); 
     setTitle(myFind); 

     myItems.doAdd(new MyItem(1, "Eins")); 
     myItems.doAdd(new MyItem(2, "Zwei")); 
     myItems.doAdd(new MyItem(3, "Drei")); 
     myItems.doAdd(new MyItem(4, "Vier")); 

     myList.setCallback(new MyListFieldCallback()); 
     add(myList); 
    } 

    private class MyListFieldCallback implements ListFieldCallback { 

     public void drawListRow(ListField list, Graphics g, int index, int y, int width) { 
      System.err.println("XXX index=" + index+ ", y=" + y + ", width=" + width); 

      g.setColor(Color.WHITE); 

      if (index < EXTRA_ROWS) { 
       Font i = getFont().derive(Font.ITALIC); 
       g.setFont(i); 
       g.drawText("Add Item", 0, y); 
       return; 
      } 

      if (index >= EXTRA_ROWS) { 
       MyItem item = (MyItem) myItems.getAt(index - EXTRA_ROWS); 
       g.drawText(item.toString(), 0, y); 

       g.setColor(0x333333); 
       // XXX why do I need to subtract 9 here? 
       g.drawLine(0, y-9, width, y-9); 

       return; 
      } 

      g.drawText(list.getEmptyString(), 0, y); 
     } 

     public Object get(ListField list, int index) { 
      return myItems.getAt(index); 
     } 

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

     public int indexOfList(ListField list, String prefix, int start) { 
      return 0; 
     } 
    } 

    class MyItemList extends SortedReadableList { 
     public MyItemList() { 
      super(new MyItem.MyComparator());   
     } 

     protected void doAdd(Object obj) { 
      super.doAdd(obj); 
      myList.setSize(size() + EXTRA_ROWS); 
     } 

     protected boolean doRemove(Object obj) { 
      myList.setSize(size() - 1 + EXTRA_ROWS); 
      return super.doRemove(obj);   
     } 
    } 
} 

class MyItem { 
    int _num; 
    String _name; 

    public MyItem(int num, String name) { 
     _num = num; 
     _name = name; 
    } 

    public String toString() { 
     return _num + ": " + _name; 
    } 

    static class MyComparator implements Comparator { 
     public int compare(Object obj1, Object obj2) { 
      MyItem item1 = (MyItem) obj1; 
      MyItem item2 = (MyItem) obj2; 

      return item1.toString().compareTo(item2.toString()); 
     } 
    } 

    static class MyProvider implements KeywordProvider { 
     public String[] getKeywords(Object obj) { 
      MyItem item = (MyItem) obj; 
      return new String[]{ Integer.toString(item._num), item._name }; 
     } 
    } 
} 

所产生的输出是:

[ 64,890] XXX index=0, y=9, width=360 
[ 64,890] XXX index=1, y=49, width=360 
[ 64,898] XXX index=2, y=89, width=360 
[ 64,898] XXX index=3, y=129, width=360 
[ 64,906] XXX index=4, y=169, width=360 
[ 64,906] XXX index=5, y=209, width=360 

更新在代表LY到jprofitt

当我尝试你的建议(我用红色为您的文本和线条):

if (index >= EXTRA_ROWS) { 
     MyItem item = (MyItem) myItems.getAt(index - EXTRA_ROWS); 
     g.drawText(item.toString(), 0, y); 

     g.setColor(Color.RED);     
     g.drawText("XXX", 0, y + (list.getRowHeight() - list.getFont().getHeight())/2); 

     g.setColor(0x333333); 
     // XXX why do I need to subtract 9 here? 
     g.drawLine(0, y-9, width, y-9); 

     g.setColor(Color.RED); 
     g.drawLine(0, y, width, y); 
     return; 
    } 

然后它并没有真正的工作 - 因为蓝色重点线不对齐的建议(红色)线。它对齐与我(灰)线,这意味着你真的需要减去-9出于某种原因:

not aligned

谢谢! 亚历克斯

+0

也许检查是否有某些填充由于某种原因被添加。我过去观察过这种行为,我想说填充或边距是问题。 – jprofitt 2011-05-17 14:34:06

+0

我同意,但哪种方法会打印该填充?我不想将9硬编码到我的应用程序中。 – 2011-05-17 14:38:53

+0

我会检查列表和包含管理器getPaddingTop/Bottom()和getMarginTop/Bottom() – jprofitt 2011-05-17 15:39:31

回答

2

是的,这是一个奇怪的行为。我想这是具体的操作系统6。看起来像在OS 6 ListField变得如此聪明,它通过了Y坐标已准备直接用于文字绘图,所以你不必手动计算(通常我用jprofitt建议的相同方式计算Y的文本绘图)。所以假设我的猜测是真的,我改变了代码如下:

if (index >= EXTRA_ROWS) { 
    MyItem item = (MyItem) myItems.getAt(index - EXTRA_ROWS); 
    g.drawText(item.toString(), 0, y); 

    g.setColor(0x333333); 
    // XXX why do I need to subtract 9 here? 

    // use the offset instead 
    int offset = (myList.getRowHeight() - getFont().getHeight()) >> 1; 

    g.drawLine(0, y - offset, width, y - offset); 

    return; 
} 

它工作正常(在设备设置中可用的所有字体大小进行测试)。

2

好吧我相信我得到了这个想通了。发生什么事是你的行高比字体高度大。所以当你在y上绘制文本时,你正在将它绘制到实际行的顶部。在我的情况下,行高为40,字体高度为20.这种差异的一半是你的y-9进入的地方。如果你改变你的drawText()调用,它应该工作,而不需要在绘制line:

g.drawText(theString, 0, y + (list.getRowHeight() - list.getFont().getHeight())/2); 

您可以缓存字体高度和行高,因此您不必在paint()中进行计算,以提高效率。

+0

对不起,对我不起作用,因为蓝色焦点没有对齐 - 请参阅上面的更新文本和屏幕截图。 – 2011-05-23 13:10:58