【问题标题】:Why is my DrawerLayout still open on activity resume, in spite of closing it?为什么我的 DrawerLayout 在活动恢复时仍然打开,尽管关闭它?
【发布时间】:2015-06-15 20:42:06
【问题描述】:

我有一个 DrawerLayout,其中包含链接到其他活动的项目的 ListView。 ListView 的 OnItemClick 事件是每个菜单元素的 switch-case,它运行代码

...
case targetActivity:
    listViewInstance.ClearChoices();
    drawerInstance.CloseDrawer(MainMenuLayout);
    drawerInstance.RequestLayout();

    StartActivity(targetIntent);
    break;
...

这基本上可以按预期工作,但是如果我更改设备方向并且 targetIntent 返回到带有 ClearTop 标志的基本活动,DrawerLayout 仍然是打开的!尽管对 CloseDrawer 进行了非常明确的调用,并且尽管我可以看到它在新活动开始时关闭。我究竟做错了什么? (如果相关,我正在使用 Xamarin.Android)。

[编辑 1: 我怀疑 CloseDrawer 仅在关闭动画完成时将抽屉注册为关闭,并且在此之前基本活动已暂停。如果我在不同的线程中调用 CloseDrawer 并在调用 StartActivity 之前暂停当前线程片刻,抽屉将按预期工作,尽管这当然不是一个合适的解决方案。有没有人知道如何以干净的方式解决这个问题?]。

[编辑 2: 一种可能的解决方案,linked here,是为抽屉的 OnDrawerClosed 事件创建一个事件监听器:

public class DrawerListener2 : DrawerLayout.SimpleDrawerListener
    {
        public override void OnDrawerClosed(View view)
        {
            base.OnDrawerClosed(view);

            var listParent = (RelativeLayout)view;
            var listViewInstance = listParent.FindViewById<ListView>(Resource.Id.mainmenu);

            int selectedIndex = menuListView.CheckedItemPosition;

            switch (selectedIndex)
            {
                case 0:
                    // Start activity A
                    break;
                case 2: // Element 1 is a menu spacer
                    // Start activity B
                    break;
                case 3:
                    // Start activity C
                    break;
            }
        }
    }

...
// In base activity's OnResume:
drawerInstance.SetDrawerListener(new DrawerListener2());
...

这有两个问题无法解决:我必须在 switch-case 中重新创建菜单项顺序,因为我无法在 OnDrawerClosed 处理程序中访问包含此信息的对象,而且我也可以' t 从事件处理程序启动所需的活动,因为这些活动需要来自基本活动的意图信息]。

【问题讨论】:

  • 你在任何地方使用SyncState()吗?
  • 在任何地方都没有 SyncState(),没有。在这一点上我相当有信心,问题在于抽屉状态仅在动画完成后保存,并且持有抽屉的 Activity 在此之前停止。

标签: android xamarin.android android-navigation


【解决方案1】:

通过半丑黑客解决:

在基础活动中,创建将其值存储为 Extra 的属性:

private bool ForceDrawerMenuCloseOnActivityResume
    {
        get { return Intent.GetBooleanExtra("ForceDrawerMenuCloseOnActivityResumeKey", false); }
        set { Intent.PutExtra("ForceDrawerMenuCloseOnActivityResumeKey", value); } 
    }

在基础活动的 OnResume() 中,如果设置了此属性,则重新关闭抽屉:

if (ForceDrawerMenuCloseOnActivityResume) { 
            drawerInstance.CloseDrawer(MainMenuLayout);
            ForceDrawerMenuCloseOnActivityResume = false;
        }

当关闭抽屉时,紧接在启动导致抽屉在活动恢复时保持打开的活动之前:

case targetActivity:
    drawerInstance.CloseDrawer(MainMenuLayout);
    listViewInstance.ClearChoices();
    ForceDrawerMenuCloseOnActivityResume = true;

    StartActivity(targetIntent);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    相关资源
    最近更新 更多