为什么我的 DrawerLayout 在 activity 恢复时仍然打开,尽管它已关闭?
Why is my DrawerLayout still open on activity resume, in spite of closing it?
我有一个 DrawerLayout,其中包含 link 到其他 Activity 的项目的 ListView。 ListView 的 OnItemClick 事件是每个菜单元素的 switch-case,它运行代码
...
case targetActivity:
listViewInstance.ClearChoices();
drawerInstance.CloseDrawer(MainMenuLayout);
drawerInstance.RequestLayout();
StartActivity(targetIntent);
break;
...
这基本上按预期工作,但如果我将设备方向和 targetIntent returns 更改为带有 ClearTop 标志的基础 activity,DrawerLayout 仍然打开!尽管非常明确地调用了 CloseDrawer,尽管事实上我可以看到它在新的 activity 开始时关闭。我究竟做错了什么? (我正在使用 Xamarin.Android,如果相关的话)。
[编辑 1: 我怀疑 CloseDrawer 仅在关闭动画完成时才将抽屉注册为已关闭,并且基础 activity 在此之前暂停.如果我在另一个线程中调用 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 处理程序中访问包含此信息的对象,而且我还无法从事件处理程序启动所需的活动,因为这些活动需要来自基础 activity] 的意图信息。
由半丑陋的黑客解决:
在基础 activity 中,创建 属性 将其值存储为 Extra:
private bool ForceDrawerMenuCloseOnActivityResume
{
get { return Intent.GetBooleanExtra("ForceDrawerMenuCloseOnActivityResumeKey", false); }
set { Intent.PutExtra("ForceDrawerMenuCloseOnActivityResumeKey", value); }
}
在基础 activity 的 OnResume() 中,如果设置了 属性,则重新关闭抽屉:
if (ForceDrawerMenuCloseOnActivityResume) {
drawerInstance.CloseDrawer(MainMenuLayout);
ForceDrawerMenuCloseOnActivityResume = false;
}
关闭抽屉时,在启动 activity 之前立即导致抽屉在 activity 恢复上保持打开状态:
case targetActivity:
drawerInstance.CloseDrawer(MainMenuLayout);
listViewInstance.ClearChoices();
ForceDrawerMenuCloseOnActivityResume = true;
StartActivity(targetIntent);
我有一个 DrawerLayout,其中包含 link 到其他 Activity 的项目的 ListView。 ListView 的 OnItemClick 事件是每个菜单元素的 switch-case,它运行代码
...
case targetActivity:
listViewInstance.ClearChoices();
drawerInstance.CloseDrawer(MainMenuLayout);
drawerInstance.RequestLayout();
StartActivity(targetIntent);
break;
...
这基本上按预期工作,但如果我将设备方向和 targetIntent returns 更改为带有 ClearTop 标志的基础 activity,DrawerLayout 仍然打开!尽管非常明确地调用了 CloseDrawer,尽管事实上我可以看到它在新的 activity 开始时关闭。我究竟做错了什么? (我正在使用 Xamarin.Android,如果相关的话)。
[编辑 1: 我怀疑 CloseDrawer 仅在关闭动画完成时才将抽屉注册为已关闭,并且基础 activity 在此之前暂停.如果我在另一个线程中调用 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 处理程序中访问包含此信息的对象,而且我还无法从事件处理程序启动所需的活动,因为这些活动需要来自基础 activity] 的意图信息。
由半丑陋的黑客解决:
在基础 activity 中,创建 属性 将其值存储为 Extra:
private bool ForceDrawerMenuCloseOnActivityResume
{
get { return Intent.GetBooleanExtra("ForceDrawerMenuCloseOnActivityResumeKey", false); }
set { Intent.PutExtra("ForceDrawerMenuCloseOnActivityResumeKey", value); }
}
在基础 activity 的 OnResume() 中,如果设置了 属性,则重新关闭抽屉:
if (ForceDrawerMenuCloseOnActivityResume) {
drawerInstance.CloseDrawer(MainMenuLayout);
ForceDrawerMenuCloseOnActivityResume = false;
}
关闭抽屉时,在启动 activity 之前立即导致抽屉在 activity 恢复上保持打开状态:
case targetActivity:
drawerInstance.CloseDrawer(MainMenuLayout);
listViewInstance.ClearChoices();
ForceDrawerMenuCloseOnActivityResume = true;
StartActivity(targetIntent);