在某些设备上 onPause 后,NavigationDrawer 高度会折叠到工具栏的高度
NavigationDrawer height collapses to that of the Toolbar after onPause on some devices
我有一个相当简单的应用程序,它有一个带有 NavigationDrawer
的自定义 Toolbar
。除了这些项目,我还有一个 GLSurfaceView
填满了整个屏幕。在我的 NavigationDrawer
中,我有一个可以选择的案例列表,然后在 GLSurfaceView
.
中获取和呈现数据
一切正常,除了一件事:当应用程序暂停然后恢复时,NavigationView
的高度收缩为 Toolbar
的高度。 NavigationView
仍然可以在那个小高度滚动,当在那个点选择一个案例时,NavigationView
的高度被刷新并且一切恢复正常。因此,这也会发生在设备旋转时。
请注意,如果 NavigationView
在 rotating/pausing 应用程序时 可见 ,则 不会 发生问题.
但并非所有设备都会出现此问题。这是我测试过的列表:
问题出现在:
- 三星 Galaxy S2 标签:Android6.0.1
- 三星 Galaxy S7 Edge:Android6.0.1
- HTC One A9s:Android6.0
- 三星 Galaxy Note 10.1:Android5.11
问题没有出现在:
- 索尼 Xperia XZ:Android6.0.1
- 华为荣耀7:Android5.0.2
- 华为 Nexus P6:Android7.0
我已经尝试使 onPause
中的所有视图无效,但没有任何帮助,我无法弄清楚我哪里做错了。
其他说明:
compileSdkVersion = 25
targetSdkVersion = 25
- 支持库版本:
25.2.0
- 构建工具版本:
25.0.2
- Gradle 插件版本:
2.3.0
/ Android Studio 2.3
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- This style is set in AndroidManifest.xml -->
<style name="DemoTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- To be able to use a custom Toolbar. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimary">@color/demo_color_main_brand</item>
<item name="colorPrimaryDark">@color/demo_color_extras_darkblue</item>
<item name="colorAccent">@color/demo_color_extras_lightgreen</item>
</style>
<style name="DemoActionBarStyle" parent="@style/Widget.AppCompat.ActionBar">
<item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@color/demo_color_main_brand</item>
<item name="android:minHeight">?attr/actionBarSize</item>
</style>
...
</resources>
activity_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/demo_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Wrap Toolbar in AppBarLayout to add shadow below the Toolbar. -->
<android.support.design.widget.AppBarLayout
android:id="@+id/demo_appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v7.widget.Toolbar
android:id="@+id/demo_toolbar"
style="@style/DemoActionBarStyle" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/demo_appbarlayout" >
<android.support.design.widget.CoordinatorLayout
android:id="@+id/fv_coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.DemoActivity" >
<com.my.company.demo.views.DemoGLSurfaceView
android:id="@+id/demo_glsurfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/demo_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/demo_navigationview_header"
app:menu="@menu/demo_navigationview_menu"
app:itemIconTint="@drawable/demo_colors_navigationview"
app:itemTextColor="@drawable/demo_colors_navigationview" />
</android.support.v4.widget.DrawerLayout>
onCreate
在 DemoActivity:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
// Setup Toolbar.
Toolbar toolbar = (Toolbar) findViewById(R.id.demo_toolbar);
setSupportActionBar(toolbar);
// Setup NavigationView.
NavigationView navigationView = (NavigationView) findViewById(R.id.demo_navigationview);
navigationView.setNavigationItemSelectedListener(this);
// Setup DrawerLayout.
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.demo_drawer_layout);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
// Load demo cases.
mModuleConfiguration = new ModuleConfiguration(getString(R.string.module_config_url), this);
}
轮换前:
旋转后:
这是一个奇怪的错误,也许您应该在 activity 的 onPause
方法中调用 DrawerLayout
的 close
函数,如下所示:
@Override
public void onPause() {
super.onPause();
drawerLayout.closeDrawer(GravityCompat.START);
}
祝你好运。
我发现了一个类似的问题,帮助 med 解决了我的问题 here。它的要点是在 Activity
中实现一个额外的 DrawerLayout.DrawerListener
并执行
@Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
mDrawerLayout.bringChildToFront(drawerView);
mDrawerLayout.requestLayout();
}
确保抽屉绘制在GLSurfaceView
上方。
修复步骤:
- 在
Activity
中实施 DrawerLayout.DrawerListener
。
- 添加
ActionBarDrawerToggle
和 Activity
作为 DrawerLayout
的侦听器。
- 从
DrawerLayout.DrawerListener
接口实现上述 onDrawerSlide()
方法(mDrawerLayout
只是对 DrawerLayout
的本地引用)。
我有一个相当简单的应用程序,它有一个带有 NavigationDrawer
的自定义 Toolbar
。除了这些项目,我还有一个 GLSurfaceView
填满了整个屏幕。在我的 NavigationDrawer
中,我有一个可以选择的案例列表,然后在 GLSurfaceView
.
一切正常,除了一件事:当应用程序暂停然后恢复时,NavigationView
的高度收缩为 Toolbar
的高度。 NavigationView
仍然可以在那个小高度滚动,当在那个点选择一个案例时,NavigationView
的高度被刷新并且一切恢复正常。因此,这也会发生在设备旋转时。
请注意,如果 NavigationView
在 rotating/pausing 应用程序时 可见 ,则 不会 发生问题.
但并非所有设备都会出现此问题。这是我测试过的列表:
问题出现在:
- 三星 Galaxy S2 标签:Android6.0.1
- 三星 Galaxy S7 Edge:Android6.0.1
- HTC One A9s:Android6.0
- 三星 Galaxy Note 10.1:Android5.11
问题没有出现在:
- 索尼 Xperia XZ:Android6.0.1
- 华为荣耀7:Android5.0.2
- 华为 Nexus P6:Android7.0
我已经尝试使 onPause
中的所有视图无效,但没有任何帮助,我无法弄清楚我哪里做错了。
其他说明:
compileSdkVersion = 25
targetSdkVersion = 25
- 支持库版本:
25.2.0
- 构建工具版本:
25.0.2
- Gradle 插件版本:
2.3.0
/ Android Studio 2.3
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- This style is set in AndroidManifest.xml -->
<style name="DemoTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- To be able to use a custom Toolbar. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimary">@color/demo_color_main_brand</item>
<item name="colorPrimaryDark">@color/demo_color_extras_darkblue</item>
<item name="colorAccent">@color/demo_color_extras_lightgreen</item>
</style>
<style name="DemoActionBarStyle" parent="@style/Widget.AppCompat.ActionBar">
<item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@color/demo_color_main_brand</item>
<item name="android:minHeight">?attr/actionBarSize</item>
</style>
...
</resources>
activity_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/demo_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Wrap Toolbar in AppBarLayout to add shadow below the Toolbar. -->
<android.support.design.widget.AppBarLayout
android:id="@+id/demo_appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v7.widget.Toolbar
android:id="@+id/demo_toolbar"
style="@style/DemoActionBarStyle" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/demo_appbarlayout" >
<android.support.design.widget.CoordinatorLayout
android:id="@+id/fv_coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.DemoActivity" >
<com.my.company.demo.views.DemoGLSurfaceView
android:id="@+id/demo_glsurfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/demo_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/demo_navigationview_header"
app:menu="@menu/demo_navigationview_menu"
app:itemIconTint="@drawable/demo_colors_navigationview"
app:itemTextColor="@drawable/demo_colors_navigationview" />
</android.support.v4.widget.DrawerLayout>
onCreate
在 DemoActivity:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
// Setup Toolbar.
Toolbar toolbar = (Toolbar) findViewById(R.id.demo_toolbar);
setSupportActionBar(toolbar);
// Setup NavigationView.
NavigationView navigationView = (NavigationView) findViewById(R.id.demo_navigationview);
navigationView.setNavigationItemSelectedListener(this);
// Setup DrawerLayout.
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.demo_drawer_layout);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
// Load demo cases.
mModuleConfiguration = new ModuleConfiguration(getString(R.string.module_config_url), this);
}
轮换前:
旋转后:
这是一个奇怪的错误,也许您应该在 activity 的 onPause
方法中调用 DrawerLayout
的 close
函数,如下所示:
@Override
public void onPause() {
super.onPause();
drawerLayout.closeDrawer(GravityCompat.START);
}
祝你好运。
我发现了一个类似的问题,帮助 med 解决了我的问题 here。它的要点是在 Activity
中实现一个额外的 DrawerLayout.DrawerListener
并执行
@Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
mDrawerLayout.bringChildToFront(drawerView);
mDrawerLayout.requestLayout();
}
确保抽屉绘制在GLSurfaceView
上方。
修复步骤:
- 在
Activity
中实施DrawerLayout.DrawerListener
。 - 添加
ActionBarDrawerToggle
和Activity
作为DrawerLayout
的侦听器。 - 从
DrawerLayout.DrawerListener
接口实现上述onDrawerSlide()
方法(mDrawerLayout
只是对DrawerLayout
的本地引用)。