Add a split line to the NavigationView of DrawerLayout. The original implementation of the left navigation bar in the project was

In the way of system Menu to achieve, the requirement to add a dividing line to the navigation, and custom color and height, view the document,

Although you can add the dividing line by adding id to the menu group, the code is as follows:

<? The XML version = "1.0" encoding = "utf-8"? > <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/group1" android:checkableBehavior="single"> <item android:id="@+id/nav_camera" android:icon="@drawable/ic_menu_camera" android:title="Import" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="Gallery" /> </group> <group android:id="@+id/group2" android:checkableBehavior="single"> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="Slideshow" /> <item android:id="@+id/nav_manage" android:icon="@drawable/ic_menu_manage" android:title="Tools" /> </group> <group android:id="@+id/group3"> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="Share"  /> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="Send" /> </group> </menu>Copy the code

As shown in the figure:

\

But design does not like this line ah, very thick ah, the color is not beautiful ah! All right! But it’s not in NavigationView

Have found can customize the properties! Then look at the source code of NavigationView and find that the layout of the left column is passed

NavigationMenuPresenter: NavigationMenuPresenter: NavigationMenuPresenter: NavigationMenuPresenter

Design_navigation_item_separater.xml This layout:

<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="1dp"
          android:background="?android:attr/listDivider"/>

</FrameLayout>
Copy the code

The color can be configured by using the listDivider attribute in the theme, but the height is fixed at 1dp and the View has no ID

I didn’t think about this height. How do I change it? Take a look at the implementation of NavigationMenuPresenter, the entire layout on the left side

Is through RecyclerView to achieve, through different View TYPE TYPE to load different layout! So is it

Can start from RecyclerView addOnChildAttachStateChangeListener method? Real knowledge comes from practice! We can go first

RecyclerView obtained by over-reflection:

Field fieldByPressenter = navigationView.getClass().getDeclaredField("mPresenter");
            fieldByPressenter.setAccessible(true);
            NavigationMenuPresenter menuPresenter = (NavigationMenuPresenter) fieldByPressenter.get(navigationView);
            Field fieldByMenuView = menuPresenter.getClass().getDeclaredField("mMenuView");
            fieldByMenuView.setAccessible(true);
            final NavigationMenuView mMenuView = (NavigationMenuView) fieldByMenuView.get(menuPresenter);
Copy the code

MMenuView is RecyclerView, the other is for its registered addOnChildAttachStateChangeListener listening, each

Load a view and get its ViewHolder. Check whether the ViewHolder is SeparatorViewHolder

An instance of ViewHolder to determine the splitter View, and then do as you please! The complete code is as follows:

public static void setNavigationMenuLineStyle(NavigationView navigationView, @ColorInt final int color, final int height) { try { Field fieldByPressenter = navigationView.getClass().getDeclaredField("mPresenter"); fieldByPressenter.setAccessible(true); NavigationMenuPresenter menuPresenter = (NavigationMenuPresenter) fieldByPressenter.get(navigationView); Field fieldByMenuView = menuPresenter.getClass().getDeclaredField("mMenuView"); fieldByMenuView.setAccessible(true); final NavigationMenuView mMenuView = (NavigationMenuView) fieldByMenuView.get(menuPresenter); mMenuView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(View view) { RecyclerView.ViewHolder viewHolder = mMenuView.getChildViewHolder(view); if (viewHolder ! = null && "SeparatorViewHolder".equals(viewHolder.getClass().getSimpleName()) && viewHolder.itemView ! = null) { if (viewHolder.itemView instanceof FrameLayout) { FrameLayout frameLayout = (FrameLayout) viewHolder.itemView;  View line = frameLayout.getChildAt(0); line.setBackgroundColor(color); line.getLayoutParams().height = height; line.setLayoutParams(line.getLayoutParams()); } } } @Override public void onChildViewDetachedFromWindow(View view) { } }); } catch (Throwable e) { e.printStackTrace(); }}Copy the code

The renderings are as follows:

\

Here’s a more intuitive picture: \

\