我创建了一个NavigationDrawerFragment
,它实际上只是Android Studio生成的代码的略微修改版本。
我有一个包含Dashboard
的NavigationDrawerFragment
活动,该活动可以启动其他几个活动,每个活动也包含NavigationDrawerFragment
。让我们将这些活动之一称为Foo
。
如果使用仪表板的导航抽屉从Foo
输入Dashboard
,然后打开Foo的导航抽屉,则back button
将正确关闭导航抽屉。但是,如果我使用Foo
(在实现导航抽屉之前就已进入)进入UI element
,然后打开Foo的导航抽屉,则back button
返回到Dashboard活动,而不是关闭导航抽屉。
我不知道为什么会这样。对于NavigationDrawerFragment
,我具有ItemClickListener
,对于UI element
,我具有ClickListener
,但是在两种情况下,我都使用Foo
启动新的intent
活动。
我想知道是否设置了一些我没有意识到的东西,是否可以控制这些东西。
我知道我可以重写onBackPressed
来检查抽屉是否处于打开状态(如here所示),但这感觉很骇人,因为这里显然发生了一些我不知道的行为。
编辑:这与ActionBar-PullToRefresh有关。我从Foo
删除了它,并且导航抽屉正常工作。
编辑2:正如@adneal所指出的,我对“强制刷新”是错误的。一定有一个巧合使我想到了这一点。我最终重写了onBackPressed
并有条件地检查了抽屉是否打开。同样正如@adneal指出的那样,问题与焦点有关。我仍然非常好奇,当以相同的方式但从不同的地方启动活动时,重点可能会有所不同。
最佳答案
因此,我相当确定我了解发生了什么,但是我仍然不确定为什么只有在使用View.OnClicklistener
时它才会发生。也许您的代码还有很多我不知道的地方,或者在这些方面我忽略了一些东西。
但您遇到此问题的原因是由于Android如何处理View.onKey...
事件。 DrawerLayout
覆盖View.onKeyDown
和View.onKeyUp
,每次检查是否按“后退”按钮,以便可以确定是否关闭抽屉。但是对于您而言,此事件并未发生,因为您设置的AdapterView
在调用DrawerLayout
之后将使焦点从AdapterView.setAdpater
移开。
如何修复
只需复制DrawerLayout
源并进行修改,您肯定可以做到;它只是一个类,我建议将每个Foo
Activity
转换为Fragment
,然后使用创建FrameLayout
时通常放置的DrawerLayout
来显示它们。您应该创建一个NavigationDrawerActivity
而不是Fragment
来托管所有内容。
这与DrawerLayout
的布局方式有关,因为它必须使用MeasureSpec.EXACTLY
。换句话说,将NavigationDrawerFragment
放置在Foo
布局的顶部时,它将占用整个空间。如果在View.setFocusableInTouchMode
中设置了ListAdapter
后调用了Foo
,则DrawerLayout
会像应该的那样工作,但是AdapterView
将不再滚动。而且您不能基于DrawerLayout
的打开或关闭位置来切换焦点,因为这两种方式都占据了整个空间,并且总是在true
中返回View.onTouchEvent
。
或者只是覆盖Activity.onBackPressed
,它确实不像您想的那样“笨拙”,但我理解您的意思。
无论如何,我希望这至少是清楚的和/或有用的。花了我一些时间重现您的问题,但是在我做完之后不久,便排除了“从上到下刷新”库。简而言之,我认为这是一个重点问题。证明我是错的。
资源
You can view the source for the DrawerLayout
here to look over how it handles the "back" event
You can see here how AdapterView.checkFocus
works
You can see here in ListView
(GridView
is the same), when AdapterView.checkFocus
is called