2011-05-17 46 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