Is it possible to make the header sticky in the design support library NavigationView?
<android.support.design.widget.NavigationView
android:id="@+id/nav_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/nav_drawer"
style="@style/navigation_view_drawer"
/>
EDIT:
My attempts so far have led to this
Overriding the NavigationView widget and adding a new method:
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);
}
// Inflates header as a child of NavigationView, on top of the normal menu
public void createHeader(int res) {
LayoutInflater inflater = LayoutInflater.from(getContext());;
View view = inflater.inflate(res, this, false);
addView(view);
}
}
Then adding this to the onCreate of the activity:
CustomNavigationView navigationView = (CustomNavigationView) findViewById(R.id.your_navigation_view);
navigationView.createHeader(R.layout.your_header);
This achieves the desired effect (if a bit hackily) but when menu items are below the header you can still click them, any ideas to fix this?
After lots of experimenting I've got something that works...it's very hacky and I'd love to hear any suggestions you have to improve it!
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 drawer
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);