Blackberry:如何过滤列表字段表示的行?
我正在尝试创建一个应用程序,在项目列表顶部显示几个额外的行,顶部有一个“live search”字段: 当然,一开始我试着用它。但这并不能很好地工作-因为我无法控制关键字FilterField调用setSize()的时间和方式,这给了我绘图问题(当我输入关键字并向列表中添加新项时,没有绘制一行,等等) 因此,这次我尝试“回到根”并使用一个列表字段(顶部还有一个BasicEditField),因为在那里我可以控制自己,何时以及如何调用setSize() 下面是我的简化测试代码-src\mypackage\MyList.java和border.png 代码运行良好,除了过滤问题——我将在下面描述Blackberry:如何过滤列表字段表示的行?,blackberry,collections,filtering,listfield,Blackberry,Collections,Filtering,Listfield,我正在尝试创建一个应用程序,在项目列表顶部显示几个额外的行,顶部有一个“live search”字段: 当然,一开始我试着用它。但这并不能很好地工作-因为我无法控制关键字FilterField调用setSize()的时间和方式,这给了我绘图问题(当我输入关键字并向列表中添加新项时,没有绘制一行,等等) 因此,这次我尝试“回到根”并使用一个列表字段(顶部还有一个BasicEditField),因为在那里我可以控制自己,何时以及如何调用setSize() 下面是我的简化测试代码-src\mypac
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;
BasicFilteredList myFilter = new BasicFilteredList();
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);
}
};
MyItemList myItems = new MyItemList();
// add 1 row for the "* Empty *" string
ListField myList = new ListField(EXTRA_ROWS + 1) {
protected boolean navigationClick(int status, int time) {
int index = getSelectedIndex();
if (index >= EXTRA_ROWS && myItems.size() > 0) {
String str = ((MyItem) myItems.getAt(
index - EXTRA_ROWS)).toString();
Status.show("You have clicked - " + str);
}
return true;
}
};
Border myBorder = BorderFactory.createBitmapBorder(
new XYEdges(12, 12, 12, 12),
Bitmap.getBitmapResource("border.png"));
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);
myFilter.addDataSet(1, myItems.getElements(), "Test",
BasicFilteredList.COMPARISON_IGNORE_CASE);
}
protected boolean keyChar(char key, int status, int time) {
if (key == Characters.BACKSPACE && myFind.getTextLength() == 0) {
Status.show("Kill kill kill!");
return true;
}
if (myFind.getTextLength() > 0) {
System.err.println("XXX filter for " + myFind.getText());
}
return super.keyChar(key, status, time);
}
private class MyListFieldCallback implements ListFieldCallback {
public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
Font i = getFont().derive(Font.ITALIC);
g.setColor(Color.DIMGRAY);
g.drawLine(0, y-9, width, y-9);
g.setColor(Color.WHITE);
if (index < EXTRA_ROWS) {
g.setFont(i);
g.drawText("Add Item", 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
if (myItems.size() == 0) {
g.setFont(i);
g.drawText(list.getEmptyString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
MyItem item = (MyItem) myItems.getAt(index - EXTRA_ROWS);
g.drawText(item.toString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
}
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) {
// if the list is empty, add 1 row for "* Empty *" string
int size = (size() == 0 ? EXTRA_ROWS + 1 : size() - 1 + EXTRA_ROWS);
myList.setSize(size);
return super.doRemove(obj);
}
protected Object[] getElements() {
return super.getElements();
}
}
}
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 };
}
}
}
但我不知道如何在这里应用它
更新:
我已经在上面的测试代码中添加了一个基本过滤列表,但仍然不确定如何将其与列表字段相结合。您必须在代码中的某个地方进行过滤,然后存储结果。重写myFind.update(int)以在筛选文本更改时运行筛选。除了myItems之外,您还需要存储myFilteredItems。过滤后,在listfield上调用setSize()。listfield绘图代码还需要从过滤的集合中绘图。然后您应该被设置。您必须在某个地方的代码中进行过滤,然后存储结果。重写myFind.update(int)以在筛选文本更改时运行筛选。除了myItems之外,您还需要存储myFilteredItems。过滤后,在listfield上调用setSize()。listfield绘图代码还需要从过滤的集合中绘图。然后你就可以开始了。我最终得到了这段代码,这段代码似乎对我很有效(下面列出的两个小问题除外),绿色的答案是Michael Donohue的宝贵建议 我使用两个向量:myData和MyFilteredata。对于UI,我使用ListField和BasicEditField: border.png: src\mypackage\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 {
static final int EXTRA_ROWS = 3;
Background myBg = BackgroundFactory.createSolidBackground(0x111111);
StringProvider myProvider = new StringProvider("Search");
BasicEditField myFind = new BasicEditField(USE_ALL_WIDTH|TextField.NO_NEWLINE) {
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);
}
protected void update(int delta) {
filterData(getText());
}
};
Vector myData = new Vector();
final static SimpleSortingVector myFilteredData = new SimpleSortingVector();
// add 1 row for the "* Empty *" string
ListField myList = new ListField(EXTRA_ROWS + 1) {
protected boolean navigationClick(int status, int time) {
int index = getSelectedIndex();
if (index >= EXTRA_ROWS && myFilteredData.size() > 0) {
String str = ((MyItem) myFilteredData.elementAt(index - EXTRA_ROWS)).toString();
Status.show("You have clicked - " + str);
}
return true;
}
};
Border myBorder = BorderFactory.createBitmapBorder(
new XYEdges(12, 12, 12, 12),
Bitmap.getBitmapResource("border.png"));
public MyScreen() {
getMainManager().setBackground(myBg);
myFind.setBorder(myBorder);
setTitle(myFind);
myData.addElement(new MyItem(1, "Eins"));
myData.addElement(new MyItem(2, "Zwei"));
myData.addElement(new MyItem(3, "Drei"));
myData.addElement(new MyItem(4, "Vier"));
myFilteredData.setSortComparator(new MyItem.MyComparator());
filterData("");
myList.setCallback(new MyListFieldCallback());
add(myList);
}
private void filterData(String prefix) {
myFilteredData.removeAllElements();
if (prefix == null || prefix.length() == 0) {
// no prefix specified - copy everything
for (int i = myData.size() - 1; i >= 0; i--) {
MyItem item = (MyItem) myData.elementAt(i);
myFilteredData.addElement(item);
}
} else {
// copy only strings starting with prefix
for (int i = myData.size() - 1; i >= 0; i--) {
MyItem item = (MyItem) myData.elementAt(i);
String name = item.name.toLowerCase();
if (name.startsWith(prefix.toLowerCase())) {
myFilteredData.addElement(item);
}
}
}
myFilteredData.reSort();
// if the list is empty, add 1 row for "* Empty *" string
int size = (myFilteredData.size() == 0 ? EXTRA_ROWS + 1 : myFilteredData.size() + EXTRA_ROWS);
myList.setSize(size);
}
protected boolean keyChar(char key, int status, int time) {
if (key == Characters.BACKSPACE && myFind.getTextLength() == 0) {
int index = myList.getSelectedIndex();
if (index >= EXTRA_ROWS && myFilteredData.size() > 0) {
String str = ((MyItem) myFilteredData.elementAt(index - EXTRA_ROWS)).toString();
Status.show("You're deleting - " + str);
}
return true;
}
return super.keyChar(key, status, time);
}
static class MyListFieldCallback implements ListFieldCallback {
public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
Font i = g.getFont().derive(Font.ITALIC);
g.setColor(Color.DIMGRAY);
g.drawLine(0, y-9, width, y-9);
g.setColor(Color.WHITE);
if (index < EXTRA_ROWS) {
g.setFont(i);
g.drawText("Add Item", 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
if (myFilteredData.size() == 0) {
g.setFont(i);
g.drawText(list.getEmptyString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
MyItem item = (MyItem) myFilteredData.elementAt(index - EXTRA_ROWS);
g.drawText(item.toString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
}
public Object get(ListField list, int index) {
return myFilteredData.elementAt(index);
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
public int indexOfList(ListField list, String prefix, int start) {
return myFilteredData.indexOf(prefix, start);
}
}
}
class MyItem {
int num;
String name;
public MyItem(int num, String name) {
this.num = num;
this.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;
String name1 = item1.toString().toLowerCase();
String name2 = item2.toString().toLowerCase();
return name1.compareTo(name2);
}
}
}
package-mypackage;
导入java.util.*;
导入net.rim.device.api.collection.*;
导入net.rim.device.api.collection.util.*;
导入net.rim.device.api.system.*;
导入net.rim.device.api.ui.*;
导入net.rim.device.api.ui.component.*;
导入net.rim.device.api.ui.container.*;
导入net.rim.device.api.ui.decor.*;
导入net.rim.device.api.util.*;
公共类MyList扩展了UiApplication{
公共静态void main(字符串参数[]){
MyList应用程序=新建MyList();
app.enterEventDispatcher();
}
公共MyList(){
推屏(新MyScreen());
}
}
类MyScreen扩展了MainScreen{
静态最终int额外_行=3;
后台myBg=BackgroundFactory.createSolidBackground(0x111111);
StringProvider myProvider=新的StringProvider(“搜索”);
BasicEditField myFind=新建BasicEditField(使用_ALL_WIDTH | TextField.NO_NEWLINE){
受保护的空心漆(图g){
if(getTextLength()==0){
g、 setColor(颜色:浅灰色);
g、 drawText(myProvider.toString(),0,0);
}
g、 设置颜色(颜色为黑色);
超级油漆(g);
}
受保护的无效更新(整数增量){
filterData(getText());
}
};
向量myData=新向量();
最终静态SimpleSortingVector myFilteredData=新SimpleSortingVector();
//为“*空*”字符串添加1行
ListField myList=新的ListField(额外的行+1){
受保护的布尔导航单击(int状态,int时间){
int index=getSelectedIndex();
如果(索引>=额外的行和myFilteredData.size()>0){
字符串str=((MyItem)myFilteredata.elementAt(index-EXTRA_ROWS)).toString();
Status.show(“您已单击-”+str);
}
返回true;
}
};
Border myBorder=BorderFactory.createBitmapBorder(
新的XY边(12,12,12,12),
getBitmapResource(“border.png”);
公共MyScreen(){
getMainManager().setBackground(myBg);
myFind.setboorder(myBorder);
设置标题(myFind);
myData.addElement(新的MyItem(1,“EIN”);
myData.addElement(新的MyItem(2,“Zwei”);
myData.addElement(新的MyItem(3,“Drei”);
myData.addElement(新的MyItem(4,“Vier”);
myFilteredData.setSortComparator(新的MyItem.MyComparator());
过滤数据(“”);
setCallback(新的MyListFieldCallback());
添加(myList);
}
私有void filterData(字符串前缀){
myFilteredData.removeAllElements();
if(prefix==null | | prefix.length()==0){
//未指定前缀-复制所有内容
对于(int i=myData.size()-1;i>=0;i--){
MyItem=(MyItem)myData.elementAt(i);
MyFilteredata.附录(项目);
}
}否则{
//仅复制以前缀开头的字符串
对于(int i=myData.size()-1;i>=0;i--){
MyItem=(MyItem)myData.elementAt(i);
字符串名称=item.name.toLowerCase();
if(name.startsWith(前缀.toLowerCase())){
MyFilteredata.附录(项目);
}
}
}
MyFilteredata.reSort();
//如果列表为空,请为“*empty*”字符串添加1行
int size=(myFilteredata.size()==0?额外的_行+1:myFilteredata.size()+额外的_行);
myList.setSize(大小);
}
受保护的布尔键字符(字符键、int状态、int时间){
if(key==Characters.BACKSPACE&&myFind.getTextLength()==0){
int index=myList.getSelectedIndex();
如果(索引>=额外的行和myFilteredData.size()>0){
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;
Background myBg = BackgroundFactory.createSolidBackground(0x111111);
StringProvider myProvider = new StringProvider("Search");
BasicEditField myFind = new BasicEditField(USE_ALL_WIDTH|TextField.NO_NEWLINE) {
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);
}
protected void update(int delta) {
filterData(getText());
}
};
Vector myData = new Vector();
final static SimpleSortingVector myFilteredData = new SimpleSortingVector();
// add 1 row for the "* Empty *" string
ListField myList = new ListField(EXTRA_ROWS + 1) {
protected boolean navigationClick(int status, int time) {
int index = getSelectedIndex();
if (index >= EXTRA_ROWS && myFilteredData.size() > 0) {
String str = ((MyItem) myFilteredData.elementAt(index - EXTRA_ROWS)).toString();
Status.show("You have clicked - " + str);
}
return true;
}
};
Border myBorder = BorderFactory.createBitmapBorder(
new XYEdges(12, 12, 12, 12),
Bitmap.getBitmapResource("border.png"));
public MyScreen() {
getMainManager().setBackground(myBg);
myFind.setBorder(myBorder);
setTitle(myFind);
myData.addElement(new MyItem(1, "Eins"));
myData.addElement(new MyItem(2, "Zwei"));
myData.addElement(new MyItem(3, "Drei"));
myData.addElement(new MyItem(4, "Vier"));
myFilteredData.setSortComparator(new MyItem.MyComparator());
filterData("");
myList.setCallback(new MyListFieldCallback());
add(myList);
}
private void filterData(String prefix) {
myFilteredData.removeAllElements();
if (prefix == null || prefix.length() == 0) {
// no prefix specified - copy everything
for (int i = myData.size() - 1; i >= 0; i--) {
MyItem item = (MyItem) myData.elementAt(i);
myFilteredData.addElement(item);
}
} else {
// copy only strings starting with prefix
for (int i = myData.size() - 1; i >= 0; i--) {
MyItem item = (MyItem) myData.elementAt(i);
String name = item.name.toLowerCase();
if (name.startsWith(prefix.toLowerCase())) {
myFilteredData.addElement(item);
}
}
}
myFilteredData.reSort();
// if the list is empty, add 1 row for "* Empty *" string
int size = (myFilteredData.size() == 0 ? EXTRA_ROWS + 1 : myFilteredData.size() + EXTRA_ROWS);
myList.setSize(size);
}
protected boolean keyChar(char key, int status, int time) {
if (key == Characters.BACKSPACE && myFind.getTextLength() == 0) {
int index = myList.getSelectedIndex();
if (index >= EXTRA_ROWS && myFilteredData.size() > 0) {
String str = ((MyItem) myFilteredData.elementAt(index - EXTRA_ROWS)).toString();
Status.show("You're deleting - " + str);
}
return true;
}
return super.keyChar(key, status, time);
}
static class MyListFieldCallback implements ListFieldCallback {
public void drawListRow(ListField list, Graphics g, int index, int y, int width) {
Font i = g.getFont().derive(Font.ITALIC);
g.setColor(Color.DIMGRAY);
g.drawLine(0, y-9, width, y-9);
g.setColor(Color.WHITE);
if (index < EXTRA_ROWS) {
g.setFont(i);
g.drawText("Add Item", 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
if (myFilteredData.size() == 0) {
g.setFont(i);
g.drawText(list.getEmptyString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
return;
}
MyItem item = (MyItem) myFilteredData.elementAt(index - EXTRA_ROWS);
g.drawText(item.toString(), 0, y, DrawStyle.ELLIPSIS|DrawStyle.HCENTER, width);
}
public Object get(ListField list, int index) {
return myFilteredData.elementAt(index);
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
public int indexOfList(ListField list, String prefix, int start) {
return myFilteredData.indexOf(prefix, start);
}
}
}
class MyItem {
int num;
String name;
public MyItem(int num, String name) {
this.num = num;
this.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;
String name1 = item1.toString().toLowerCase();
String name2 = item2.toString().toLowerCase();
return name1.compareTo(name2);
}
}
}