Android Navigation Drawer开发:Switch Case报常量表达式要求错误
问题原因
从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
相关产品推荐
相关产品推荐

