如何制作向用户显示图像而不是文本的下拉列表?

ObjectChoiceField字段符合我的所有要求,但它并不漂亮。

这就是我所拥有的:

String pets[] = {"Dog", "Cat", "Duck" }; ObjectChoiceField dd = new ObjectChoiceField("My Pet",pets,0,ObjectChoiceField.FIELD_LEFT); 

但我更愿意在下拉列表中有图片。 我的理解是对象数组必须包含支持toString方法的对象。 我必须有一种方法可以在其他应用程序中看到它,我在API中找不到正确的对象。

它不必是ObjectChoiceField。

我会使用自定义ButtonField和PopupScreen。 两个原因:

  • 在移动设计中,最好有效地使用屏幕,而经典的桌面下拉控件似乎不如弹出窗口,至少对于复杂的项目(图像+文本)
  • 它更容易:)

替代文字http://img405.imageshack.us/img405/3746/dropdown.jpg

DropDownItem:

 class DropdownItem { Bitmap mBitmap; String mName; public DropdownItem(Bitmap bitmap, String name) { this.mBitmap = bitmap; this.mName = name; } } 

自定义ButtonField:

 class BitmapButtonField extends ButtonField { protected DropdownItem mItem; boolean mTextItem; int mWidth; int mHeight; public BitmapButtonField(DropdownItem item, boolean textItem) { super(CONSUME_CLICK); mItem = item; mTextItem = textItem; mWidth = mItem.mBitmap.getWidth() + 6 + (mTextItem ? getFont().getAdvance(mItem.mName) + 6 : 0); mHeight = mItem.mBitmap.getHeight() + 6; setMargin(0, 0, 0, 0); setPadding(0, 0, 0, 0); setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0))); setBorder(VISUAL_STATE_ACTIVE, BorderFactory .createSimpleBorder(new XYEdges(0, 0, 0, 0))); } protected void paint(Graphics graphics) { int color = (getVisualState() == VISUAL_STATE_FOCUS) ? Color.LIGHTGREY : Color.DARKGRAY; graphics.setColor(color); graphics.drawRect(1, 1, mWidth - 2, mHeight - 2); graphics.drawBitmap(3, 3, mItem.mBitmap.getWidth(), mItem.mBitmap .getHeight(), mItem.mBitmap, 0, 0); if (mTextItem) graphics.drawText(mItem.mName, mItem.mBitmap.getWidth() + 6, 3); } public int getPreferredWidth() { return mWidth; } public int getPreferredHeight() { return mHeight; } protected void layout(int width, int height) { setExtent(mWidth, mHeight); } } 

下拉控件本身:

 class DDImagesButton extends BitmapButtonField implements FieldChangeListener { DropdownItem[] mItems; int mIndex; public DDImagesButton(DropdownItem[] items) { super(items[0], false); mItems = items; updateIndex(0); setChangeListener(this); } protected void paint(Graphics graphics) { super.paint(graphics); int x = mItems[mIndex].mBitmap.getWidth() + 2; int y = 5; int y1 = y; int y2 = y + 10; int x1 = x; int x2 = x + 18; int[] xPts = new int[] { x1, x2, x1 + 9 }; int[] yPts = new int[] { y1, y1, y2 }; graphics.drawFilledPath(xPts, yPts, null, null); } public void fieldChanged(Field field, int context) { getScreen().getUiEngine().pushScreen(new DDImagesPopUp()); } public void updateIndex(int index) { mIndex = index; mItem = mItems[mIndex]; mWidth = mItem.mBitmap.getWidth() + 6 + 18 + 3; mHeight = mItem.mBitmap.getHeight() + 6; invalidate(); } class DDImagesPopUp extends PopupScreen implements FieldChangeListener { public DDImagesPopUp() { super( new VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR)); for (int i = 0; i < mItems.length; i++) { BitmapButtonField button = new BitmapButtonField(mItems[i], true); add(button); button.setChangeListener(this); } setFieldWithFocus(getField(mIndex)); } protected boolean keyChar(char key, int status, int time) { if (Keypad.KEY_ESCAPE == key) { this.close(); return true; } else return super.keyChar(key, status, time); } public void fieldChanged(Field field, int context) { updateIndex(getFieldWithFocusIndex()); close(); } } } 

使用样品:

 class Scr extends MainScreen { DDImagesButton ddImages1; DDImagesButton ddImages2; public Scr() { HorizontalFieldManager hfm = new HorizontalFieldManager(); add(hfm); DropdownItem[] items = new DropdownItem[6]; items[0] = new DropdownItem(Bitmap.getBitmapResource("1.png"), "Add Item"); items[1] = new DropdownItem(Bitmap.getBitmapResource("2.png"), "Attachment"); items[2] = new DropdownItem(Bitmap.getBitmapResource("3.png"), "Time"); items[3] = new DropdownItem(Bitmap.getBitmapResource("4.png"), "User"); items[4] = new DropdownItem(Bitmap.getBitmapResource("5.png"), "Group"); items[5] = new DropdownItem(Bitmap.getBitmapResource("6.png"), "Information"); ddImages1 = new DDImagesButton(items); hfm.add(ddImages1); ddImages2 = new DDImagesButton(items); hfm.add(ddImages2); } } 

我不熟悉黑莓开发,但我想你可以ObjectChoiceField并覆盖layout(int, int)paint(Graphics)方法。

然后在paint(Graphics)可能使用传入的Graphics-object的drawImage(...)方法来绘制图像。

只是一个疯狂的猜测

我的回答将是抖动的反应 。 您想要的自定义类型的一般想法是覆盖基本组件的默认行为。

假设,您要显示的选项可以由名为Choice的类封装,如下所示:

 private class Choice { public Bitmap image; public String label; public Choice(String name) { this.image = Bitmap.getBitmapResource(name + ".png"); this.label = name; } public String toString() { return this.label; } } 

然后你可以将ObjectListField实例声明为:

 ObjectChoiceField choice = new ObjectChoiceField() { protected void paint(Graphics graphics) { // Get the current selected Choice Choice item = (Choice) this.getChoice(getSelectedIndex()); int xOffset = 5; // 5 px padding on the left graphics.drawBitmap(xOffset, 0, item.image.getWidth(), item.image.getHeight(), item.image, 0, 0); // Add text after the image and 10px padding. xOffset += item.image.getWidth() + 10; graphics.drawText(item.label, xOfffset, 0); } }; 

将您的选择项设置为:

 choice.setChoices(new Choice[]{ new Choice("choice 1"), new Choice("choice 2")}); 

然后使用以下命令将其添加到您的Screen (或您选择的FieldManager ):

 add(choice); 

我无法覆盖实际的选择弹出菜单项。 这似乎调用了您选择项的toString()方法。 这就是我在Choice类中覆盖toString()的默认实现的原因,以便我们可以在该弹出窗口中显示逻辑名称。

如果这是一个java小部件,那么你可以将简单的html作为项目传递到选择字段中显示(或者让toString()返回简单的html)。 然后,如果是这种情况,您传递图像URL /相对路径,则应显示图像。 AFAIK至少可以在Swing中工作,例如……

“ Dog

(为预览中显示的代码添加的空格)