Create Your First Android App – Part 1

Today, I am beginning a three part Android tutorial series where I will provide step by step guide on how to create your first Android app. Are you ready to build your first Android app? Great choice! – let’s get started.

User Story

Most software products begins with a user story, it could be a request from your boss or from your client. For this tutorial we will pretend that a friend of yours came to you and said

I need an Android app that will help me record the attendance for my up coming event

That is the user story. How will you proceed to build and publish an app like this for your friend. Well, I will share with you how I will approach this in 3 blog post.

Post 1
Covers project creation and Material Design Navigation Drawer

Post 2
Covers User Interface, adding/managing of Attendants and Events

Post 3
Covers adding business logic, functionalities and Data Persistence

Domain Objects to Android App Screens

Now take a look again at the “User Story”, how many nouns do you see stand out in that sentence? I see Attendance and Event. Another implied noun is the Attendants whose attendance need to be recorded. So that leaves us with the following nouns or the technically correct name domain objects.

  1. Event List
  2. Attendance List
  3. Create Attendant

This means that we should have a screen in our app for Events, Attendance and Attendants. We can now translate these into Android screens as follows

  1. Main Activity

1. Create Attendant Fragment
2. Attendance List Fragment
3. Create Event
4. Events List Fragment

Having identified the screens we need for our app, let us go ahead and create a new project using Android Studio

Create New Android Studio Project

Step 1: Create new Android Studio project – select the blank template, should be the first option. Set your Activity to inherit from AppCompatActivity instead of ActionBarActivity

Step 2: Add Fragments – at the root of the project, add a “fragments” package and inside this fragments package add the following blank Fragments (dis-select “Include fragment factory method” and “include interface callbacks”)

  1. AttendanceListFragment.java
  2. EventsListFragment.java
  3. AddAttendantFragment.java
  4. AddEventFragment.java

Step 3: Add Source Control – click on tools -> VCS -> Enable Git Integration, after that you need to add and commit what you have worked on so far and then try to commit as often as you can. If you are not familiar with how to use Git in Android Studio, then checkout this post by Mark Winterbottom.

Step 4: Choose Material Design Color – Bright and bold colors are one of the hallmarks of material design so we need to add material design colors from MaterialPallette.com. We need to get colors for our custom Toolbar and the header image background color therefore, head over to the above link and play with the available color combinations, pick anyone you like, do not over think it, it can always be changed. Download the xml color to your computer and go to the next step.

Step 5: Add Color Resource – under res/value create color.xml file and add the color resources that you downloaded from the above step and your color.xml will look like this:

<?xml version="1.0" encoding="utf-8"?>
 <resources>
 <!--Get colors from: http://www.materialpalette.com/-->
 <color name="primary">#3F51B5</color>
 <color name="primary_dark">#303F9F</color>
 <color name="primary_light">#C5CAE9</color>
 <color name="accent">#FF5252</color>
 <color name="primary_text">#212121</color>
 <color name="secondary_text">#727272</color>
 <color name="icons">#FFFFFF</color>
 <color name="divider">#B6B6B6</color>
</resources>

Add Material Design ToolBar

We are going to add material design toolbar using the material design color that you choose above and below are the steps to add toolbar:

Step 1: Remove old ActionBar – update your styles.xml in res/value to remove the old ActionBar, it is no longer needed as we are going to replace it with Toolbar.

<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/primary</item>
<item name="android:windowActionBar">false</item>
</style>
</resources>

Step 2: Add ToolBar layout – under res/layout create a layout resource file called toolbar.xml and add the following content within it:

<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
    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="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

Step 3: Add ToolBar layout to MainActitivity Layout – we can now include our new toolbar.xml in our MainActivity layout, and if we add more activities we can simply reuse the same toolbar layout file. Your main_activity.xml should look like this:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/DrawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:elevation="7dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true" />
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/RecyclerView"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="#ffffff"
        android:scrollbars="vertical"></android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>

Step 4: Add ToolBar to MainActivity – in the MainActitivity Java code, first add a private toolbar property and then bind that toolbar property to the toolbar layout file that you created. Then set the toolbar property that you created to be the ActionBar of the MainActivity. The top of your MainActivity.java should look like this:

public class MainActivity extends AppCompatActivity {
    private Toolbar mToolbar;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

End of Adding ToolBar – You should now be able to run your app and it should have a ToolBar similar to this
Material Design Navigation Drawer with Header View

And here comes the most intriguing kid on the block; navigation drawer has always been a challenging concept to implement and material design does not make it any easier with RecylcerView, Layout Manager and RecyclerView adapter. This is what we will accomplish in this section of the tutorial.


Material Design Navigation Drawer

Please follow these 15 steps below to setup Navigation drawer and let me know if you need any clarification.

Step 1: Models Folder – At the root of your project add a package named “models”

Step 2: Add DrawerItem – Add a Java class file called DrawerItems.java to the Models package and here are the contents of that file, this is a simple class that defines each row in our navigation drawer

public class DrawerItem {
    String ItemName;
    int imgResID;
    public DrawerItem(String itemName, int imgResID) {
        super();
        ItemName = itemName;
        this.imgResID = imgResID;
    }
    public String getItemName() {
        return ItemName;
    }
    public void setItemName(String itemName) {
        ItemName = itemName;
    }
    public int getImgResID() {
        return imgResID;
    }
    public void setImgResID(int imgResID) {
        this.imgResID = imgResID;
    }
}

Step 3: Add Header Strings – near the top of the MainActivity.java add the following properties

    public String HEADER_NAME = "Val Okafor";  //this shows your name in the navigation header
    public String HEADER_EMAIL = "valokafor@someemail.com";
    public int HEADER_IMAGE = 1; //we will change this later to point to a resource file

Step 4: Add RecyclerView Dependency – RecyclerView is a more flexible version of ListView that was introduced as part of material design. RecyclerView has an external dependency so we have to add that dependency. Also you noticed the circle image of my picture I showed above, we also need to add another external library that provides that circle image functionality. In your build.gradle update your dependencies like so:

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.0'
    compile 'de.hdodenhof:circleimageview:1.3.0'
}

Step 5: Declare Member Variables – near the top of the Main Activity under the HEADER_IMAGE add the following lines

 private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private DrawerLayout Drawer;
private ActionBarDrawerToggle mDrawerToggle;
private List<DrawerItem> dataList;

There are some problems with the configuration of the opt-in shortcode

Step 6: Add Adapter File – At the root of the project add a package called Adapters, and under the Adapters package add a Java class file called NavDrawerAdapter.java this is where we will implement that adapter that will manage our NavigationDrawer, we will populate this file shortly

Step 7: Add Row Layout – under res/layout add layout resource file named nav_bar_row.xml – each of the item in our NavigationDrawer has two items an image and a text, and this xml file defines the layout for each row. Here is the content of this file

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:paddingTop="8dp"
              android:paddingBottom="8dp"
              android:layout_height="wrap_content"
              android:background="#ffffff"
              android:orientation="horizontal"&gt;

    &lt;ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/rowIcon"
        android:paddingLeft="16dp"
        android:src="@mipmap/ic_launcher"/&gt;

    &lt;TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="12dp"
        android:paddingTop="4dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:clickable="true"
        android:background="?attr/selectableItemBackground"
        android:id="@+id/rowText" /&gt;

&lt;/LinearLayout&gt;

Step 8: Add Header Layout – under res/layout add a layout resource file named header.xml and enter the content below; this layout file defines the header above the NavigationDrawer. The background can be any color of your choice. What did was go to http://www.materialpalette.com/ picked a blue color and using snipping tool in windows I took a little screen shot of that blue color, saved it to my res/drawable folder and used it as the background for my header.xml, you can find that background file here and here is the content of the header.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="178dp"
    android:background="@drawable/blue_background"
    android:orientation="vertical"
    android:weightSum="1">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:text="Akash Bangad"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="akash.bangad93@gmail.com"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:textStyle="normal" />
    </LinearLayout>

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/circleView"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="38dp"
        android:src="@drawable/no_logo" />
</RelativeLayout>

Step 9: Add Icons – each item in the navigation drawer has an item and icon. Its up to you what Icon you use, Here are few places where you can get icons for your Android project, the icons I used for this project are from icons4android.com. Whatever icons you select, add them to your res/drawables folder. Remember to add all the resolutions hdpi. xhdpi, etc

http://romannurik.github.io/AndroidAssetStudio
http://www.icons4android.com/
http://www.androidicons.com/

Step 10: Add Navigation Drawer Items – at the button of Main Activity add a method addItemsToDataList and here is the content of this method, and this should be after you have added your icons to the drawables folder, this method creates list of the items you want to add to your NavigationDrawer

private void addItemsToDataList(){
dataList.add(new DrawerItem(getString(R.string.title_attendants), R.drawable.ic_action_attendants_list));
dataList.add(new DrawerItem(getString(R.string.title_events), R.drawable.ic_action_events_list));
dataList.add(new DrawerItem(getString(R.string.title_registration), R.drawable.ic_action_registration));
dataList.add(new DrawerItem(getString(R.string.title_reports), R.drawable.ic_action_report));
dataList.add(new DrawerItem(getString(R.string.title_settings), R.drawable.ic_action_settings));
}

Step 11: Add Strings – add two strings items to your res/value/string.xm Open Navigation Drawer and Close Navigation Drawer

&lt;string name="navigation_drawer_open"&gt;Open Navigation Drawer&lt;/string&gt;
&lt;string name="navigation_drawer_close"&gt;Close Navigation Drawer&lt;/string&gt;

Step 12: Add DrawerLayout – update activity_main.xml in the layout folder to include DrawerLayout and RecyclerView and this is what your activity_main.xml should now look like

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/DrawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:elevation="7dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true" />
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/RecyclerView"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="#ffffff"
        android:scrollbars="vertical"></android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>

Step 13: Implement RecyclerView Adapter – Now re-open your blank navdraweradapter.java, open this Github gist and copy and paste its content into the navdraweradapter.java, to learn more about material design Navigation drawer checkout this post by Akash Bangad

Step 14: Update Java Code – Now update your MainActivity.java onCreate method to look like this

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

        mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
        mRecyclerView.setHasFixedSize(true);
        dataList = new ArrayList<DrawerItem>();
        addItemsToDataList();

        mAdapter = new NavDrawerAdapter(dataList, this, HEADER_NAME, HEADER_EMAIL, HEADER_IMAGE);

        mRecyclerView.setAdapter(mAdapter);
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout);
        mDrawerToggle = new ActionBarDrawerToggle(this, Drawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
            }

            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
            }
        };
        Drawer.setDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();
        onTouchDrawer(currentFragment);
    }

Step 15: Show Thy Image – Add an image of yourself or any image to res/drawable and then go back to #3 above and change the HEADER_IMAGE value from 1 to the drawable representing the image that you added.
You should now be able to run your App and the NavigationDrawer should be working. It will will not navigate to anywhere yet, because we have not added it and we will do that in the next section.

Support Fragment
Please make sure that all your Fragments extend from android.support.v4.app.Fragment and not from android.app.Fragment, this is because components like the DrawerLayout, RecyclerView, ActionBarToggle are defined in the Support library and not the Framework API.

Remember that our navigation drawer was implemented with RecyclerView and unlike the humble ListView the RecyclerView does not implement OnItemClick. With ListView which provides OnItemClickedListener, it is easy to handle the event that happens when a row in any list is clicked. That simplicity does bring some challenges such as what happens when you have other clickable items inside a row like buttons. The RecyclerView solved some of this problem with the concept of a LayoutManager instead of rows.

There are two ways we can handle clicks in the RecylerView – in the Adapter class and in the calling Activity or Fragment and we will use both approaches in this tutorial. To handle click for the Navigation Drawer follow these steps. To see a full tutorial about how to handle onItemTouch for RecylerView, please consult this blog post

To implement the ability to navigate to new Fragment from the navigation drawer follow these steps:

Step 1: OpenFragment Method – implement a method that opens another Fragment; the goal of any navigation system is to take you from point A to point B. In the case of the navigation drawer, you want to go from one screen (Fragment or Activity) to another screen. This simple method below accepts the name of the Fragment we want it to open and all it does is open that Fragment, copy and paste the code below to the end of your Main Activity.

public void openFragment(final Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).commit();
    }

Step 2: Static Fragment Names – At the top of your Main Activity, create static names to represent your Fragments like this

    private final static int ATTENDANT_FRAGMENT = 1;
    private final static int EVENTS_FRAGMENT = 2;
    private final static int ATTENDANCE_FRAGMENT = 3;
    private int currentFragment = 1;

Step 3: Switch Statement – As you will see shortly, once an item is clicked in the navigation drawer, the RecyclerView returns the position of that item that was clicked and we need a simple switch statement that calls the openFragment() method based on the position number that was selected. Copy and paste the method below under your openFragment() method towards the bottom of your MainActivity

private void onTouchDrawer(final int position) {
// if (currentFragment == position) return;
 currentFragment = position;
    switch (position) {
        case ATTENDANCE_FRAGMENT:
            openFragment(new AttendanceListFragment());
            setTitle(getString(R.string.title_attendants));
            break;
        case EVENTS_FRAGMENT:
            openFragment(new EventsListFragment());
            setTitle(getString(R.string.title_events));
            break;
        case ATTENDANT_FRAGMENT:
            openFragment(new AddAttendantFragment());
            setTitle(getString(R.string.title_registration));
            break;
        case CREATE_EVENT_FRAGMENT:
            openFragment(new AddEventFragment());
            setTitle(getString(R.string.title_create_event));
            break;
        default:
            return;
    }
}

Step 4: Gesture Detector – This object determines what type of touch was received whether it is a swipe up or regular tap. Add the code below towards the end of the onCreate method in your Main Activity.

final GestureDetector mGestureDetector =
                new GestureDetector(MainActivity.this, new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onSingleTapUp(MotionEvent e) {
                        return true;
                    }
                });

Step 5: AddOnItemTouchListener – this listens for a touch, and when an item is touched, we check with the GestureDetector to detect what kind of touch this is, we are only interested in the click event, we are not handling the swipe event here, and the GestureDetector returns true for click events. If the GetureDetector returns true then we get the position of the item that was clicked and pass it to the switch statement method to determine what was clicked and open that Fragment. Here is the method.

 mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
                View child = recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());

                if (child != null && mGestureDetector.onTouchEvent(motionEvent)){
                    Drawer.closeDrawers();
                    onTouchDrawer(recyclerView.getChildLayoutPosition(child));
                    return true;
                }
                return false;
            }

            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {

            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

            }
        });

You should now be able to navigate to the different Fragments listed in the navigation drawer. To verify change the Hello World texts in each of the layout of the Fragment to Hello Fragment name or change the background color of each Fragment layout to a different color so you will get visual feedback. If any thing is not working, use the source code to double check that you typed everything correctly.

Source Code
You can find the Source Code for this Tutorial @ Github

Advertisements

About the Author valokafor

I am a Software Engineer with expertise in Android Development. I am available for Android development projects.

follow me on:

Leave a Comment: