Android Design Support Library: Getting Started
The Design Support Library helps you implement shiny, interactive Material Design components and supports phones running extremely old versions of Android! By Zahidur Rahman Faisal.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Android Design Support Library: Getting Started
30 mins
- Getting started
- Managing Design Support Dependencies
- Showcasing Items with RecyclerView
- Highlight with CardView
- RecyclerView in Action
- Listening to Click Events
- Using VectorDrawables for Icons
- Categorize items with BottomNavigationView
- Implementing BottomNavigationView
- Handling Item Selection on BottomNavigationView
- Adding New Items
- Using FloatingActionButton
- Interacting with TextInputLayout
- Using Snackbar for Temporary Messages
- Animating Item Details
- Using CoordinatorLayout and CollapsingToolbarLayout
- Adding Parallax Scrolling Effect
- Where To Go From Here?
Have you been surfing through thousands of Github libraries to add a Facebook-like Sliding Navigation menu in your project? Or searching for a convenient widget that will show tabs with icons at the bottom of your app’s homepage?
Behold – the Android Design Support Library is for you!
The Android Design Support Library helps you implement those shiny, interactive design components with minimal code!
In this tutorial, you’ll create a marketplace app called iSell using the Android Design Support Library. By the end, you will learn how to:
- Use common Material Design components like
BottomNavigationView
andFloatingActionButton
- Get rid of needing different images for the same icon to support different device resolutions with
VectorDrawables
- Bring some wow-factors to your users with
CoordinatorLayout
andCollapsingToolbarLayout
Getting started
To kick things off, start by downloading the materials for this tutorial (you can find a link at the top or bottom of this tutorial). Unzip iSell.zip folder into your desktop.
Now launch Android Studio 3.1.2 or greater and select Open an existing Android Studio project to import the starter project.
Choose iSell-Starter inside the iSell folder and click Open
Build and run by firing keyboard shortcut Shift + F10 (or Control + R if you are using a Mac)
And you will see a screen with the project name. Kudos – you’ve successfully kickstarted the project!
Managing Design Support Dependencies
Adding Design Support Library to your project is a piece of cake, but it requires a few different components. You should always use the latest version of each component, and make sure they’re the same version for all the components.
To manage this efficiently, an external variable is defined in your Project level build.gradle file as following:
ext.supportLibraryVersion = '27.1.1'
You will use this version with all the Design Support Library components later.
Open the build.gradle file from your app module and append the following lines inside the dependencies section:
// 1: Design Support Library
implementation "com.android.support:design:$supportLibraryVersion"
// 2: CardView
implementation "com.android.support:cardview-v7:$supportLibraryVersion"
Let’s take a moment to understand what each of dependencies provides:
-
Design Support Library: Adds all those “exciting” UI components we are talking about. For example:
BottomNavigationView
,FloatingActionButton
. We’ll be adding one of each later in this tutorial. - CardView: Is a View component that shows its content in an elevated card, and highlights it to stand-out from the background. Most commonly used with list items.
Also, you’re are going to use VectorDrawables
for the icons, so add this inside the defaultConfig section:
vectorDrawables.useSupportLibrary = true
Your app module’s build.gradle file finally may look like this:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.raywenderlich.isell"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
androidExtensions {
experimental = true
}
}
dependencies {
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion"
// AppCompat
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
// Design Support Library
implementation "com.android.support:design:$supportLibraryVersion"
// CardView
implementation "com.android.support:cardview-v7:$supportLibraryVersion"
}
Notice that the build.gradle file has uses a plugin:
apply plugin: 'kotlin-android-extensions'
With kotlin-android-extensions
, you can directly access a View
‘s id
without having to initialize it using findViewById()
. Its just sweet syntactic sugar! If you are keen to know more about kotlin-android-extensions
you can find out more here.
Before adding any Kotlin code, configure Android Studio to automatically insert import statements so that you don’t need to worry about imports for every change you make.
Go to Preferences\Editor\General\Auto Import, check Add unambiguous imports on the fly and Optimize imports on the fly checkboxes and click OK.
Again, don’t forget to click Sync Now in the top-right corner of your IDE. You’re now done with all the setup!
Showcasing Items with RecyclerView
First things first, you’ll display a list of items to sell. To show the list, replace the TextView
inside activity_main.xml with a RecyclerView
:
<RelativeLayout 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=".ui.activity.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/itemsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="2"/>
</RelativeLayout>
Here, RecyclerView
will be identified as itemsRecyclerView
and the width and height properties should match its parent layout.
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="2"
You’ll notice that you set the layoutManager
directly in the XML to use a GridLayoutManager
. Setting the app:spanCount
tells the GridLayoutManager
that you want to show 2 items in a row, so you tell the layoutManager
to prepare layout for the grid.
Next, you need to design the layout for the items in the list.
Highlight with CardView
For each item in being sold, you’ll want to show the image, price and title. To make a layout for that, right-click on layout folder, select New, then select Layout resource file and name it layout_list_item.xml.
Now add following code inside layout_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardBackgroundColor="@color/cardview_light_background"
card_view:cardCornerRadius="@dimen/cardview_default_radius"
card_view:cardElevation="@dimen/cardview_default_elevation">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/itemImage"
android:layout_width="match_parent"
android:layout_height="@dimen/item_image_height"
android:scaleType="fitCenter"
tools:src="@drawable/laptop_1"/>
<TextView
android:id="@+id/itemPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/itemImage"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textColor="@color/colorAccent"
tools:text="@string/hint_price"/>
<TextView
android:id="@+id/itemTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/itemPrice"
android:layout_marginBottom="@dimen/default_margin"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:ellipsize="end"
android:maxLines="2"
android:minLines="2"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
tools:text="@string/hint_title"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
It will look like this in the Preview pane:
Here the CardView
and its properties may seem new to you, but other components are quite familiar – you are just adding views to show the image, price and title inside a RelativeLayout
sequentially.
Using CardView
makes your item appear elevated with the use of drop shadows around the element.
card_view:cardBackgroundColor="@color/cardview_light_background"
The above property adds a light-themed background color for the CardView
from Design Support Library.
card_view:cardCornerRadius="@dimen/cardview_default_radius"
This property makes the card’s corners to look rounded. You are using the default radius provided in Design Support Library. You can play with the values for this property, the edges will look more rounded with a larger value.
The most interesting property of CardView
is:
card_view:cardElevation="@dimen/cardview_default_elevation"
This property allows a CardView
to look more or less elevated. This elevation of the view determines the size of the drop shadow. The larger the value you provide, the more elevated it’ll look.
RecyclerView in Action
It’s time to bind some data to the layout. Consider the DataProvider
class inside util package as a storehouse of all your Items
. You need an adapter to show items in the RecyclerView
added earlier. To do so, add a new class inside the adapter package named ItemsAdapter
as follows:
// 1
class ItemsAdapter(private val items: List<Item>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
// 2
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(item: Item) = with(itemView) {
itemTitle.text = item.title
itemImage.setImageResource(item.imageId)
}
}
// 3
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent?.context)
.inflate(R.layout.layout_list_item, parent, false)
return ViewHolder(view)
}
// 4
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).bind(items[position])
}
// 5
override fun getItemCount(): Int {
return items.size
}
}
That’s a lot of code to digest at once! Let’s break it down…
-
ItemsAdapter
is declared as a subclass ofRecyclerView.Adapter
which accepts a list ofItem
. -
ViewHolder
is a subclass ofRecyclerView.ViewHolder
. It inherits the power of being cached into memory and re-used to display anItem
inside theRecyclerView
. Thebind(item: Item)
function inside it does all the binding between theItem
and theView
. -
onCreateViewHolder()
function creates a newViewHolder
when the adapter needs a new one with the view you designed in layout_list_item.xml. -
onBindViewHolder()
glues eachItem
from the list with aViewHolder
to populate it using thebind()
function. -
getItemCount()
function tellsItemsAdapter
the number of items in the list.
Add a function that will set the data in RecyclerView
according to the category you want inside MainActivity.kt:
private fun populateItemList(category: Category) {
val items = when (category) {
Category.LAPTOP -> DataProvider.laptopList
Category.MONITOR -> DataProvider.monitorList
Category.HEADPHONE -> DataProvider.headphoneList
}
if (items.isNotEmpty()) {
itemsRecyclerView.adapter = ItemsAdapter(items)
}
}
This function accepts Category
as input and fetches a list of items from that category through the DataProvider
. Then it creates a new ItemsAdapter
with those items and sets to itemsRecyclerView
.
Call this function with a Category
from onCreate()
function inside MainActivity:
populateItemList(Category.LAPTOP)
Here you are fetching items from the LAPTOP category through the DataProvider
. Feel free to play around with other categories also.
Run the app again. You’ll see the list as follows: