NavigationViewの区切り線の高さを変える


はじめに

Design Support Libraryの NavigationView を使ってナビゲーションドロワーを実装しており、各グループ毎に表示される区切り線(separator)の高さを調整したいという要望がありました。StyleやAttributeで簡単に実現できるだろうと思っていたのですが、ちょっとハマったのでメモします。

実装

NavigationView の基本的な実装は 公式のドキュメント を参考に進めます。独自のレイアウトを使いたい場合は

activity_main.xml
<DrawerLayout>

    <FrameLayout />

    <NavigationView>

        <include layout="@layout/navigation_view">

    </NavigationView>

</DrawerLayout>

みたいな感じでよしなにやってくれればいいかと。XMLで設定できる内容を 公式ドキュメント で確認します。

XML attributes 内容
itemBackground メニュー項目の背景を指定したリソースに設定する。
itemIconTint メニュー項目のアイコンに適用される色を設定する。
itemTextAppearance メニュー項目のテキストの外見を指定したリソースに設定する。
itemTextColor メニュー項目のテキストの色を設定する。

と、区切り線に関する設定は表記されていませんでした。次にDesign Support Libraryで NavigationView がどのように実装されているのかAndroid Studioを使ってソースコードを追ってみました。

ヘッダー、メニュー項目、サブタイトル、などのレイアウト(ViewHolder)の読み込みは NavigationMenuPresenter で行われていました。区切り線(separator)の部分は

NavigationMenuPresenter.java
private static class SeparatorViewHolder extends NavigationMenuPresenter.ViewHolder {
    public SeparatorViewHolder(LayoutInflater inflater, ViewGroup parent) {
        super(inflater.inflate(layout.design_navigation_item_separator, parent, false));
    }
}

という実装でした。この読み込んでいる design_navigation_item_separator.xml を上書きしてしまえば、ワンチャンいけるのでは

before after

いけました。具体的にはDesign Support Libraryと同名のレイアウトを作成するだけです。

design_navigation_item_separator.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <View
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="?android:attr/listDivider" />

</FrameLayout>

まとめ

本来であれば RecyclerView を配置してゴニョゴニョするのがセオリーだと思うのですが(Stack Overflowでもそのように回答されてました)、 手を抜きたい なるべシンプルな実装を目指した結果こうなりました。なお、あくまでも個人の解決方法であり、これが正しい実装とは限りませんのでご了承ください。また、Design Support Libraryのバージョンを更新した場合、リソースの名称が変更される可能性があるので、都度確認する必要がありそうです。サンプルを GitHub にアップしておきます。

どうでもいい話

ナビゲーションドロワーは『ハンバーガーメニュー』とも呼ばれます。由来としては、メニューの横3本線で構成されたアイコンがハンバーガーに見えるかららしいです。

参考文献