Почему выполняются обе стороны оператора if else и как это исправить? - PullRequest
3 голосов
/ 09 сентября 2011

У меня есть блок кода:

passwordEditText.setOnKeyListener(new OnKeyListener() 
    {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) 
        {
            if (keyCode == KeyEvent.KEYCODE_ENTER)
            {
                launch.performClick();
                return true;

            }
            else
            {
                return false;
            }
        }
    });

Я хочу, чтобы при нажатии клавиши ввода выполнялась команда входа в систему (запуск - кнопка, выполняющая вход в систему).Однако после выполнения блока true он продолжает выполнять блок else, возвращая false и вызывая (только на некоторых устройствах) вход в систему во второй раз.

Так что мой вопрос состоит из двухparts: Как оператор if else может быть оценен как true и false, и как я могу сделать так, чтобы он не делал этого.Я подумал о нескольких приемах, чтобы это произошло, но, похоже, это проблема, которая лучше понимается, чем быстро исправляется.

Ответы [ 5 ]

9 голосов
/ 09 сентября 2011

Вы видите, что OnKey запускается дважды, первый раз при нажатии клавиши, и второй раз при нажатии клавиши вверх, поэтому вам нужно отфильтровать его с помощью

    if (event.getAction()!=KeyEvent.ACTION_DOWN) {
        return true;
    }

    switch (keyCode) {
       case KeyEvent.KEYCODE_1 : 
            //do something
            break;
       case KeyEvent.KEYCODE_2 : 
            //do something
            break;
       case KeyEvent.KEYCODE_3 : 
            //do something
            break;
    }

    return true;
1 голос
/ 13 сентября 2011

попробуйте с этим кодом ...

passwordEditText.setOnKeyListener (new OnKeyListener () {

    public boolean onKey(View v, int keyCode, KeyEvent event) 
    {
        if (keyCode == KeyEvent.KEYCODE_ENTER)
        {
            launch.performClick();
            return true;

        }
        return false;

    }
});
1 голос
/ 09 сентября 2011

Отладчик может вводить в заблуждение, когда условный результат просто приводит к оператору возврата.Вставьте бесполезную переменную int x и присвойте ей x = 2 (скажем) перед возвращением true и x = 3 (скажем) перед возвращением false.Пройдите снова в отладчике, держу пари, вы видите, что он входит только в один из блоков

0 голосов
/ 09 сентября 2011

При нажатии клавиши (или удержании, или отпускании) запускается несколько событий.

Специально для пресса и выпуска запускается следующее:

ACTION_DOWN

ACTION_DOWN (если удерживается, с ненулевым repeatCount, событие может повторяться несколько раз)

ACTION_UP (возможно, с установленным FLAG_CANCELED, если событие было отменено)

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

Заменить

if (keyCode == KeyEvent.KEYCODE_ENTER)

с

if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP)

если вы хотите, чтобы это срабатывало только один раз, когда ключ отпущен. Проверка ACTION_DOWN требует дополнительной фильтрации, чтобы избежать множественных возгораний из-за повторения ключа. Возможно, вы также захотите проверить состояние FLAG_CANCELED, когда происходит ACTION_UP.

0 голосов
/ 09 сентября 2011

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

Тем не менее, некоторые ошибки кодирования могут привести программиста к мысли, что выполняются блоки if и else.Например,

if(condition) {
  // do something
}
else; // note the semicolon here
{
  // do something else
  // this gets executed regardless of whether the condition is true!
}

Но даже тогда, если у вас есть "return" в вашем блоке "if", вы не сможете добраться до 2-го блока:)

...