Android Studio报错constant expression required,底部导航栏代码求助
问题
在Android Studio中用Java实现底部导航栏时,switch语句里的R.id.home、R.id.favorites、R.id.tools、R.id.status持续报“constant expression required”错误,相关代码如下:
MainActivity代码
package com.rpitest.appmudu; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.MenuItem; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.navigation.NavigationBarView; public class MainActivity extends AppCompatActivity { BottomNavigationView bottomNavigationView; HomeFragment homeFragment = new HomeFragment(); FavoritesFragment favoritesFragment = new FavoritesFragment(); ToolsFragment toolsFragment = new ToolsFragment(); StatusFragment statusFragment = new StatusFragment(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bottomNavigationView = findViewById(R.id.bottom_navigation); getSupportFragmentManager().beginTransaction().replace(R.id.container,homeFragment).commit(); bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.home: getSupportFragmentManager().beginTransaction().replace(R.id.container,homeFragment).commit(); return true; case R.id.favorites: getSupportFragmentManager().beginTransaction().replace(R.id.container,favoritesFragment).commit(); return true; case R.id.tools: getSupportFragmentManager().beginTransaction().replace(R.id.container,toolsFragment).commit(); return true; case R.id.status: getSupportFragmentManager().beginTransaction().replace(R.id.container,statusFragment).commit(); return true; } return false; } }); } }
菜单XML代码(menu目录下)
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/home" android:title="Home" android:icon="@drawable/icon_home"/> <item android:id="@+id/favorites" android:title="favorites" android:icon="@drawable/icon_favorites"/> <item android:id="@+id/tools" android:title="Tools" android:icon="@drawable/icon_tools"/> <item android:id="@+id/status" android:title="Status" android:icon="@drawable/icon_status"/> </menu> ## 解决方案 ### 报错原因 Java的switch case要求case分支的值必须是**编译时常量**,但默认配置下,旧版Android Gradle插件生成的`R.id`字段不是final类型(属于运行时常量),因此触发该错误。 ### 两种解决方法 #### 方法一:用if-else替代switch 直接替换switch逻辑为if-else判断,避开常量要求: ```java @Override public boolean onNavigationItemSelected(MenuItem item) { int itemId = item.getItemId(); if (itemId == R.id.home) { getSupportFragmentManager().beginTransaction().replace(R.id.container, homeFragment).commit(); return true; } else if (itemId == R.id.favorites) { getSupportFragmentManager().beginTransaction().replace(R.id.container, favoritesFragment).commit(); return true; } else if (itemId == R.id.tools) { getSupportFragmentManager().beginTransaction().replace(R.id.container, toolsFragment).commit(); return true; } else if (itemId == R.id.status) { getSupportFragmentManager().beginTransaction().replace(R.id.container, statusFragment).commit(); return true; } return false; }
方法二:让R.id成为编译时常量
如果想保留switch写法,可在模块的build.gradle(或build.gradle.kts)中添加配置,让AGP生成final类型的R字段:
android { buildFeatures { buildConfig = true resValues = true } // 若使用AGP 3.0~7.0版本,可替换为: // defaultConfig { // generateBuildConfig true // } }
配置完成后同步项目,R.id就会变成编译时常量,switch语句即可正常编译。
内容的提问来源于stack exchange,提问作者Andi St
相关产品推荐
相关产品推荐

