0

我试图在 ListField 的顶部显示一个额外的行 - 称为“添加项目”,它几乎可以工作,但我的数据的最后一行“项目 4”没有显示。

屏幕截图,缺少 1 行

你会如何解决这个问题?

请看下面我非常简单的测试代码MyList.java

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 {

    ObjectListField myList = new ObjectListField() {
        public void drawListRow(ListField list,
                        Graphics g,
                        int index,
                        int y,
                        int width) {
            if (index == 0) {
                Font i = getFont().derive(Font.ITALIC);
                g.setFont(i);
                g.drawText("Add Item", 0, y);
            } else {
                String str = (String) get(this, index - 1);
                g.drawText(str, 0, y);
            }                
        }

        protected boolean navigationClick(int status, int time) {
            int index = myList.getSelectedIndex();
            String str = (index > 0 ? (String) get(this, index - 1) : 
                "Add item");
            Status.show("You have clicked: " + str);
            return true;
        }
    };

    public MyScreen() {
        setTitle("How to display an extra row?");
        myList.set(new String[]{"Item 1","Item 2","Item 3","Item 4",});
        // myList.setSize(5);
        add(myList);
    }
}

我试过添加myList.setSize(5); 但得到 Vector.elementAt(4) 抛出的 ArrayIndexOutOfBoundsException

更新:

根据 Michael 的建议,我已从 ObjectListField 切换到 KeywordFilterField(这是我在实际程序中实际使用的),现在我可以调用myList.setSize(5)而不会引发任何异常。

但是最后一行仍然没有显示:

截屏

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 = 1;

    MyItemList myItems = new MyItemList();
    KeywordFilterField myList = new KeywordFilterField() {
        protected boolean navigationClick(int status, int time) {
            int index = getSelectedIndex();
            String str = (index < EXTRA_ROWS ? "Add item" :
                ((MyItem) getElementAt(index - EXTRA_ROWS)).toString());
            Status.show("You have clicked - " + str);
            return true;
        }
    };

    public MyScreen() {
        setTitle(myList.getKeywordField());
        myList.setSourceList(myItems, new MyItem.MyProvider());
        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.setSourceList(myItems, new MyItem.MyProvider());
        myList.setCallback(new MyListFieldCallback());
        myList.setSize(myItems.size() + EXTRA_ROWS);
        myList.updateList();
        add(myList);
    }

    private class MyListFieldCallback implements ListFieldCallback {

        public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
            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) ((KeywordFilterField) list).getElementAt(index - EXTRA_ROWS);
                g.drawText(item.toString(), 0, y);
                return;
            }

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

        public Object get(ListField listField, int index) { 
            return null; 
        }

        public int getPreferredWidth(ListField listField) { 
            return 0; 
        }

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

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

    protected void doAdd(Object obj) {
        super.doAdd(obj);   
    }

    protected boolean doRemove(Object obj) {
        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 };
        }
    }
}

我有一种感觉,在两者之间调用了setSize(4)(而不是 5)——因为我看到最后一行一会儿,然后它又消失了。

谢谢!亚历克斯

4

3 回答 3

1

您不想使用 ObjectListField,在类型层次结构中上一层到ListField,然后您可以随意执行 setSize() 。

于 2011-05-09T16:12:28.167 回答
0

我想这应该可行:

public MyScreen() {
    setTitle("How to display an extra row?");
    myList.set(new String[] { "Add Item", "Item 1","Item 2","Item 3","Item 4"});
    add(myList);
}

还是我错过了什么?:)

于 2011-05-09T14:48:42.630 回答
0

这是我自己的解决方案 - 覆盖 ListField 的 setSize():

在此处输入图像描述

(上面的屏幕截图有 EXTRA_ROWS = 3,仍然可以正常工作)。

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 = 3;

    MyItemList myItems = new MyItemList();
    KeywordFilterField myList = new KeywordFilterField() {
        protected boolean navigationClick(int status, int time) {
            int index = getSelectedIndex();
            String str = (index < EXTRA_ROWS ? "Add item" :
                ((MyItem) getElementAt(index - EXTRA_ROWS)).toString());
            Status.show("You have clicked - " + str);
            return true;
        }

        public void setSize(int count) {
            super.setSize(count + EXTRA_ROWS);
        }
    };

    public MyScreen() {
        setTitle(myList.getKeywordField());
        myList.setSourceList(myItems, new MyItem.MyProvider());
        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.setSourceList(myItems, new MyItem.MyProvider());
        myList.setCallback(new MyListFieldCallback());
        add(myList);
    }

    private class MyListFieldCallback implements ListFieldCallback {

        public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
            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) ((KeywordFilterField) list).getElementAt(index - EXTRA_ROWS);
                g.drawText(item.toString(), 0, y);
                return;
            }

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

        public Object get(ListField listField, int index) { 
            return null; 
        }

        public int getPreferredWidth(ListField listField) { 
            return 0; 
        }

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

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

    protected void doAdd(Object obj) {
        super.doAdd(obj);   
    }

    protected boolean doRemove(Object obj) {
        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 };
        }
    }
}
于 2011-05-10T14:10:34.390 回答