如何在Kotlin中实现带图标、标题、副标题的导航抽屉菜单项及选中样式?
在Kotlin中实现带图标、标题副标题的导航抽屉菜单项及选中效果
1. 自定义菜单项布局
默认导航菜单没有副标题显示,先创建自定义布局res/layout/nav_drawer_item.xml,用来容纳图标、主标题和副标题:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="16dp" android:background="@drawable/nav_item_selector" android:gravity="center_vertical"> <ImageView android:id="@+id/nav_item_icon" android:layout_width="24dp" android:layout_height="24dp" android:layout_marginEnd="16dp"/> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/nav_item_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="@color/nav_item_text_color"/> <TextView android:id="@+id/nav_item_subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" android:textColor="@color/nav_item_subtitle_color"/> </LinearLayout> </LinearLayout>
2. 定义选中状态背景Selector
创建res/drawable/nav_item_selector.xml,控制选中/未选中的背景样式:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/selected_nav_item_bg" android:state_checked="true"/> <item android:drawable="@android:color/transparent"/> </selector>
同时在res/values/colors.xml添加对应颜色值:
<color name="selected_nav_item_bg">#FFE0F7FA</color> <color name="nav_item_text_color">#FF000000</color> <color name="nav_item_subtitle_color">#FF757575</color>
3. 配置导航菜单资源
在res/menu/nav_menu.xml中添加菜单项,指定使用自定义布局:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_home" android:title="" app:actionLayout="@layout/nav_drawer_item"/> <item android:id="@+id/nav_profile" android:title="" app:actionLayout="@layout/nav_drawer_item"/> <item android:id="@+id/nav_settings" android:title="" app:actionLayout="@layout/nav_drawer_item"/> </group> </menu>
这里留空默认android:title,后续在代码中设置自定义布局里的文本内容。
4. Kotlin代码绑定菜单内容
在Activity(如MainActivity.kt)中找到NavigationView,为每个菜单项设置图标、标题和副标题:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navView = findViewById<NavigationView>(R.id.nav_view) val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout) val toggle = ActionBarDrawerToggle( this, drawerLayout, R.string.navigation_drawer_open, R.string.navigation_drawer_close ) drawerLayout.addDrawerListener(toggle) toggle.syncState() // 绑定菜单内容 setupNavMenuItems(navView) // 设置默认选中项 navView.setCheckedItem(R.id.nav_home) } private fun setupNavMenuItems(navView: NavigationView) { // 首页项 val homeItem = navView.menu.findItem(R.id.nav_home) val homeLayout = homeItem.actionView as LinearLayout homeLayout.findViewById<ImageView>(R.id.nav_item_icon).setImageResource(R.drawable.ic_home) homeLayout.findViewById<TextView>(R.id.nav_item_title).text = "首页" homeLayout.findViewById<TextView>(R.id.nav_item_subtitle).text = "查看最新内容" // 个人资料项 val profileItem = navView.menu.findItem(R.id.nav_profile) val profileLayout = profileItem.actionView as LinearLayout profileLayout.findViewById<ImageView>(R.id.nav_item_icon).setImageResource(R.drawable.ic_profile) profileLayout.findViewById<TextView>(R.id.nav_item_title).text = "个人资料" profileLayout.findViewById<TextView>(R.id.nav_item_subtitle).text = "编辑你的信息" // 设置项 val settingsItem = navView.menu.findItem(R.id.nav_settings) val settingsLayout = settingsItem.actionView as LinearLayout settingsLayout.findViewById<ImageView>(R.id.nav_item_icon).setImageResource(R.drawable.ic_settings) settingsLayout.findViewById<TextView>(R.id.nav_item_title).text = "设置" settingsLayout.findViewById<TextView>(R.id.nav_item_subtitle).text = "调整应用偏好" } }
5. 处理菜单项选中事件
为NavigationView设置选中监听器,处理点击逻辑并维护选中状态:
// 在onCreate方法中添加监听器 navView.setNavigationItemSelectedListener { menuItem -> // 处理各菜单项的业务逻辑 when (menuItem.itemId) { R.id.nav_home -> { supportFragmentManager.beginTransaction() .replace(R.id.nav_host_fragment_content_main, HomeFragment()) .commit() } R.id.nav_profile -> { supportFragmentManager.beginTransaction() .replace(R.id.nav_host_fragment_content_main, ProfileFragment()) .commit() } R.id.nav_settings -> { supportFragmentManager.beginTransaction() .replace(R.id.nav_host_fragment_content_main, SettingsFragment()) .commit() } } // 关闭导航抽屉 drawerLayout.closeDrawer(GravityCompat.START) // 标记当前项为选中状态 menuItem.isChecked = true true }
注意事项
- 确保Activity布局中的NavigationView已正确引用菜单:
app:menu="@menu/nav_menu" - 代码中的图标资源请替换为你自己的项目资源
内容的提问来源于stack exchange,提问作者Sab
相关产品推荐
相关产品推荐

