Android中Java Switch Case用R.id编译报错(需常量表达式)求解决
修复Android底部导航栏switch判断的"constant expression required"编译错误
问题场景
我为底部导航栏定义了如下item:
<item android:id="@+id/nav_home" android:title="Home" android:icon="@drawable/baseline_home_24"/> <item android:id="@+id/nav_qr" android:title="QR Scanner" android:icon="@drawable/baseline_qr_code_scanner_24"/> <item android:id="@+id/nav_students" android:title="Students" android:icon="@drawable/baseline_group_24"/> <item android:id="@+id/nav_attendance" android:title="Attendance" android:icon="@drawable/baseline_list_24"/>
随后在MainActivity中通过switch判断底部导航栏选中项ID:
binding.bottomNavView.setOnItemSelectedListener(item -> { switch (item.getItemId()) { case R.id.nav_home: replaceFragment(new HomeFragment()); break; case R.id.nav_students: replaceFragment(new StudentFragment()); break; case R.id.nav_attendance: replaceFragment(new AttendanceFragment()); break; case R.id.nav_qr: replaceFragment(new QRFragment()); break; } return true; });
编译时出现错误,提示“constant expression required”,具体报错信息如下:
Task :app:compileDebugJavaWithJavac C:\Users\pc\AndroidStudioProjects\MyApplication\app\src\main\java\com\example\myapplication\MainActivity.java:34: error: constant expression required case R.id.nav_home: ^ C:\Users\pc\AndroidStudioProjects\MyApplication\app\src\main\java\com\example\myapplication\MainActivity.java:38: error: constant expression required case R.id.nav_students: ^ C:\Users\pc\AndroidStudioProjects\MyApplication\app\src\main\java\com\example\myapplication\MainActivity.java:42: error: constant expression required case R.id.nav_attendance: ^ C:\Users\pc\AndroidStudioProjects\MyApplication\app\src\main\java\com\example\myapplication\MainActivity.java:46: error: constant expression required case R.id.nav_qr: ^ Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. 4 errors Task :app:compileDebugJavaWithJavac FAILED
错误原因
Android Gradle Plugin 3.0及以上版本默认开启R8代码压缩,或手动启用了android.nonTransitiveRClass=true,这会导致R类中的ID不再是编译时常量,而是普通变量。而switch的case分支要求条件必须是编译时常量,因此触发编译错误。
修复方法
方法1:改用if-else语句替代switch
if-else判断不要求条件为编译时常量,直接替换即可:
binding.bottomNavView.setOnItemSelectedListener(item -> { int itemId = item.getItemId(); if (itemId == R.id.nav_home) { replaceFragment(new HomeFragment()); } else if (itemId == R.id.nav_students) { replaceFragment(new StudentFragment()); } else if (itemId == R.id.nav_attendance) { replaceFragment(new AttendanceFragment()); } else if (itemId == R.id.nav_qr) { replaceFragment(new QRFragment()); } return true; });
方法2:关闭非传递R类(针对特定场景)
如果是因为开启了nonTransitiveRClass导致的问题,可在模块级build.gradle(或build.gradle.kts)的android块中,移除该配置或设置为false:
android { // 移除该行,或设置为false // nonTransitiveRClass = true }
注意:关闭非传递RClass会增加编译时间,因为每个模块都会生成完整的R类,建议优先使用方法1。
内容的提问来源于stack exchange,提问作者Sir Craktus
相关产品推荐
相关产品推荐

