2013-05-15 3 views
1

У меня есть ImageButton в VerticalFieldManager и VFM в HorizontalFieldManager. Событие clickButton click стреляет, когда я нажимаю в любом месте в окружающем поле. Я хочу, чтобы это событие щелчка срабатывало только при нажатии кнопки ImageButton, а не в поле (VFM или HFM).Blackberry Click Events

Ниже приводится код:

ImageButton Login = new ImageButton(configModel.getLoginButton(), FOCUSABLE|Field.FIELD_RIGHT, "login.png", "plogin.png",0x9cbe95); 
HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_WIDTH); 
VerticalFieldManager loginButtonVfm = new VerticalFieldManager(USE_ALL_WIDTH); 

loginButtonVfm.add(Login); 
hfm.add(loginButtonVfm); 
add(hfm); 


FieldChangeListener loginListener = new FieldChangeListener() { 
public void fieldChanged(Field field, int context) { 
    Dialog.alert("Fired"); 
    } 
} 
Login.setChangeListener(loginListener); 

ImageButton Код класса здесь:

public class ImageButton extends Field{ 

     //Image Button Class 
     private String _label; 
     private int _labelHeight; 
     private int _labelWidth; 
     private Font _font; 

     private Bitmap _currentPicture; 
     private Bitmap _onPicture; 
     private Bitmap _offPicture; 
     int color; 

     public ImageButton(String text, long style ,String img, String img_hvr, int color){ 
      super(style); 

      _offPicture = Bitmap.getBitmapResource(img); 
      _onPicture = Bitmap.getBitmapResource(img_hvr); 

      _font = Font.getDefault().derive(Font.BOLD, 7, Ui.UNITS_pt); 
      _label = text; 


      _labelHeight = _onPicture.getHeight(); 
      _labelWidth = _onPicture.getWidth(); 

      this.color = color; 

      _currentPicture = _offPicture; 
     } 
     public void setImage(String img){ 

      _offPicture = Bitmap.getBitmapResource(img); 
      _currentPicture = _offPicture; 
     } 

     /** 
     * @return The text on the button 
     */ 
     public void setText(String text){ 
      _label = text; 
     } 
      String getText(){ 
      return _label; 
     } 

     /** 
     * Field implementation. 
     * @see net.rim.device.api.ui.Field#getPreferredHeight() 
     */ 
     public int getPreferredHeight(){ 
      return _labelHeight; 
     } 
     /** 
     * Field implementation. 
     * @see net.rim.device.api.ui.Field#getPreferredWidth() 
     */ 
     public int getPreferredWidth(){ 
      return _labelWidth; 
     } 

     /** 
     * Field implementation. Changes the picture when focus is gained. 
     * @see net.rim.device.api.ui.Field#onFocus(int) 
     */ 
     protected void onFocus(int direction) { 

      _currentPicture = _onPicture; 
      // invalidate(); 
      super.onFocus(direction); 
     } 

     /** 
     * Field implementation. Changes picture back when focus is lost. 
     * @see net.rim.device.api.ui.Field#onUnfocus() 
     */ 
     protected void onUnfocus() { 
      _currentPicture = _offPicture; 
      invalidate(); 
      super.onUnfocus(); 
     } 

     /** 
     * Field implementation. 
     * @see net.rim.device.api.ui.Field#drawFocus(Graphics, boolean) 
     */ 
//  protected void drawFocus(Graphics graphics, boolean on) { 
//   // Do nothing 
//  } 
     protected void drawFocus(Graphics graphics, boolean on) { 
      if (on) { 
        //draw your own custom focus. 
        } 
       } 
     /** 
     * Field implementation. 
     * @see net.rim.device.api.ui.Field#layout(int, int) 
     */ 
     protected void layout(int width, int height) { 
      setExtent(Math.min(width, getPreferredWidth()), 
      Math.min(height, getPreferredHeight())); 
     } 
     /** 
     * Field implementation. 
     * @see net.rim.device.api.ui.Field#paint(Graphics) 
     */ 
     protected void paint(Graphics graphics){  
      // First draw the background colour and picture 
      graphics.setColor(this.color); 
      graphics.fillRect(0, 0, getWidth(), getHeight()); 
      graphics.drawBitmap(0, 0, getWidth(), getHeight(), _currentPicture, 0, 0); 

      // Then draw the text 
      graphics.setColor(Color.WHITE); 
      graphics.setFont(_font); 
      graphics.setFont(graphics.getFont().derive(Font.BOLD)); 
      graphics.drawText(_label, 5,9, 
       (int)(getStyle() & DrawStyle.ELLIPSIS | DrawStyle.VALIGN_MASK | DrawStyle.HALIGN_MASK), 
       getWidth() - 6); 

     } 

     /** 
     * Overridden so that the Event Dispatch thread can catch this event 
     * instead of having it be caught here.. 
     * @see net.rim.device.api.ui.Field#navigationClick(int, int) 
     */ 
     protected boolean navigationClick(int status, int time){ 
      fieldChangeNotify(1); 
      return true; 
     } 
} 

ответ

1

Такого рода вещи на самом деле довольно легко найти ошибки в, когда вы пытаетесь писать пользовательские полей. (Это не ваша вина ... BlackBerry Java делает этот материал более сложным, чем это действительно должно быть!)

Я думаю, что самый простой способ решить эту проблему - повторное использование того, что кто-то еще испытал. Я бы рекомендовал смотреть на BlackBerry Advanced UI библиотеке, в частности, эти два класса:

BaseButtonField

BitmapButtonField

Как я думаю, что они делают именно то, что вам нужно. Я считаю, что важно код, который нужно изменить, или добавить к вашему ImageButton класса это:

protected boolean keyChar(char character, int status, int time) 
{ 
    if(character == Characters.ENTER) { 
     clickButton(); 
     return true; 
    } 
    return super.keyChar(character, status, time); 
} 

protected boolean navigationClick(int status, int time) 
{ 
    if (status != 0) clickButton(); 
    return true;  
} 

protected boolean trackwheelClick(int status, int time) 
{   
    if (status != 0) clickButton();  
    return true; 
} 

protected boolean invokeAction(int action) 
{ 
    switch(action) { 
     case ACTION_INVOKE: { 
      clickButton(); 
      return true; 
     } 
    } 
    return super.invokeAction(action); 
}  

protected boolean touchEvent(TouchEvent message) 
{ 
    int x = message.getX(1); 
    int y = message.getY(1); 
    if(x < 0 || y < 0 || x > getExtent().width || y > getExtent().height) { 
     // Outside the field 
     return false; 
    } 
    switch(message.getEvent()) { 

     case TouchEvent.UNCLICK: 
      clickButton(); 
      return true; 
    } 
    return super.touchEvent(message); 
} 

/** 
* A public way to click this button 
*/ 
public void clickButton() 
{ 
    fieldChangeNotify(0); 
} 

Вы тогда сможете использовать FieldChangeListener точно так, как вы сейчас, но изображение кнопки не будет вызывать это, если щелчок не наступает на вашей кнопке.

Если вы хотите, вы можете, конечно, изменить код, чтобы использовать

fieldChangeNotify(1); 

если 1 является содержательным значение контекст для вас. Важно добавить другие методы и изменить navigationClick().

+0

Pure awesomeness, в чем проблема, если бы вы могли немного описать свое решение? –

+2

Если вы видите эту проблему на экране ** touch **, я думаю, что проблема заключалась в отсутствии реализации 'touchEvent()'. Если вы посмотрите на этот код, вы увидите, что он выполняет проверку, чтобы убедиться, что прикосновение ** находится внутри кнопки, а не снаружи. Вы должны включить и другие вещи. Например, 'keyChar()' гарантирует, что пользователь может сфокусироваться на вашей кнопке и * щелкнуть мышью *, нажав ENTER. 'trackwheelClick()' делает обработку единообразной для устройств со стрелками и т. д. – Nate

+0

@Nate Одна проблема с вышеуказанным кодом заключается в том, что вы обработали 'navigationClick', а не' navigationUnClick', тогда как в событии touch вы обрабатываете UNCLCIK. Это приведет к тому, что clickButton будет вызываться дважды, один раз во время щелчка, а затем снова во время unclick на сенсорных устройствах. Обычно я рекомендую людям обрабатывать 'navigationUnclick()', чтобы соответствовать стандартным поведением пользовательского интерфейса. – adwiv