Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change drawer gap between header group and first item menu

I need change the space between header group and first item menu, here's an example:

enter image description here

I have seen a lot of examples and posts but only be can change the space for all items, and I just need to change only for header group.

Any idea?

like image 721
Gaston Flores Avatar asked May 31 '17 20:05

Gaston Flores


3 Answers

There are 4 types of items in the RecyclerView that NavigationView creates:


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case VIEW_TYPE_NORMAL:
                return new NormalViewHolder(mLayoutInflater, parent, mOnClickListener);
            case VIEW_TYPE_SUBHEADER:
                return new SubheaderViewHolder(mLayoutInflater, parent);
            case VIEW_TYPE_SEPARATOR:
                return new SeparatorViewHolder(mLayoutInflater, parent);
            case VIEW_TYPE_HEADER:
                return new HeaderViewHolder(mHeaderLayout);
        }
        return null;
    }

The one you are interested in is SubheaderViewHolder. R.layout.design_navigation_item_subheader is the layout, that would be inflated for that ViewHolder.

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="?attr/listPreferredItemHeightSmall"
          android:gravity="center_vertical|start"
          android:maxLines="1"
          android:paddingLeft="?attr/listPreferredItemPaddingLeft"
          android:paddingRight="?attr/listPreferredItemPaddingRight"
          android:textAppearance="@style/TextAppearance.AppCompat.Body2"
          android:textColor="?android:textColorSecondary"/>

As you can see, the height is taken from the theme's listPreferredItemHeightSmall attribute. But you cannot achieve your requirement just by changing the value of listPreferredItemHeightSmall, because NormalViewHolder's item is also dependent on that value, thus changing it would affect all other items too.

The sneaky and non-reliable way of achieving that would be to acquire this RecyclerView on runtime with getIdentifier() API. The id of the custom RecyclerView is design_navigation_view. Once acquired, you can manually get the actual View from RecyclerView (knowing which child of RecyclerView is the one you need). Then you can manually change the height of that View. But that is not reliable, because:

  • It won't be easy to handle that for many such items, because you cannot know how many of them are actually displayed (well, you can, but is it worth it?)

  • You have to listen for scroll events and detect when any new SubheaderViewHolder is getting displayed - then apply your custom height.

I cannot find enough seams to affect the height of that item. Your best option would be to provide your custom layout as the content of NavigationView.

like image 157
azizbekian Avatar answered Oct 21 '22 01:10

azizbekian


Thanks to azizbekian, his answer gived to me a great idea (maybe not the best but in my case more simple and fast to implement). Basically, I add a layout with the same name (this will override it). After that I change all that I need, so the result is this:

enter image description here

enter image description here

like image 31
Gaston Flores Avatar answered Oct 21 '22 01:10

Gaston Flores


In my experience, the best way to handle nav drawer is to have it display a full Fragment. This allows you to have a total control of its layout and behavior.

like image 2
Vasiliy Avatar answered Oct 21 '22 01:10

Vasiliy