サポートライブラリからDrawerLayoutとNavigationViewをホストするアクティビティがあります。ヘッダーレイアウトをナビゲーションビューに設定していて、ナビゲーションヘッダーの高さを「wrap_content」にします。そのため、高さを「wrap_content」に設定すると、ヘッダーレイアウトがステータスバーの後ろに表示されます。
私が望む結果は、ナビゲーションドロワーはステータスバーの後ろに描画する必要がありますが、ナビゲーションヘッダーはステータスバーの高さだけ押し下げられる必要があります。
以下は私が得ているもののスクリーンショットです。ステータスバーの後ろにある「サインイン」ボタンに注意してください。
アクティビティレイアウト
<Android.support.v4.widget.DrawerLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/nav_drawer"
Android:fitsSystemWindows="true">
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v4.view.ViewPager
Android:id="@+id/view_pager"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"></Android.support.v4.view.ViewPager>
<Android.support.design.widget.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<include layout="@layout/include_toolbar"/>
<Android.support.design.widget.TabLayout
app:theme="@style/ThemeOverlay.AppCompat.Dark"
style="@style/MyCustomTabLayout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/tabs"
/>
</Android.support.design.widget.AppBarLayout>
</Android.support.design.widget.CoordinatorLayout>
<Android.support.design.widget.NavigationView
Android:id="@+id/navigation_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
app:headerLayout="@layout/nav_header"
app:menu="@menu/menu_navigation"
Android:fitsSystemWindows="true"
Android:layout_gravity="start"/>
</Android.support.v4.widget.DrawerLayout>
ナビゲーションビューヘッダーレイアウト
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="?attr/colorPrimaryDark"
Android:padding="16dp"
Android:theme="@style/ThemeOverlay.AppCompat.Dark"
Android:orientation="vertical"
Android:fitsSystemWindows="true"
Android:gravity="bottom">
<TextView
Android:visibility="gone"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/text_user_name"
Android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
<TextView
Android:visibility="gone"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/text_email"
Android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
<Button
Android:id="@+id/button_sign_in"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Sign In"/>
</LinearLayout>
StackOverflowで解決策を検索しましたが、見つかりませんでした。だから誰かが光を当ててください。前もって感謝します。
<Android.support.design.widget.NavigationView
Android:id="@+id/navigation_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
app:headerLayout="@layout/nav_header"
app:menu="@menu/menu_navigation"
Android:fitsSystemWindows="false"
Android:layout_gravity="start"/>
Android:fitsSystemWindows = "false"
およびCoordinatorLayout => Android:fitsSystemWindows = "false"
まず、ロリポップの前にステータスバーの後ろに引くことはできないことを覚えておいてください。
Lollipop +の場合、DrawerLayout
にAndroid:fitsSystemWindows="true"
を設定し、NavigationView
にデフォルトのままにする必要があります。
次に、ヘッダーを設定した後のアクティビティまたはフラグメントについて:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat_WATCH) {
navigationView.setOnApplyWindowInsetsListener { v, insets ->
val header = navigationView.getHeaderView(0)
header.setPadding(
header.paddingLeft,
header.paddingTop + insets.systemWindowInsetTop,
header.paddingRight,
header.paddingBottom
)
insets.consumeSystemWindowInsets()
}
}
ウィンドウは、insets
(上、左、下、右の寸法)というオブジェクトを子ビューに渡します。 fitSystemWindows=true
を持つ子ビューは、このインセットに対して何も行わず、子に転送する場合があります。 falseのビューは、値を使用して、それ自体に追加のパディングまたはマージンを追加する場合があります。
NavigationView
のSetfitSystemWindows=false
は、インセットを使用してそれ自体に追加のマージンを適用しているため、機能していません。必要なのは、このマージンを適用するためのヘッダービューLinearLayout
です。ただし、NavigationView
内には2つの中間コンテナビューがあり、インセットをLinearLayout
に転送しないため、これらのコンテナの前にウィンドウのインセットをインターセプトして、マージンまたはパディングを適用する必要があります。ヘッダービュー。
Androidバージョンが何であれ、ウィンドウインセットが固定値であると想定したり、リソースから取得したりしないでください。特定のデバイスにはウィンドウインセットに特定の値があり、一部のデバイスにはより厚い「ノッチ」があります。大きなカメラに合うように、一部のメーカーはそれをAndroid推奨仕様よりも薄くすることを決定します。
ヘッダーレイアウトのルート要素としてLinearLayout
を使用しています。 FrameLayout
、LinearLayout
などは、Android:fitsSystemWindows
属性を無視する基本的なレイアウトです。 ヘッダーレイアウトのルート要素としてCoordinatorLayout
を使用することをお勧めします。CoordinatorLayout
とそのAndroid:fitsSystemWindows
を使用する属性をtrue
に設定すると、内部パディングが自動的に調整され、子要素がステータスバーなどのシステムウィンドウと重複しないようになります。
これらの情報は この記事 、「なぜfitsSystemWindowsが必要なのですか?」イアンレイクによって。
基本的なレイアウト(FrameLayout、LinearLayoutなど)はデフォルトの動作を使用しますが、特定のユースケースに合うようにfitsSystemWindowsへの反応をすでにカスタマイズしているレイアウトがいくつかあります。
.。
CoordinatorLayoutは、ウィンドウインセットの処理方法をオーバーライドすることも利用して、子ビューに設定された動作が、各子自体でdispatchApplyWindowInsets()を呼び出す前に、ビューがウィンドウインセットに反応する方法をインターセプトおよび変更できるようにします。また、fitsSystemWindowsフラグを使用して、ステータスバーの背景をペイントする必要があるかどうかを判断します。
目的を達成するには、このレイアウト構造に従っていることを確認してください。
layout/activity_xxxxx.xml
<Android.support.v4.widget.DrawerLayout
...
Android:fitsSystemWindows="true">
<!-- content -->
...
<!-- drawer -->
<Android.support.design.widget.NavigationView
...
Android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header" />
<Android.support.v4.widget.DrawerLayout>
layout/nav_header.xml
<Android.support.design.widget.CoordinatorLayout
...
Android:fitsSystemWindows="true">
<!-- content -->
...
<Android.support.design.widget.CoordinatorLayout>