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