将 NavigationView 与 SlidingPaneLayout 一起使用

Using NavigationView with SlidingPaneLayout

根据 Google 的 Material Design guideline for Navigation drawer, to achieve Standard drawer for tablet or desktop devices, I would use NavigationView with SlidingPaneLayout for tablet devices instead of DrawerLayout for phone devices, which is to achieve Modal drawer

我把一个 NavigationView 作为 SlidingPaneLayout 的第一个子视图。出现问题。

如您所知如果 SlidingPaneLayout 的子视图的组合宽度超过 SlidingPaneLayout 中的可用宽度,它们就会重叠。在这种情况下,子视图会扩展以填充 SlidingPaneLayout 中的可用宽度。用户可以通过将最上面的视图从屏幕边缘向后拖动来将其滑出。

但是我的 NavigationView 的窗格不会滑动。 它只是在最大宽度处出现或消失,没有滑动动画。

我该如何解决这个问题?

<androidx.slidingpanelayout.widget.SlidingPaneLayout
    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"
    tools:context=".MainActivity">

    <!-- The first child view becomes the left pane. When the combined
         desired width (expressed using android:layout_width) would
         not fit on-screen at once, the right pane is permitted to
         overlap the left. -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_view_header"
        app:menu="@menu/navigation_view" />

    <!-- The second child becomes the right (content) pane. In this
         example, android:layout_weight is used to expand this detail pane
         to consume leftover available space when the
         the entire window is wide enough to fit both the left and right pane.-->
    <fragment
        android:id="@+id/navigationHost"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="320dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        app:navGraph="@navigation/main" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

app:elevation="0dp" 添加到 NavigationView。

<com.google.android.material.navigation.NavigationView
    android:id="@+id/navigationView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:elevation="0dp"
    app:headerLayout="@layout/navigation_view_header"
    app:menu="@menu/navigation_view" />

如果您检查布局,您会注意到默认情况下 NavigationView 的高度为 16dp。这导致了问题。可能是SlidingPaneLayout在两个子view的高度相同的情况下处理的(0dp).

所以一个解决方案是用 0dp.

覆盖 NavigationView 的默认高度 (16dp)

另一种解决方案是用 FrameLayout 或某些 ViewGroup 包装 NavigationView。

<FrameLayout
    android:layout_width="280dp"
    android:layout_height="match_parent">
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_view_header"
        app:menu="@menu/navigation_view" />
</FrameLayout>

那么,你应该指定 layout_width with FrameLayout 和 NavigationView 的 layout_widthmatch_parent

尽管 NavigationView 的默认高度为 16dp,但其父 ViewGroup 的高度为 0dp,SlidingPaneLayout 可以正确处理。