BlackBerry touchEvent outside Field triggers fieldChanged

风格不统一 提交于 2019-12-30 05:22:07

问题


I am having a problem where if i press/touch outside of a field the fieldChanged() event is triggered for the field that has focus.

The layout for my MainScreen is pretty straight forward, something like so:

public class myMainScreen extends MainScreen implements FieldChangeListener{

    public myMainScreen(){
        CustomFM1 fm1 = new CustomFM1();
        CustomFM2 fm2 = new CustomFM2();

        add(fm1);
        add(fm2);
    }

}

If i press a button/field inside of either FieldManager it works fine. The problem is when i press on empty space. So if i were to press inside empty space in fm2 and a Field inside fm1 had focus, its fieldchanged event would be triggered.

At the moment, my remedy is to catch the touchEvent and pass it down to the appropriate FieldManager. The touchEvent for my CustomFM would then handle getting the field and calling fieldChanged, if a field has actually been pressed

So in myMainScreen touchEvent looks like:

protected boolean touchEvent(TouchEvent message){

    int index = this.getFieldAtLocation(message.getX(1), message.getY(1));

    switch(index){

        case 0:
           fm1.touchEvent(message);
           break;       

        case 1:
           fm2.touchEvent(message);
           break;

    }

    return true;
}

And my touchEvent for my CustomFM2 is. OFFSET is the top y position of fm2, in relation to the screen.

protected boolean touchEvent(TouchEvent message){

    switch(message.getEvent()){

    ... 

        case TouchEvent.UP:
            int index = this.getFieldAtLocation(message.getGlobalX(1), message.getGlobalY(1) - OFFSET);
            if(index != -1){
                Field field = getField(index);
                field.getChangeListener().fieldChanged(field, 0);

            }

            break;

    }

    return true;

}

What I'm wondering is that if there is an easier solution to this? Am i missing something?


回答1:


Just had the same issue. The main problem is that navigationClick and trackwheelClick are called if the touch event is not consumed in touchEvent.

The solution is to call fieldChangeNotify within the *Click methods only if the click was triggered by a non-touch event. Touch events are given a status of 0 so you can check for that as follows:

protected boolean navigationClick( int status, int time ){

    if (status != 0) fieldChangeNotify(0);
    return true;  
}

protected boolean trackwheelClick( int status, int time ){        

    if (status != 0) fieldChangeNotify(0);
    return true;
}

This method means you don't need to track whether the touch event was within the bounds of the field.




回答2:


Seems what i was doing was a bit off. I didn't need to pass the event down. That is done naturally (or unnaturally, as the Field that has focus seems to be recieving TouchEvents event if it hasnt been touched). What seems to be happening is that after a TouchEvent.Click a navigationClick is sent to the field. In navigationClick i was calling fieldChangeNotify(0)

To fix this my Field's touchEvent and navigationClick now look like this:

    private boolean touchEventInside;
    ...

    protected boolean touchEvent(TouchEvent message) {

        if(message.getX(1) < 0 || message.getX(1) > getWidth() || message.getY(1) < 0 || message.getY(1) > getHeight()) {

            touchEventInside = false;
            return false;

        }else{

            touchEventInside = true;
            return true;

        }

    }

    protected boolean navigationClick(int status, int time) {

        if(((myMainScreen)this.getScreen()).touchStarted){

            if(touchEventInside){
                fieldChangeNotify(0);
            }

        }else{

            fieldChangeNotify(0);

        }

        return true;
    }

I am also keeping track of touch events being started in myMainScreen, like so:

    protected boolean touchStarted;
    ...
    protected boolean touchEvent(TouchEvent message){

        if(message.getEvent() == TouchEvent.UP){
            touchStarted = false;
        }else if(message.getEvent() == TouchEvent.DOWN){
            touchStarted = true;
        }   
        super.touchEvent(message);
        return false;

    }



回答3:


The trick is not to override touchEvent(TouchEvent message) at all. :)

Just override navigationClick(int status, int time) for the field you want to handle the click (just to be clear - no need to do this for ButtonField - it works nice as is). The BB UI framework will call navigationClick(int status, int time) when user clicks your field on a touch screen. As well it'll work for a non-touch screen devices.



来源:https://stackoverflow.com/questions/6398282/blackberry-touchevent-outside-field-triggers-fieldchanged

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!