Java 自定义列表字段单击事件
我正在编写一个应用程序,其中创建了用于显示listview的自定义列表字段。 我的CustomListField在一行中包含一个图像和文本。我在单击listfield行时获得fieldchange listener,但我也想将fieldchange listener放在图像上。。 谁能告诉我怎么做 这是我的密码Java 自定义列表字段单击事件,java,blackberry,blackberry-jde,listfield,Java,Blackberry,Blackberry Jde,Listfield,我正在编写一个应用程序,其中创建了用于显示listview的自定义列表字段。 我的CustomListField在一行中包含一个图像和文本。我在单击listfield行时获得fieldchange listener,但我也想将fieldchange listener放在图像上。。 谁能告诉我怎么做 这是我的密码 public class CustomListField extends ListField implements ListFieldCallback { private Vec
public class CustomListField extends ListField implements ListFieldCallback {
private Vector _listData;
private int _MAX_ROW_HEIGHT = 60;
public CustomListField(Vector data) {
_listData = data;
setSize(_listData.size());
setSearchable(true);
setCallback(this);
setRowHeight(_MAX_ROW_HEIGHT);
}
protected void drawFocus(Graphics graphics, boolean on) {
XYRect rect = new XYRect();
graphics.setGlobalAlpha(150);
graphics.setColor(Color.BLUE);
getFocusRect(rect);
drawHighlightRegion(graphics, HIGHLIGHT_FOCUS, true, rect.x, rect.y, rect.width, rect.height);
}
public int moveFocus(int amount, int status, int time) {
this.invalidate(this.getSelectedIndex());
return super.moveFocus(amount, status, time);
}
public void onFocus(int direction) {
super.onFocus(direction);
}
protected void onUnFocus() {
this.invalidate(this.getSelectedIndex());
}
public void refresh() {
this.getManager().invalidate();
}
public void drawListRow(ListField listField, Graphics graphics, int index, int y, int w) {
listField.setBackground(BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("listing_bg.png")));
ListRander listRander = (ListRander) _listData.elementAt(index);
graphics.setGlobalAlpha(255);
graphics.setFont(Font.getDefault().getFontFamily().getFont(Font.PLAIN, 24));
final int margin = 5;
final Bitmap thumb = listRander.getListThumb();
final String listHeading = listRander.getListTitle();
final Bitmap nevBar = listRander.getNavBar();
// list border
graphics.setColor(Color.GRAY);
graphics.drawRect(0, y, w, _MAX_ROW_HEIGHT);
// thumbnail border & thumbnail image
graphics.setColor(Color.BLACK);
// graphics.drawRoundRect(margin-2, y+margin-2,thumb.getWidth()+2, thumb.getHeight()+2, 5, 5);
graphics.drawBitmap(margin, y + margin, thumb.getWidth(), thumb.getHeight(), thumb, 0, 0);
// drawing texts
// graphics.setFont(Font.BOLD);
graphics.drawText(listHeading, margin + thumb.getWidth(), y + margin);
graphics.setColor(Color.GRAY);
// graphics.setFont(Font.smallFont); // graphics.drawText(listDesc, 2*margin+thumb.getWidth(), y+ margin+20); // //
// graphics.drawText(listDesc2, 2*margin+thumb.getWidth(), y+ margin+32);
// draw navigation button
final int navBarPosY = y + (_MAX_ROW_HEIGHT / 2 - nevBar.getHeight() / 2);
final int navBarPosX = Graphics.getScreenWidth() - nevBar.getWidth() + margin;
graphics.drawBitmap(navBarPosX, navBarPosY, nevBar.getWidth(), nevBar.getHeight(), nevBar, 0, 0);
}
public Object get(ListField listField, int index) {
String rowString = (String) _listData.elementAt(index);
return rowString;
}
public int indexOfList(ListField listField, String prefix, int start) {
for (Enumeration e = _listData.elements(); e.hasMoreElements();) {
String rowString = (String) e.nextElement();
if (rowString.startsWith(prefix)) {
return _listData.indexOf(rowString);
}
}
return 0;
}
public int getPreferredWidth(ListField listField) {
return 3 * listField.getRowHeight();
}
/*
protected boolean trackwheelClick(int status, int time) {
invalidate(getSelectedIndex());
Dialog.alert(" U have selected :" + getSelectedIndex());
return super.trackwheelClick(status, time);
}
*/
}
我想把click listner放在listfield行的星形图像上
下面是abbove代码的输出。
与Android的
列表视图不同,BB的列表字段
没有设计成在列表项的内部有一个可聚焦/可点击的字段。因此,任何试图解决这一问题的尝试都会产生一些负面的副作用
一个相对简单/快速的解决方法是切换到VerticalFieldManager
(选中)。但是如果列表太长(我相信超过几百个),你就有可能“吃掉”太多的内存
如果该应用程序仅为触摸屏设计,那么您可以尝试使用ListField
+手动跟踪触摸事件坐标。因此,当您检测到列表字段单击时(以通常的方式),您可以检查触摸坐标是否对应于星形图像区域(至少在X轴上)。我不打算发明/提供一个实现,而只是给出一个想法。我在过去的一个项目中做了类似的事情:
背景
,并且正如您所读到的,您不能在列表字段
中有完整的字段
对象。ListField
行的内容直接在drawListRow()
中绘制为文本和位图等。这些内容不是Field
实例,因此不可聚焦
因此,我所做的是用Manager
的子类替换ListField
。最初,我使用了一个VerticalFieldManager
,但遇到了问题。我也看到了很多关于堆栈溢出的问题,人们将VerticalFieldManager子类化,自定义一个小行为,然后一切都开始崩溃。在我看来,VerticalFieldManager
如果您接受它的正常行为,那么它工作得很好,如果您需要更多的东西,只需直接扩展Manager
。为垂直堆叠的行执行布局非常简单
然后,我让每一行都有自己的管理器
,并在sublayout()
中实现自定义布局,以将行的字段
放置在我想要的位置。然后,我还可以将行设置为可聚焦,然后将行上的位图/按钮单独设置为可聚焦(如您的星形)。单击行调用一个操作,单击星形调用另一个操作
然而,我会注意到,在我的应用程序中,性能不是问题,因为我只有10-20行。此外,我必须修改我的代码以匹配您的示例,所以请考虑此代码只是轻度测试。然而,我确实将它构建到了一个应用程序中,所以只要我的假设和您的描述是有效的,它就会运行良好
实施
首先,我不清楚您的ListRander
是什么(您没有显示该代码)。然而,在我的代码中,我需要一个数据类来包含关于一行的详细信息。看起来你就是这样使用ListRander的,所以我就是这么用的:
公共类列表器{
私有字符串\u标题;
私有位图(U thumb);
公共ListRander(字符串标题、位图缩略图){
_头衔=头衔;
_拇指=拇指;
}
公共字符串getTitle(){
返回标题;
}
公共位图getThumb(){
返回拇指;
}
}
然后,我将您的CustomListField
类替换为我自己的类:
公共类CustomListField扩展管理器实现FocusChangeListener{
私有内部最大行高=60;
私有布尔值_searchable=false;
私有向量列表数据;
私有FieldChangeListener\u fieldListener;
公共CustomListField(矢量数据){
超级(可聚焦|垂直|滚动条|垂直|滚动条);
设置可搜索(真);
可编辑设置(假);
setListData(数据);
}
公共无效setChangeListener(FieldChangeListener listener){
//我们需要保存此侦听器,因为我们将其设置为侦听所有新行
_fieldListener=监听器;
int numFields=getFieldCount();
对于(int f=0;f=\u listData.size()| |!\u可搜索){
返回-1;
}否则{
int result=getSelectedIndex();//如果找不到匹配项,则为默认结果
对于(枚举e=_listData.elements();e.hasMoreElements();){
String rowString=(String)e.nextElement();
if(rowString.startsWith(prefix)){
返回_listData.indexOf(rowString);
}
}
返回结果;
}
}
受保护的布尔导航单击(int状态,int时间){
CustomListRow焦点=(CustomListRow)getFieldWithFocus();
if(焦点!=null){
//查看该行是否要处理此单击
如果(!focus.navigationClick(状态、时间)){
//让我们的FieldChangeListener知道此行已被单击
fieldChangeNotify(getFieldWithFocusIndex());
}
返回true;
}否则{
返回false;
}
}
受保护的空位子布局(整数宽度、整数高度){
int w=Math.min(宽度,getPreferredWidth());
我