In order to use a custom layout for the NavigationDrawer
, you can wrap your custom layout within the NavigationView
, so that your layout structure will look like the below:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- MainActivity Layout -->
<include
layout="@layout/activity_main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- NavigationView -->
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
<!-- Custom NavigationView Layout-->
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
With that in place, you can freely customize your NavigationView
layout as you want, like putting ConstraintLayout
or any layout as you like. And you can also add buttons' listeners like you can do with a normal layout.
Here is a demo that you can start from, the credits of the VerticalButton
back to this tutorial
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ADADAD"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Main Layout -->
<include
layout="@layout/activity_main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- NavigationView Layout-->
<com.google.android.material.navigation.NavigationView
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#666666">
<!-- Header Layout -->
<include
android:id="@+id/include"
layout="@layout/nav_header_main" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#ffff00"
android:onClick="onNavigationButtonClick"
android:text="Button1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include" />
<com.example.android.customnavigationdrawerconstraintlayout.VerticalButton
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="24dp"
android:background="#ffff00"
android:onClick="onNavigationButtonClick"
android:text="Button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1" />
<com.example.android.customnavigationdrawerconstraintlayout.VerticalButton
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:background="#ffff00"
android:onClick="onNavigationButtonClick"
android:text="button3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="64dp"
android:layout_marginLeft="64dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="64dp"
android:layout_marginRight="64dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2"
android:src="@drawable/ic_android" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
activity_main_content.xml (MainActivity layout)
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:id="@+id/tv_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="@color/colorAccent"
android:gravity="bottom"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:paddingTop="8dp"
app:srcCompat="@drawable/ic_launcher_foreground" />
</LinearLayout>
VerticalButton
public class VerticalButton extends Button {
final boolean topDown;
public VerticalButton(Context context, AttributeSet attrs) {
super(context, attrs);
final int gravity = getGravity();
if (Gravity.isVertical(gravity) && (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
setGravity((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
topDown = true;
} else
topDown = false;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint textPaint = getPaint();
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
if (topDown) {
canvas.translate(getWidth(), 0);
canvas.rotate(90);
} else {
canvas.translate(0, getHeight());
canvas.rotate(-90);
}
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
getLayout().draw(canvas);
canvas.restore();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DrawerLayout mDrawerLayout;
NavigationView navView;
Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerLayout = findViewById(R.id.drawer);
navView = findViewById(R.id.navView);
toolbar = findViewById(R.id.toolbar_main);
setupDrawer();
}
private void setupDrawer() {
// Show the burger button on the ActionBar
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this,
mDrawerLayout, toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
mDrawerLayout.addDrawerListener(toggle);
toggle.syncState();
}
public void onNavigationButtonClick(View view) {
TextView tvMain = findViewById(R.id.tv_main);
tvMain.setText(((Button) view).getText().toString());
mDrawerLayout.closeDrawer(navView);
switch (view.getId()) {
case R.id.button1:
// Do something with button 1
break;
case R.id.button2:
// Do something with button 2
break;
case R.id.button3:
// Do something with button 3
break;
}
}
}
strings.xml
<resources>
<string name="app_name">Custom NavigationView</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
</resources>
Material design dependency
implementation 'com.google.android.material:material:1.0.0'
Preview
