You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Navigation Drawer开发:Switch Case报常量表达式要求错误

解决Navigation Drawer菜单Item ID在switch case中报错“constant expression required”的问题

问题原因

从Android Gradle Plugin 3.0版本开始,默认启用了**非传递R类(Non-transitive R Class)**特性。该特性会让模块R类中的字段(如R.id.nav_item1)不再是编译时常量,而是普通变量。而Java的switch语句要求case后必须是编译时常量,因此直接用R.id作为case值会触发编译错误。

解决方案

方案1:改用if-else语句替代switch(推荐)

这是适配非传递R类特性最直接的方式,代码逻辑清晰且符合官方优化趋势:

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    int itemId = item.getItemId();
    if (itemId == R.id.nav_item1) {
        // 处理Item 1的逻辑
    } else if (itemId == R.id.nav_item2) {
        // 处理Item 2的逻辑
    }
    // 可添加更多菜单项的判断分支
    drawerLayout.closeDrawers();
    return true;
}

方案2:将菜单ID定义为编译时常量

如果坚持使用switch,可以手动把需要用到的菜单ID定义为static final常量(需确保常量值与XML中定义的ID完全一致):

public class drawer_left extends AppCompatActivity {
    private static final int NAV_ITEM1 = R.id.nav_item1;
    private static final int NAV_ITEM2 = R.id.nav_item2;

    // ... 其他成员变量与生命周期代码

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case NAV_ITEM1:
                // 处理Item 1的逻辑
                break;
            case NAV_ITEM2:
                // 处理Item 2的逻辑
                break;
        }
        drawerLayout.closeDrawers();
        return true;
    }
}

方案3:关闭非传递R类特性(不推荐)

可以在模块的build.gradle(或build.gradle.kts)中关闭该特性,但这会导致R类体积增大、编译速度变慢,不符合Android官方的优化方向:

android {
    buildFeatures {
        nonTransitiveRClass = false
    }
}

补充说明

非传递R类是官方为优化编译效率、减少R类冗余推出的特性,建议优先使用方案1(if-else)来适配,避免依赖旧的R类行为。

内容的提问来源于stack exchange,提问作者Sriram S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 09:27:13