I want to scroll only the menu items of the navigation view but it also scroll the header with it. Please any body tell me how to achieve this... Here is my code:
I also faced thhis problem and resolved it . here is the solution
1) Create default navigation drawer in your project
2) remove header tag from NavigationView in activity_main.xml and add header inside NavigationView
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main" >>>>>> X
app:menu="@menu/activity_main_drawer" >
<include
layout="@layout/nav_header_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.NavigationView>
3) add required blank items in top of menu->activity_main_drawer.xml (depand on your header height
I solved this problem by doing
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
//where your main content goes.
<include
layout="@layout/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="@layout/nav_drawer_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
Inside drawer layout, included add this layout,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//your header layout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:gravity="bottom"
android:orientation="vertical">
<include layout="@layout/layout_drawer_header"></include>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/drawerRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_weight="1"
android:background="#ffffff" />
//your footer layout
<include layout="@layout/nav_footer_item" />
Then just populate the recyclerview.
I couldn't get Lornes answer to work, but I had some success by using a custom NavigationView. It's very hacky but achieves the desired effect.
The methods added to the custom NavigationView allow you to add a header on top of the NavigationView then size the menu so it fits beneath the header.
Comments for improvements are welcome
The overrided NavigationView
public class CustomNavigationView extends NavigationView {
public CustomNavigationView(Context context) {
super(context);
}
public CustomNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomNavigationView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// Consumes touch in the NavigationView so it doesn't propagate to views below
public boolean onTouchEvent (MotionEvent me) {
return true;
}
// Inflates header as a child of NavigationView
public void createHeader(int res) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(res, this, false);
// Consumes touch in the header so it doesn't propagate to menu items below
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event){
return true;
}
});
addView(view);
}
// Positions and sizes the menu view
public void sizeMenu(View view) {
// Height of header
int header_height = (int) getResources().getDimension(R.dimen.nav_header_height);
// Gets required display metrics
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float screen_height = displayMetrics.heightPixels;
// Height of menu
int menu_height = (int) (screen_height - header_height);
// Layout params for menu
LayoutParams params = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM;
params.height = menu_height;
view.setLayoutParams(params);
}
}
And this in the onCreate of main activity
// Inflates the nav header
CustomNavigationView navigationView = (CustomNavigationView) findViewById(R.id.your_nav_view);
navigationView.createHeader(R.layout.your_nav_header);
// sizes nav drawer menu so it appears under header
ViewGroup parent = (ViewGroup) navigationView;
View view = parent.getChildAt(0);
navigationView.sizeMenu(view);
I know its Too old Question but its too easy!
<android.support.design.widget.NavigationView
android:id="@+id/navigationview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header_drawer"
app:menu="@menu/item_drawer">
</android.support.design.widget.NavigationView>
Add the following code to the NavigationView (<include layout="@layout/header_drawer"/>
)
<android.support.design.widget.NavigationView
android:id="@+id/navigationview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header_drawer"
app:menu="@menu/item_drawer">
<include layout="@layout/header_drawer"/>
</android.support.design.widget.NavigationView>
You should be able to place your header outside of the NavigationView
, like so:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<!-- nav drawer -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<!-- header -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="190dp"
android:background="@drawable/background_material"
android:orientation="vertical"
>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/profile_image"
android:layout_width="76dp"
android:layout_height="76dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp"
android:src="@mipmap/ic_launcher"
app:border_color="#FF000000" />
</RelativeLayout>
<!-- menu -->
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="0px"
android:layout_weight="1"
android:layout_gravity="start"
app:menu="@menu/drawer" />
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
Note: I've added a FrameLayout
to encapsulate everything in a single view for the DrawerLayout
, adjusted the NavigationView's height to automatically use the available space below your header, and have removed the headerLayout
attribute.
I know its Too old Question but its too easy.
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>
change it to below code (include header inside)
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer" />
<include layout="@layout/header"/>
</android.support.v4.widget.DrawerLayout>
work like charm happy coding :)