Ошибка оператора case: выражение выражения должно быть постоянным выражением

Мой оператор switch-case работает отлично. Но когда я запускаю код ранее утром, затмение дало мне ошибку, подчеркивающую утверждения case красным цветом и говорит: case-выражения должны быть постоянным выражением, оно постоянное, я не знаю, что произошло. Здесь мой код ниже:

public void onClick(View src)
    {
        switch(src.getId()) {
        case R.id.playbtn:
            checkwificonnection();
            break;

        case R.id.stopbtn:
            Log.d(TAG, "onClick: stopping srvice");
            Playbutton.setImageResource(R.drawable.playbtn1);
            Playbutton.setVisibility(0); //visible
            Stopbutton.setVisibility(4); //invisible
            stopService(new Intent(RakistaRadio.this,myservice.class));
            clearstatusbar();
            timer.cancel();
            Title.setText(" ");
            Artist.setText(" ");
            break;

        case R.id.btnmenu:
            openOptionsMenu();
            break;
        }
    }

Все элементы R.id.int подчеркнуты красным цветом.

Ответ 1

В обычном Android-проекте константы класса ресурса R объявляются следующим образом:

public static final int main=0x7f030004;

Однако с ADT 14 в проекте библиотеки они будут объявлены следующим образом:

public static int main=0x7f030004;

Другими словами, константы не являются окончательными в проекте библиотеки. Поэтому ваш код больше не будет компилироваться.

Решение для этого просто: Преобразуйте оператор switch в инструкцию if-else.

public void onClick(View src)
{
    int id = src.getId();
    if (id == R.id.playbtn){
        checkwificonnection();
    } else if (id == R.id.stopbtn){
        Log.d(TAG, "onClick: stopping srvice");
        Playbutton.setImageResource(R.drawable.playbtn1);
        Playbutton.setVisibility(0); //visible
        Stopbutton.setVisibility(4); //invisible
        stopService(new Intent(RakistaRadio.this,myservice.class));
        clearstatusbar();
        timer.cancel();
        Title.setText(" ");
        Artist.setText(" ");
    } else if (id == R.id.btnmenu){
        openOptionsMenu();
    }
}

http://tools.android.com/tips/non-constant-fields

Вы можете быстро преобразовать оператор switch в оператор if-else, используя следующее:

В Eclipse
Переместите курсор на ключевое слово switch и нажмите Ctrl + 1, затем выберите

Преобразуйте 'переключатель' в 'if-else'.

В Android Studio
Переместите курсор на ключевое слово switch и нажмите Alt + Enter, затем выберите

Заменить "переключатель" на "if".

Ответ 2

Снимите флажок "Является ли библиотека" в проекте "Свойства" для меня.

Ответ 3

R.id. *, поскольку ADT 14 не более объявлены как final static int, поэтому вы не можете использовать в конструкции case switch. Вместо этого вы можете использовать if else.

Ответ 4

Простое решение этой проблемы:

Нажмите переключатель , а затем нажмите CTL + 1,. Он изменит ваш переключатель на оператор блока if-else и решит вашу проблему.

Ответ 5

Как об этом другом решении сохранить хороший коммутатор вместо if-else:

private enum LayoutElement {
    NONE(-1),
    PLAY_BUTTON(R.id.playbtn),
    STOP_BUTTON(R.id.stopbtn),
    MENU_BUTTON(R.id.btnmenu);

    private static class _ {
        static SparseArray<LayoutElement> elements = new SparseArray<LayoutElement>();
    }

    LayoutElement(int id) {
        _.elements.put(id, this);
    }

    public static LayoutElement from(View view) {
        return _.elements.get(view.getId(), NONE);
    }

}

Итак, в коде вы можете сделать это:

public void onClick(View src) {
    switch(LayoutElement.from(src)) {
    case PLAY_BUTTTON:
        checkwificonnection();
        break;

    case STOP_BUTTON:
        Log.d(TAG, "onClick: stopping srvice");
        Playbutton.setImageResource(R.drawable.playbtn1);
        Playbutton.setVisibility(0); //visible
        Stopbutton.setVisibility(4); //invisible
        stopService(new Intent(RakistaRadio.this,myservice.class));
        clearstatusbar();
        timer.cancel();
        Title.setText(" ");
        Artist.setText(" ");
        break;

    case MENU_BUTTON:
        openOptionsMenu();
        break;
    }
}

Перечисления являются статическими, поэтому это будет иметь очень ограниченное влияние. Единственное окно для беспокойства - это двойной поиск (сначала на внутреннем SparseArray, а затем на таблице коммутаторов)

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

Ответ 6

Решение может быть выполнено следующим образом:

  • Просто назначьте значение Целое
  • Сделайте переменную до final

Пример:

public static final int cameraRequestCode = 999;

Надеюсь, это поможет вам.

Ответ 7

Это была ошибка, когда я использовал переключатель в функции с переменными, объявленными в моем классе:

private void ShowCalendar(final Activity context, Point p, int type) 
{
    switch (type) {
        case type_cat:
            break;

        case type_region:
            break;

        case type_city:
            break;

        default:
            //sth
            break;
    }
}

Проблема была решена, когда я объявил final переменным в начале класса:

final int type_cat=1, type_region=2, type_city=3;

Ответ 8

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

Теперь я попытался удалить библиотеку, которую я добавил, даже тогда она не сработала. как когда-либо " при очистке проекта" все ошибки просто погасли!