You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个Activity中实现多个DrawerLayout?

同一Activity中实现多个DrawerLayout的方案

需求说明

需求:在同一个Activity中打开多个导航页面(DrawerLayout),一个通过Toolbar触发,其他通过普通按钮触发。已知OpenDrawer(GravityCompat.Start);可实现按钮打开侧边栏,寻求多DrawerLayout的实现方法。
环境:基于默认导航项目修改
已执行操作:将activity_main.xml的根布局改为FrameLayout,添加2个DrawerLayout;在app_bar_main.xml中新增一个Toolbar。

现有代码问题修正

  1. app_bar_main.xml布局错误:AppBarLayout内部存在无效的冗余标签,导致Toolbar无法正常渲染
  2. MainActivity控件绑定错误:获取第二个Toolbar时误绑定了第一个Toolbar的ID,导致第二个DrawerLayout的Toggle无法正常工作
  3. DrawerLayout重叠问题:两个DrawerLayout直接放在FrameLayout中会重叠,需要通过显示状态控制避免冲突

完整修正代码

1. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             xmlns:tools="http://schemas.android.com/tools"
             android:id="@+id/frame_drawer"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <!-- 第一个DrawerLayout:通过Toolbar触发 -->
    <androidx.drawerlayout.widget.DrawerLayout
         android:id="@+id/drawer_layout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:fitsSystemWindows="true"
         tools:openDrawer="start">

        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <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"
            android:fitsSystemWindows="true"
            app:menu="@menu/activity_main_drawer" />

    </androidx.drawerlayout.widget.DrawerLayout>

    <!-- 第二个DrawerLayout:默认隐藏,通过按钮触发 -->
    <androidx.drawerlayout.widget.DrawerLayout
         android:id="@+id/drawer_layout2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:fitsSystemWindows="true"
         android:visibility="gone"
         tools:openDrawer="start">

        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:menu="@menu/activity_main_drawer" />

    </androidx.drawerlayout.widget.DrawerLayout>
</FrameLayout>

2. app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar2"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

3. MainActivity.cs

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity, NavigationView.IOnNavigationItemSelectedListener
{
    private DrawerLayout _drawerLayout1;
    private DrawerLayout _drawerLayout2;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        // 初始化第一个Toolbar和DrawerLayout
        Toolbar toolbar1 = FindViewById<Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar1);
        SupportActionBar.Title = "Site 1";

        _drawerLayout1 = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
        ActionBarDrawerToggle toggle1 = new ActionBarDrawerToggle(this, _drawerLayout1, toolbar1, 
            Resource.String.navigation_drawer_open, Resource.String.navigation_drawer_close);
        _drawerLayout1.AddDrawerListener(toggle1);
        toggle1.SyncState();

        NavigationView navView1 = FindViewById<NavigationView>(Resource.Id.nav_view);
        navView1.SetNavigationItemSelectedListener(this);

        // 初始化第二个Toolbar和DrawerLayout
        Toolbar toolbar2 = FindViewById<Toolbar>(Resource.Id.toolbar2);
        toolbar2.Title = "Site 2";
        toolbar2.SetNavigationIcon(Resource.Drawable.ic_menu);
        toolbar2.NavigationClick += (s, e) => 
        {
            _drawerLayout1.Visibility = ViewStates.Gone;
            _drawerLayout2.Visibility = ViewStates.Visible;
            _drawerLayout2.OpenDrawer(GravityCompat.Start);
        };

        _drawerLayout2 = FindViewById<DrawerLayout>(Resource.Id.drawer_layout2);
        _drawerLayout2.AddDrawerListener(new DrawerLayout.SimpleDrawerListener()
        {
            public override void OnDrawerClosed(View drawerView)
            {
                base.OnDrawerClosed(drawerView);
                _drawerLayout2.Visibility = ViewStates.Gone;
                _drawerLayout1.Visibility = ViewStates.Visible;
            }
        });

        NavigationView navView2 = FindViewById<NavigationView>(Resource.Id.nav_view2);
        navView2.SetNavigationItemSelectedListener(this);

        // 绑定FAB点击事件打开第二个DrawerLayout
        FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
        fab.Click += FabOnClick;
    }

    private void FabOnClick(object sender, EventArgs eventArgs)
    {
        _drawerLayout1.Visibility = ViewStates.Gone;
        _drawerLayout2.Visibility = ViewStates.Visible;
        _drawerLayout2.OpenDrawer(GravityCompat.Start);
    }

    public bool OnNavigationItemSelected(IMenuItem item)
    {
        int id = item.ItemId;
        // 按需添加菜单点击逻辑

        if (_drawerLayout1.IsDrawerOpen(GravityCompat.Start))
        {
            _drawerLayout1.CloseDrawer(GravityCompat.Start);
        }
        if (_drawerLayout2.IsDrawerOpen(GravityCompat.Start))
        {
            _drawerLayout2.CloseDrawer(GravityCompat.Start);
        }

        return true;
    }

    public override void OnBackPressed()
    {
        if (_drawerLayout1.IsDrawerOpen(GravityCompat.Start))
        {
            _drawerLayout1.CloseDrawer(GravityCompat.Start);
        }
        else if (_drawerLayout2.IsDrawerOpen(GravityCompat.Start))
        {
            _drawerLayout2.CloseDrawer(GravityCompat.Start);
        }
        else
        {
            base.OnBackPressed();
        }
    }
}

关键实现要点

  • 布局控制:两个DrawerLayout通过android:visibility属性切换显示状态,避免界面重叠
  • Toolbar处理:一个Activity仅能设置一个SupportActionBar,第二个Toolbar通过手动添加导航图标和点击事件触发对应DrawerLayout
  • Drawer监听:给第二个DrawerLayout添加关闭监听,自动恢复第一个DrawerLayout的显示
  • 返回键适配:优先关闭当前打开的侧边栏,再处理默认返回逻辑

内容的提问来源于stack exchange,提问作者yuki yuki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:30:52