BlackBerry touchEvent outside Поле триггеров fieldChanged - PullRequest
4 голосов
/ 18 июня 2011

У меня проблема с тем, что если я нажимаю / касаюсь за пределами поля, событие fieldChanged() запускается для поля, которое имеет фокус.

Схема для моего MainScreen довольно проста, что-то вроде этого:

public class myMainScreen extends MainScreen implements FieldChangeListener{

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

        add(fm1);
        add(fm2);
    }

}

Если я нажимаю кнопку / поле внутри либо FieldManager, это работает нормально. Проблема в том, когда я нажимаю на пустое место. Поэтому, если бы я нажал внутри пустого пространства в fm2, а Field внутри fm1 имел фокус, его событие с изменением поля было бы вызвано.

В данный момент мое лекарство - поймать touchEvent и передать его соответствующему FieldManager. touchEvent для моего CustomFM будет обрабатывать получение поля и вызов fieldChanged, если поле действительно было нажато

Так что в myMainScreen touchEvent выглядит так:

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

И мой touchEvent для моего CustomFM2 есть. OFFSET является верхней y-позицией fm2 относительно экрана.

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;

}

Что мне интересно, так это то, что если есть более простое решение для этого? Я что-то упустил?

Ответы [ 3 ]

3 голосов
/ 13 августа 2012

Просто была такая же проблема.Основная проблема заключается в том, что navigationClick и trackwheelClick вызываются, если событие касания не используется в touchEvent.

Решение состоит в том, чтобы вызвать fieldChangeNotify в *Click методах only , если щелчок был вызван событием non-touch .События касания получают статус 0, поэтому вы можете проверить это следующим образом:

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

Этот метод означает, что вам не нужно отслеживать, было ли событие касания в пределах поля.

2 голосов
/ 21 июня 2011

Кажется, то, что я делал, было немного странно Мне не нужно было пропустить событие. Это делается естественным образом (или неестественно, так как Field, имеющий фокус, кажется, получает событие TouchEvents, если оно не было затронуто). Кажется, что происходит то, что после TouchEvent.Click a navigationClick отправляется на поле. В navigationClick я звонил fieldChangeNotify(0)

Чтобы исправить это, мои Field touchEvent и navigationClick теперь выглядят так:

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

Я также отслеживаю события касания, запускаемые в myMainScreen, например:

    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;

    }
1 голос
/ 21 июня 2011

Хитрость в том, чтобы вообще не переопределить touchEvent(TouchEvent message).:)

Просто переопределите navigationClick(int status, int time) для поля, которое вы хотите обработать щелчком (просто чтобы быть понятным - не нужно делать это для ButtonField - все работает хорошо, как есть).Инфраструктура пользовательского интерфейса BB будет вызывать navigationClick(int status, int time), когда пользователь нажимает ваше поле на сенсорном экране.Также это будет работать для устройств без сенсорного экрана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...