Material Design
for Android Developers

Ahmad El-Melegy
Android Developer
About Me
CAT Member since 2013.
Ex-CAT Coordinator.
Ex-CATaZine Editor in Chief.
CSED student - 4th year.
Android Developer.
Back-end Developer.
Github https://github.com/AhmadElMelegy
Linkedin https://eg.linkedin.com/in/ahmadmelegy

Why Should I care ?


Who don't want ?!

Be Lazy !

Why Material ?
We need to stop designing for mobile, We need to stop designing for desktop. And definitely do not start designing just for wearables or just for TV or just for autos. Mobile is over.
We need to start designing for people.
Matias Duarte
Why Material ?

Why Material ?

It's EVERYWHERE !!



Is it difficult ?

Material Design Support Library

One line does the Magic !
compile 'com.android.support:design:23.0.1'
UI Components in Material Design Support Library
- Floating Action Button knows as FAB
- Snack Bar
- Coordinator Layout
- Toolbar
- Floating Labels for editing text
- Material Tabs
- Navigation Drawer view
- Motions and scrolling effect (Appbar and Toolbar)
Before we start !

But I have nothing to do with colours

Don't Panic !


Material Palette
https://www.materialpalette.com/
let's define our colours
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>Use them
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
Floating Action Button

Floating Action Button
<FrameLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
app:fabSize="normal"/>
</FrameLayout>
Add Some Action !
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "Add your action", Toast.LENGTH_SHORT).show();
}
});
Snack bar

Snack bar
Snackbar.make(view, "Add your action!", Snackbar.LENGTH_SHORT)
.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
})
.show();


Coordinator Layout
Coordinator Layout
<android.support.design.widget.CoordinatorLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.FloatingActionButton
....
/>
</android.support.design.widget.CoordinatorLayout>

ActionBar ⟶ ToolBar
In the past

Nowadays

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style><android.support.design.widget.CoordinatorLayout
...>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>Styles
Layout
Add Toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);Add Toolbar in Activity/Fragment

Let's Add some content
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1" />
</LinearLayout>
Fix it
<LinearLayout
...
app:layout_behavior="@string/appbar_scrolling_view_behavior">
...
</LinearLayout>
TabLayout

<android.support.design.widget.CoordinatorLayout
...>
<android.support.design.widget.AppBarLayout
...>
<android.support.v7.widget.Toolbar
.../>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
Layout
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
Activity

TabLayout Attributes
app:tabMode="fixed"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabGravity="center"
app:tabMode="fixed"
app:tabMode="scrollable"
Let's play with AppBarLayout
Add more content
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+1" />
...
</LinearLayout>
</ScrollView>Let's play with AppBarLayout
Then add a Scroll Flags to Toolbar like this
<android.support.v7.widget.Toolbar
...
app:layout_scrollFlags="scroll|enterAlways" />
Replace ScrollView with NestedScrollView
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+1" />
...
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
It WORKS !!
Scroll Flags
-
scroll
-
enterAlwaysCollapsed
-
enterAlways
- exitUntilCollapsed
CollapsingToolbarLayout

- Wrap Toolbar with CollapsingToolbarLayout but still be under AppBarLayout
- Remove layout_scrollFlags from Toolbar
- Declare layout_scrollFlags for CollapsingToolbarLayout and change it to scroll|exitUntilCollapsed
- Change AppBarLayout's layout height to the size of expanded state. In this example, I use 256dp
Steps
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>


The Result
Modify the transition if you want
- app:expandedTitleMargin
- app:expandedTitleMarginBottom
- app:expandedTitleMarginEnd
- app:expandedTitleMarginStart
Add background image to App Bar

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/header" />
<android.support.v7.widget.Toolbar
...Just Add an Image View !

Remove background attribute from toolbar.

parallax


<ImageView
...
app:layout_collapseMode="parallax" />Want the background colour back ?!

<ImageView
...
app:contentScrim="?attr/colorPrimary"/>Navigation Drawer

header view layout
res/layout/nav_header.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
...
android:background="#2B3E51"
android:scaleType="centerCrop" />
<ImageView
...
android:layout_gravity="bottom"
android:layout_marginBottom="36dp"
android:src="@drawable/cat" />
<TextView
...
android:layout_gravity="bottom"
android:layout_margin="16dp"
android:text="TwentyCAT"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</FrameLayout>Add navigation menu
res/menu/navigation_drawer_items.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="all">
<item
android:id="@+id/navItem1"
android:icon="@android:drawable/ic_menu_mylocation"
android:title="Home"/>
<item
android:id="@+id/navItem2"
android:icon="@android:drawable/ic_menu_mylocation"
android:title="About"/>
<item
android:id="@+id/navItem3"
android:icon="@android:drawable/ic_menu_mylocation"
android:title="Contact"/>
</group>
</menu>Add navigation view
res/layout/activity_main.xml
<android.support.v4.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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
...
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="@menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
NavigationView nav = (NavigationView) findViewById(R.id.navigation)
nav.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.navItem1:
break;
case R.id.navItem2:
break;
case R.id.navItem3:
break;
}
return false;
}
});handling navigation menu items click event
TextInputLayout

TextInputLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>

Enough for this library

Card View

Add Card View Dependency
compile 'com.android.support:cardview-v7:21.0.+'<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
card_view:contentPadding="16dp"
card_view:cardElevation="2dp"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="fill_parent"
android:layout_height="150dp"
android:src="@drawable/cat"
android:scaleType="fitXY"/>
<TextView
style="@style/Base.TextAppearance.AppCompat.Body1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="CAT Reloaded" />
</LinearLayout>
</android.support.v7.widget.CardView>

Source Code
https://github.com/AhmadElMelegy/material-design-20CAT

Questions ?

https://www.facebook.com/groups/catreloaded.team/
Thanks :)
Material Design for Android Development
By Ahmad El-Melegy
Material Design for Android Development
This deck was presented in 20 CAT event.
- 1,192