1. Setup a new project
- Open Android Studio.
- Select File -> New -> New Project…
- In the Create New Project dialog select Empty Activity from the Phone and Tablet tab and click Next.
- Make the following selections and click Finish:
- Name: Pick a name
- Package name: Pick a package name
- Save location: Pick a folder
- Language: Kotlin
- Minimum API level: API 19: Android 4.4 (KitKat)
- Leave This project will support instant apps unchecked.
- Check Use androidx.* artifacts.
2. Add the Material Components dependency
- Open the build.gradle file for the module.
- Add the following line to the dependencies block:
implementation 'com.google.android.material:material:1.0.0'
- Click Sync Now.
3. Set up the app bar
- Open the strings.xml file.
- Add the following string:
<string name="main_content_tag">Main Content</string>
- Open the activity_main.xml file.
- Replace its contents with the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/main_content_tag"/>
</FrameLayout>
</LinearLayout>
- Open the styles.xml file.
- Add the following style:
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
- Open the AndroidManifest.xml file.
- Locate the line that declares the MainActivity.
- Add the following android:theme attribute:
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.NoActionBar">
- Open the MainActivity.kt file.
- Add the following function:
private fun setupAppBar()
{
setSupportActionBar(toolbar)
}
When prompted, let Android Studio add the following import statement:
import kotlinx.android.synthetic.main.activity_main.*
- Call the function from the onCreate function:
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupAppBar()
}
4. Create the menu
- Open the strings.xml file.
- Add the following strings:
<string name="menu_item_1">Item 1</string> <string name="menu_item_2">Item 2</string> <string name="menu_item_3">Item 3</string> <string name="menu_item_4">Item 4</string> <string name="menu_item_5">Item 5</string> <string name="menu_item_6">Item 6</string> <string name="menu_item_7">Item 7</string> <string name="menu_group_3_title">Third Group</string>
- Right click the res folder and select New -> Android Resource File.
- In the dialog that appears make the following changes and click OK:
- File name: menu_drawer.
- Resource type: Menu.
- Replace the contents of the file with the following:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/menu_group_1">
<item
android:id="@+id/menu_item_1"
android:icon="@android:drawable/ic_dialog_email"
android:title="@string/menu_item_1"/>
<item
android:id="@+id/menu_item_2"
android:icon="@android:drawable/ic_dialog_alert"
android:title="@string/menu_item_2"/>
<item
android:id="@+id/menu_item_3"
android:icon="@android:drawable/ic_dialog_dialer"
android:title="@string/menu_item_3"/>
</group>
<group android:id="@+id/menu_group_2">
<item
android:id="@+id/menu_item_4"
android:title="@string/menu_item_4"/>
<item
android:id="@+id/menu_item_5"
android:title="@string/menu_item_5"/>
</group>
<item android:title="@string/menu_group_3_title">
<menu>
<item
android:id="@+id/menu_item_6"
android:icon="@android:drawable/ic_dialog_map"
android:title="@string/menu_item_6"/>
<item
android:id="@+id/menu_item_7"
android:icon="@android:drawable/ic_dialog_info"
android:title="@string/menu_item_7"/>
</menu>
</item>
</menu>
5. Set up the DrawerLayout
- Open the strings.xml file.
- Add the following strings:
<string name="open_drawer">Open drawer</string> <string name="close_drawer">Close drawer</string>
- Open the activity_main.xml file.
- Wrap the LinearLayout element into a DrawerLayout:
<?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"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/main_content_tag"/>
</FrameLayout>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
- Add the NavigationView element inside the DrawerLayout:
<?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"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/main_content_tag"/>
</FrameLayout>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu_drawer"/>
</androidx.drawerlayout.widget.DrawerLayout>
Note
The com.google.android.material.navigation.NavigationView element must be the 2nd child of the androidx.drawerlayout.widget.DrawerLayout element.
Note
You can pick a specific width for the drawer by changing the android:layout_width attribute of the com.google.android.material.navigation.NavigationView element.
6. Set up the toogle button
- Open MainActivity.kt file.
- Add the following class property:
private lateinit var toggle: ActionBarDrawerToggle
When prompted, let Android Studio add the following import statement:
import androidx.appcompat.app.ActionBarDrawerToggle
- Make the following changes to the setupAppBar function:
private fun setupAppBar()
{
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toggle = ActionBarDrawerToggle(this, drawerLayout, R.string.open_drawer, R.string.close_drawer)
drawerLayout.addDrawerListener(toggle)
}
Note
Because we set a Toolbar as the activity’s ActionBar, we have to use the ActionBarDrawerToggle(Activity, DrawerLayout, int, int) constructor otherwise onOptionsItemSelected won’t be called.
- Add the following overrides:
override fun onPostCreate(savedInstanceState: Bundle?)
{
super.onPostCreate(savedInstanceState)
toggle.syncState()
}
override fun onConfigurationChanged(newConfig: Configuration?)
{
super.onConfigurationChanged(newConfig)
toggle.onConfigurationChanged(newConfig)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean
{
if (toggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
When prompted, let Android Studio add the following import statement:
import android.content.res.Configuration import android.view.MenuItem
Note
onConfigurationChanged won’t be called. That’s because the configuration changes are handled automatically by the system by recreating the activity.
If you need, you can manually manage any configuration change by adding the android:configChanges attribute to the activity element in the AndroidManifest.xml file.
For example, by adding android:configChanges=”screenSize|orientation” you prevent the system from recreating the activity every time the device gets rotated and the onConfigurationChanged gets called to give you the chance to manually manage the configuration change.
7. Respond to user selections
- Add the following function:
private fun setupControls()
{
navigationView.setNavigationItemSelectedListener {menuItem: MenuItem -> Boolean
when (menuItem.itemId) {
R.id.menu_item_1 -> Toast.makeText(this, "Item 1", Toast.LENGTH_SHORT).show()
R.id.menu_item_2 -> Toast.makeText(this, "Item 2", Toast.LENGTH_SHORT).show()
R.id.menu_item_3 -> Toast.makeText(this, "Item 3", Toast.LENGTH_SHORT).show()
R.id.menu_item_4 -> Toast.makeText(this, "Item 4", Toast.LENGTH_SHORT).show()
R.id.menu_item_5 -> Toast.makeText(this, "Item 5", Toast.LENGTH_SHORT).show()
R.id.menu_item_6 -> Toast.makeText(this, "Item 6", Toast.LENGTH_SHORT).show()
R.id.menu_item_7 -> Toast.makeText(this, "Item 7", Toast.LENGTH_SHORT).show()
}
drawerLayout.closeDrawers()
return@setNavigationItemSelectedListener true
}
}
- Then call it from onCreate:
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupAppBar()
setupControls()
}
8. Final touches (optional)
8.1. Add a header
- Open the strings.xml file.
- Add the following string:
<string name="developer_name">Anastasios Chondrogiannis</string>
- Right click the res folder and select New -> Android Resource File.
- In the dialog that appears make the following changes and click OK:
- File name: drawer_menu_header.
- Resource type: Layout.
- Replace the contents of the file with the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="vertical"
android:gravity="bottom"
android:padding="12dp"
android:background="@color/colorAccent"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher_round"
tools:ignore="ContentDescription"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:text="@string/developer_name"/>
</LinearLayout>
- Open the activity_main.xml file.
- Locate the com.google.android.material.navigation.NavigationView element.
- Add the following app:headerLayout attribute:
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_menu_header"
app:menu="@menu/menu_drawer"/>
8.2. Style the app bar
- Open the activity_main.xml file.
- Locate the com.google.android.material.appbar.AppBarLayout element.
- Add the following android:theme attribute:
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- Locate the androidx.appcompat.widget.Toolbar element.
- Add the following app:popupTheme attribute:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
9. Conclusion
You can download the full project from my GitHub.
Leave a Reply