133 votes

switch case statement error : les expressions de cas doivent être des expressions constantes

Mon énoncé sur le switch-case fonctionne parfaitement hier. Mais lorsque j'ai exécuté le code plus tôt ce matin, eclipse m'a donné une erreur en soulignant les déclarations de cas en couleur rouge et dit : les expressions de cas doivent être des expressions constantes, il est constant Je ne sais pas ce qui s'est passé. Voici mon code ci-dessous :

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

Tous les R.id.int sont soulignés en rouge.

0 votes

Pouvez-vous fournir la définition de R.id.playbtn etc. Tout est-il statique et définitif ?

2 votes

Vous avez probablement supprimé/modifié votre mise en page et ces identifiants n'existent plus ou quelque chose comme ça...

0 votes

La classe R est généralement généré par l'IDE/les outils de développement, de sorte qu'il est généralement correct pour la version d'Android utilisée.

285voto

Benito Bertoli Points 9458

Dans un projet Android classique, les constantes de la classe de ressources R sont déclarées comme suit :

public static final int main=0x7f030004;

Cependant, à partir d'ADT 14, dans un projet de bibliothèque, ils seront déclarés comme ceci :

public static int main=0x7f030004;

En d'autres termes, les constantes ne sont pas définitives dans un projet de bibliothèque. Par conséquent, votre code ne compilerait plus.

La solution à ce problème est simple : Convertissez l'instruction switch en une instruction 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

Vous pouvez rapidement convertir un switch à un if-else en utilisant les éléments suivants :

Dans Eclipse
Déplacez votre curseur sur le switch et appuyez sur Ctrl + 1 puis sélectionnez

Convertir le "switch" en "if-else".

Dans Android Studio
Déplacez votre curseur sur le switch et appuyez sur Alt + Enter puis sélectionnez

Remplacez "switch" par "if".

0 votes

Je change mon instruction switch-case en instruction else-if J'ai créé un nouveau projet Android et j'ai utilisé une instruction switch-case qui fonctionne bien.

1 votes

Il se peut que votre premier projet utilise un projet de bibliothèque et que votre nouveau projet ne le fasse pas.

0 votes

Je ne comprends pas cela, désolé, je suis vraiment un débutant ici pouvez-vous m'expliquer ?

52voto

rick Points 299

Décocher "Is Library" dans les propriétés du projet a fonctionné pour moi.

2 votes

Faites un clic droit sur le nom de votre projet. Puis cliquez sur propriétés -> Android. En bas à droite de la fenêtre popup se trouve une section nommée "Library". Sous celle-ci, si l'option "is Library" est cochée, décochez-la si vous ne voulez pas que votre projet soit un projet de bibliothèque. Ensuite, nettoyez et reconstruisez. Si vous voulez qu'il soit un projet de bibliothèque, vous devez changer votre commutateur en un conditionnel if else comme indiqué ailleurs.

5 votes

Il y a des raisons pour lesquelles un projet de bibliothèque est marqué avec "Is Library". Il ne s'agit pas d'une bonne solution au problème, car elle brisera la structure de votre projet Android en faisant en sorte que ce qui devrait être une bibliothèque se comporte comme une application normale.

8voto

blackbelt Points 45840

R.id.*, depuis ADT 14 ne sont plus déclarés comme final static int donc vous ne pouvez pas utiliser dans la construction switch case. Vous pouvez utiliser la clause if else à la place.

0 votes

Oui, j'ai lu cela sur tools.Android.com, j'ai également essayé de créer un nouveau projet et utilisé le code ci-dessus et cela fonctionne très bien comment est-ce possible ?

1 votes

outils.Android.com/recent/buildchangesinrevision14 voir la section "Refonte du projet de bibliothèque

6 votes

Pourquoi ont-ils fait ce changement, cela n'a aucun sens.

8voto

Pir Fahim Shah Points 1786

Une solution simple pour ce problème est :

Cliquez sur le commutateur puis appuyez sur CTL+1, Cela changera votre interrupteur en un bloc d'instructions if-else, et résoudra votre problème.

7voto

pablisco Points 2478

Comment au sujet de cette solution pour garder l'interrupteur belle place d'un 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);
    }

}

Donc, dans votre code, vous pouvez le faire:

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

Les énumérations sont statiques alors cela aura un impact très limité. La seule fenêtre de préoccupation serait le double de recherche impliqués (d'abord sur le plan interne SparseArray et, plus tard, sur l'interrupteur de la table)

Cela dit, cette enum peut aussi être utilisée pour extraire les éléments dans un fluide manière, en cas de besoin pour garder une référence à l'id... mais c'est une histoire pour une autre fois.

0 votes

Les Enums sont déconseillés dans Android en raison de leur gonflement de la mémoire ; c'est la raison principale pour laquelle ils ne sont jamais utilisés dans AOSP - et la raison pour laquelle vous voyez des ints partout.

1 votes

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X