7 Stimmen

Wie kann man eine Dropdown-Liste erstellen, die dem Benutzer Bilder statt Text anzeigt?

Das Feld ObjectChoiceField erfüllt alle meine Anforderungen, aber es ist nicht schön.

Das habe ich:

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

Aber ich würde es vorziehen, Bilder in der Dropdown-Liste zu haben. Mein Verständnis ist, dass das Objekt-Array Objekte enthalten muss, die die toString-Methode unterstützen. Es muss einen Weg geben, um zu tun, ich sehe es in anderen Anwendungen, ich kann nur nicht das richtige Objekt in der API finden.

Es muss nicht unbedingt ein ObjectChoiceField sein.

4voto

Maksym Gontar Punkte 22730

Ich würde benutzerdefinierte ButtonField und PopupScreen verwenden. Zwei Gründe:

  • Beim mobilen Design ist es besser, den Bildschirm effektiv zu nutzen, und das klassische Desktop-Dropdown-Steuerelement scheint weniger ausreichend zu sein als ein Popup, zumindest für komplexe Elemente (Bild + Text).
  • es ist einfacher :)

Alt-Text http://img405.imageshack.us/img405/3746/dropdown.jpg

DropDownElement:

class DropdownItem {
 Bitmap mBitmap;
 String mName;

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

Benutzerdefiniertes ButtonFeld:

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);
 }
}

Dropdown-Steuerung selbst:

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();
  }
 }
}

Beispiel für die Verwendung:

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);
 }
}

2voto

jitter Punkte 52721

Ich bin mit der Blackberry-Entwicklung nicht vertraut, aber ich vermute, Sie könnten eine Unterklasse ObjectChoiceField und überschreiben die layout(int, int) und die paint(Graphics) Methoden.

Und dann in paint(Graphics) vielleicht die drawImage(...) Methode des übergebenen Graphics-Objekts, um das Bild zu zeichnen.

Nur eine wilde Vermutung

1voto

paracycle Punkte 7373

Meine Antwort wird in etwa so lauten Antwort des Jitter . Die allgemeine Idee für die Art von Anpassungen, die Sie wünschen, ist, das Standardverhalten der Basiskomponenten außer Kraft zu setzen.

Angenommen, die Auswahlmöglichkeiten, die Sie anzeigen möchten, können durch eine Klasse namens Choice wie folgt erklärt:

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;
  }
}

dann können Sie eine ObjectListField Beispiel als:

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);
  }            
};

stellen Sie Ihre Auswahl als:

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

und fügen Sie es dann zu Ihrem Screen (oder FieldManager Ihrer Wahl) verwenden:

add(choice);

Es ist mir nicht gelungen, die eigentlichen Elemente des Auswahl-Popup-Menüs außer Kraft zu setzen. Dies scheint den Aufruf der toString() Methode der Artikel Ihrer Wahl. Deshalb habe ich die Standardimplementierung von toString() im Choice Klasse, damit wir logische Namen in diesem Pop-up anzeigen können.

0voto

Wenn es sich um ein Java-Widget handelt, können Sie wahrscheinlich einfaches HTML als Elemente übergeben, die im Auswahlfeld angezeigt werden sollen (oder toString() gibt einfaches HTML zurück). Wenn das der Fall ist und Sie eine Bild-URL/einen relativen Pfad übergeben, dann sollte das Bild angezeigt werden. AFAIK würde das zumindest in Swing funktionieren, z.B. ...

"< html> Hund < img src="dog.png">< /html>"

(Leerzeichen hinzugefügt, damit der Code in der Vorschau angezeigt wird)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X