多模块Android项目中NavigationDrawer复用及页面跳转优化咨询
针对你这个多模块项目里NavigationDrawer复用和跳转体验的问题,我给你几个实战中常用的解决思路,你可以根据项目情况选:
这是最直接的复用思路:
- 新建一个
base公共模块,把NavigationDrawer的核心逻辑(比如抽屉布局、菜单点击、状态管理)封装成BaseDrawerActivity或者BaseDrawerFragment。 - 其他业务模块(settings、login、places)的页面直接继承这个基础类,不用重复写抽屉的代码。
- 这样每个模块的页面自带抽屉,跳转时直接启动目标模块的Activity就行,完全不用经过app模块中转,自然不会出现短暂看到app界面的问题。
- 注意:base模块要引入AndroidX的
navigation-drawer相关依赖,其他业务模块依赖base模块即可。
这是现在Android开发的主流方案,体验最流畅:
- 整个项目只保留app模块里的一个主Activity,所有模块的页面都做成Fragment。
- NavigationDrawer直接放在主Activity的布局里,所有页面共享同一个抽屉。
- 用Jetpack Navigation管理页面跳转,切换页面只是替换Fragment,不会有Activity销毁重建的情况,自然看不到app模块的界面。
- 每个业务模块可以单独定义自己的导航图,然后在app模块的主导航图里引用这些子导航图,既保证了模块解耦,又能统一管理跳转。
- 给你个主Activity布局的示例:
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 主内容区:承载各个模块的Fragment --> <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/main_nav_graph" /> <!-- 侧边抽屉菜单 --> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/drawer_main_menu" /> </androidx.drawerlayout.widget.DrawerLayout>
3. 封装Drawer管理类,跨模块直接跳转目标Activity
如果不想改单Activity架构,这个方案也能解决问题:
- 在base模块里写一个
DrawerManager类,把抽屉的初始化、菜单点击、状态控制等逻辑都封装进去。 - 每个业务模块的Activity都初始化这个
DrawerManager,绑定自己页面的抽屉布局。 - 跳转时直接在当前模块启动目标模块的Activity,目标Activity自己初始化抽屉,完全不用经过app模块中转。
- 举个
DrawerManager的核心代码例子:
class DrawerManager(private val activity: AppCompatActivity) { private lateinit var drawerLayout: DrawerLayout private lateinit var navView: NavigationView fun init(drawerLayoutId: Int, navViewId: Int) { drawerLayout = activity.findViewById(drawerLayoutId) navView = activity.findViewById(navViewId) setupMenuClickListener() } private fun setupMenuClickListener() { navView.setNavigationItemSelectedListener { menuItem -> when (menuItem.itemId) { R.id.nav_settings -> activity.startActivity(Intent(activity, SettingsActivity::class.java)) R.id.nav_login -> activity.startActivity(Intent(activity, LoginActivity::class.java)) R.id.nav_places -> activity.startActivity(Intent(activity, PlacesActivity::class.java)) } drawerLayout.closeDrawers() true } } fun openDrawer() = drawerLayout.openDrawer(GravityCompat.START) fun closeDrawer() = drawerLayout.closeDrawers() }
- 然后在业务模块的Activity里用:
class SettingsActivity : AppCompatActivity() { private lateinit var drawerManager: DrawerManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_settings) drawerManager = DrawerManager(this) drawerManager.init(R.id.drawer_layout, R.id.nav_view) // 给Toolbar绑定打开抽屉的按钮 findViewById<Toolbar>(R.id.toolbar).setNavigationOnClickListener { drawerManager.openDrawer() } } }
个人最推荐方案2,不仅解决了你的跳转体验问题,还符合现代Android开发的最佳实践,模块间的解耦和维护性都更好。
内容的提问来源于stack exchange,提问作者just
相关产品推荐
相关产品推荐

