Runtime/Dynamically Change Android Application Theme

Before android lollipop most of the apps provides only two or three themes to change at run time because they have already bundled image object for that theme color. I mean images and all selector color are defined and drawable already created with all theme colors because there is no primary color and color accent attribute that allow you to change color dynamically before lollipop. In Lollipop they have add selector that change all objects like edit text and switch with the theme color and that's very cool. All object look similar and contrasting to your theme.

So how the app developer change themes run time ?
How to change full app theme run time?

Well for answer of above questions go through full tutorial and you will learn how application default theme changed with newly selected color at run time.

androprogrammer.com


Steps

Step - 1
Create activity where user can select theme color. in this tutorial it is ChangeThemeDemo. I have taken only two colors but you can add as many as you want. It is really lengthy process but if you go step by step it will be so much easy for you. Now create theme.xml in values folder where you will define all themes that you want to implement. And user can change theme from it run time.

values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme.Green" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/primary_green</item>
        <item name="colorPrimaryDark">@color/primary_dark_green</item>
        <item name="colorAccent">@color/accent_green</item>
        <item name="colorControlHighlight">@color/primary_green</item>
        <item name="android:textColorPrimary">@color/primary_text</item>
        <item name="android:textColorSecondary">@color/secondary_text</item>
    </style>

    <style name="AppTheme.Purple" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/primary_purple</item>
        <item name="colorPrimaryDark">@color/primary_dark_purple</item>
        <item name="colorAccent">@color/accent_purple</item>
        <item name="colorControlHighlight">@color/primary_purple</item>
        <item name="android:textColorPrimary">@color/primary_text</item>
        <item name="android:textColorSecondary">@color/secondary_text</item>
    </style>

</resources>

values/color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primary_green">#52bf90</color>
    <color name="primary_dark_green">#398564</color>
    <color name="accent_green">#FF4081</color>
    <color name="activity_bg">#e4e5e5</color>
    <color name="primary_purple">#673AB7</color>
    <color name="primary_dark_purple">#512DA8</color>
    <color name="primary_light">#D1C4E9</color>
    <color name="accent_purple">#FF9800</color>
    <color name="primary_text">#212121</color>
    <color name="secondary_text">#727272</color>
    <color name="icons">#FFFFFF</color>
    <color name="divider">#B6B6B6</color>
    <color name="activity_bg_black">#374046</color>
</resources>

Ok, now your basic theme is set. i have created themes.xml file for only declaring base of theme. You can create your hole theme over here as i have created in styles.xml. check out below code for different themes i have created light and dark and both version of my theme in it.

values/styles.xml 
<resources>

    <style name="AppTheme.Base.Green" parent="AppTheme.Green">
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@color/activity_bg</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.Base.Green.Dark" parent="AppTheme.Green">
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@color/activity_bg_black</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.Base.Purple" parent="AppTheme.Purple">
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@color/activity_bg</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.Base.Purple.Dark" parent="AppTheme.Purple">
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@color/activity_bg_black</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <!-- Base application themes. -->
    <style name="ThemeApp.Green" parent="AppTheme.Base.Green"/>
    <style name="ThemeApp.Green.Dark" parent="AppTheme.Base.Green.Dark"/>
    <style name="ThemeApp.Purple" parent="AppTheme.Base.Purple"/>
    <style name="ThemeApp.Purple.Dark" parent="AppTheme.Base.Purple.Dark"/>


    <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
        <item name="spinBars">true</item>
        <item name="color">@android:color/white</item>
    </style>

</resources>


Step - 2
In step - 1 we have set all things for themes. now in this step i am going to create layout for theme chooser. you can create as you want but for basic setup you can put below code into your activity. it will allow user to select weather they want to apply light or dark theme. i have directly given values for text and padding and margin but for this tutorial only. it is good practice that you declare it in strings.xml and dimen.xml and then apply here. so it will be reusable.

layout/activity_changetheme_demo.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize"
    tools:context="com.androprogrammer.tutorials.samples.ChangeThemeDemo">

    <LinearLayout
        android:id="@+id/layout_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="?attr/colorPrimary">


        <android.support.v7.widget.SwitchCompat
            android:id="@+id/switch_darkTheme"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dip"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:textColor="@android:color/white"
            android:text="Dark Theme"
            tools:text="Dark Theme"/>

    </LinearLayout>

    <LinearLayout
        android:layout_below="@id/layout_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dip"
        android:padding="10dip"
        android:background="@android:color/white"
        android:id="@+id/Layout_green">

        <LinearLayout
            android:layout_width="30dip"
            android:layout_height="35dip"
            android:gravity="center"
            android:clickable="false"
            android:elevation="5dip"
            android:background="@color/primary_green"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Green"
            android:gravity="center"
            android:clickable="false"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:padding="8dip"
            android:layout_marginLeft="10dip"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dip"
        android:padding="10dip"
        android:layout_below="@id/Layout_green"
        android:background="@android:color/white"
        android:id="@+id/Layout_purple">

        <LinearLayout
            android:layout_width="30dip"
            android:layout_height="35dip"
            android:gravity="center"
            android:clickable="false"
            android:elevation="5dip"
            android:background="@color/primary_purple"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Purple"
            android:gravity="center"
            android:clickable="false"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:padding="8dip"
            android:layout_marginLeft="10dip"/>

    </LinearLayout>

</RelativeLayout>


Step - 3
Now to change theme in overall screen in your application you have to put below code in your Base or Main Activity so when ever you start app your your new themes gets apply for whole app. in my case i have BaseActivty which i am extending in all other activities so if i put that code in that activity my whole app themes get changed. MainController is application class in my app you can find code here. you have to put below code before calling super.onCreate(savedInstanceState); because setTheme Method will change theme through out the app.

if (!MainController.preferenceGetString("AppliedTheme","").equals(""))
        {
            if (MainController.preferenceGetString("AppliedTheme","").equals("Green"))
            {
                setTheme(R.style.ThemeApp_Green);
            }
            else if (MainController.preferenceGetString("AppliedTheme","").equals("Green_Dark"))
            {
                setTheme(R.style.ThemeApp_Green_Dark);
            }
            else if (MainController.preferenceGetString("AppliedTheme","").equals("Purple_Dark"))
            {
                setTheme(R.style.ThemeApp_Purple_Dark);
            }
            else if (MainController.preferenceGetString("AppliedTheme","").equals("Purple"))
            {
                setTheme(R.style.ThemeApp_Purple);
            }
        }
        else
        {
            setTheme(R.style.ThemeApp_Green);
        }

As i have already told, you don't have to use strings directly you have to define in strings.xml so if you want to change some thing you have to change it at only one place.



Step - 4
Well now all set, now put below code in Java class in this tutorial it is ChangeThemeDemo.java. where you have to change preference on the basis of user selection. which theme is selected by user and weather light version or dark.

samples/ChangeThemeDemo.java
package com.androprogrammer.tutorials.samples;


import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.widget.SwitchCompat;
import android.transition.Explode;
import android.transition.Transition;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.CompoundButton;
import android.widget.LinearLayout;

import com.androprogrammer.tutorials.MainController;
import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.activities.Listactivity;


/**
 * Created by Wasim on 15-08-2015.
 */
public class ChangeThemeDemo extends Baseactivity implements View.OnClickListener{

    protected View view;
    private LinearLayout layout_green, layout_purple;
    private SwitchCompat switch_dark;
    private boolean isDarkTheme;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

            //set the transition
            Transition ts = new Explode();
            ts.setDuration(5000);
            getWindow().setEnterTransition(ts);
            getWindow().setExitTransition(ts);
        }

        super.onCreate(savedInstanceState);

        setReference();

        setToolbarElevation(0);

        setToolbarSubTittle(this.getClass().getSimpleName());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public void setReference() {
        view = LayoutInflater.from(this).inflate(R.layout.activity_changetheme_demo,container);

        switch_dark = (SwitchCompat) view.findViewById(R.id.switch_darkTheme);
        layout_green = (LinearLayout) view.findViewById(R.id.Layout_green);
        layout_purple = (LinearLayout) view.findViewById(R.id.Layout_purple);

        switch_dark.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (isChecked)
                {
                    isDarkTheme = true;
                    MainController.preferencePutBoolean("DarkTheme", true);
                }
                else {
                    isDarkTheme = false;
                    MainController.preferencePutBoolean("DarkTheme", false);
                }
            }
        });

        if (MainController.preferenceGetBoolean("DarkTheme", false))
        {
            switch_dark.setChecked(true);
        }

        layout_green.setOnClickListener(this);
        layout_purple.setOnClickListener(this);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                finish();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId())
        {
            case R.id.Layout_green:
                if (isDarkTheme)
                    MainController.preferencePutString("AppliedTheme", "Green_Dark");
                else
                    MainController.preferencePutString("AppliedTheme", "Green");

                TaskStackBuilder.create(this)
                        .addNextIntent(new Intent(this, Listactivity.class))
                        .addNextIntent(getIntent())
                        .startActivities();
                break;

            case R.id.Layout_purple:

                if (isDarkTheme)
                    MainController.preferencePutString("AppliedTheme", "Purple_Dark");
                else
                    MainController.preferencePutString("AppliedTheme", "Purple");

                TaskStackBuilder.create(this)
                        .addNextIntent(new Intent(this, Listactivity.class))
                        .addNextIntent(getIntent())
                        .startActivities();
                break;
        }

    }
}


After changing theme you have to restart your activity. you also have to change themes in previous screens also. because they are already opened and in Activity stacktrace. So to change theme in it  also i have created TaskStackBuilder. which allow us to recreate Activity stack trace. in my case i have given only two intents but you have to pass activity hierarchy so user don't know that whole app is restarted.
               TaskStackBuilder.create(this)
                        .addNextIntent(new Intent(this, Listactivity.class))
                        .addNextIntent(getIntent())
                        .startActivities();

That's it from my side. now run the app and see the result. if you have any query or suggestion please let me know in below comment box.

keep coding...

Source code

Crop and Compress Images in Android

Images and Icons are now one of the essential element of android application. With the new Material design more icons are used then text. But they are compressed and well created so it won't get stretched in any screen size devices. But at run time there are number of applications from where user can upload images, during this process image cropping and compression is required (must). because user may upload large file and it may take long to upload. and if network connectivity is weak your app may crash due to an error. That will create bad impact on user.

So developers(you) has to take proper measures because even image compression and upload task increase load on mobile's ram and processor also. Apps like facebook, whatsApp, Google plus and many well known app does the same thing. so how they do and what is the proper way of doing it and even make it optimized. Go through these tutorial and you will notice different in timing and size.


androprogrammer.com

Steps

Step -1
Create an activity where user can pic image (can take new image or can chose from gallery). in this tutorial it is TakeImageDemo. now put below layout code in xml file. I have used simple layout for this tutorial but you can create as you want.

layout/activity_takepicture_demo.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="?attr/actionBarSize"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.androprogrammer.tutorials.samples.TakePictureDemo">

        <Button
            android:id="@+id/btnTakePicture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="takePicture_Click"
            android:text="Take Picture" />

        <ImageView
            android:id="@+id/img_camera"
            android:layout_width="200dip"
            android:layout_height="200dip"
            android:layout_below="@+id/btnTakePicture"
            android:layout_centerHorizontal="true"
            android:layout_margin="5dp"
            tools:src="@mipmap/abc1" />

</RelativeLayout>


Step - 2
Now your layout or designing part is done. Android by default (implicit intent) doesn't provide any intent to crop images so we have to call "com.android.camera.action.CROP" package. That package takes image as data and display image crop view to user like the above image.

TakePictureDemo.java
package com.androprogrammer.tutorials.samples;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;

import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.util.Common;

import java.io.ByteArrayOutputStream;
import java.io.File;

public class TakePictureDemo extends Baseactivity {

    protected View view;
    protected ImageView imgViewCamera;
    protected int LOAD_IMAGE_CAMERA = 0, CROP_IMAGE = 1, LOAD_IMAGE_GALLARY = 2;
    private Uri picUri;
    private File pic;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setReference();

        setToolbarElevation(7);

        setToolbarSubTittle(this.getClass().getSimpleName());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    }

    @Override
    public void setReference() {
        view = LayoutInflater.from(this).inflate(R.layout.activity_takepicture_demo, container);
        imgViewCamera = (ImageView) view.findViewById(R.id.img_camera);
    }

    public void takePicture_Click(View v) {
        final CharSequence[] options = {"Take Photo", "Choose from Gallery"};

        AlertDialog.Builder builder = new AlertDialog.Builder(TakePictureDemo.this);
        builder.setTitle("Select Pic Using...");
        builder.setItems(options, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int item) {
                if (options[item].equals("Take Photo")) {

                    try {
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

                        pic = new File(Environment.getExternalStorageDirectory(),
                                "tmp_" + String.valueOf(System.currentTimeMillis()) + ".jpg");

                        picUri = Uri.fromFile(pic);

                        cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, picUri);

                        cameraIntent.putExtra("return-data", true);
                        startActivityForResult(cameraIntent, LOAD_IMAGE_CAMERA);
                    } catch (ActivityNotFoundException e) {
                        e.printStackTrace();
                    }

                } else if (options[item].equals("Choose from Gallery")) {
                    Intent intent = new Intent(Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(Intent.createChooser(intent, "Select Picture"), LOAD_IMAGE_GALLARY);
                }
            }
        });

        builder.show();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == LOAD_IMAGE_CAMERA && resultCode == RESULT_OK) {
                CropImage();

        }
        else if (requestCode == LOAD_IMAGE_GALLARY) {
            if (data != null) {

                picUri = data.getData();
                CropImage();
            }
        }
        else if (requestCode == CROP_IMAGE) {
            if (data != null) {
                // get the returned data
                Bundle extras = data.getExtras();

                // get the cropped bitmap
                Bitmap photo = extras.getParcelable("data");

                imgViewCamera.setImageBitmap(photo);

                if (pic != null)
                {
                    // To delete original image taken by camera
                    if (pic.delete())
                        Common.showToast(TakePictureDemo.this,"original image deleted...");
                }
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == android.R.id.home) {
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    protected void CropImage() {
        try {
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(picUri, "image/*");

            intent.putExtra("crop", "true");
            intent.putExtra("outputX", 200);
            intent.putExtra("outputY", 200);
            intent.putExtra("aspectX", 3);
            intent.putExtra("aspectY", 4);
            intent.putExtra("scaleUpIfNeeded", true);
            intent.putExtra("return-data", true);

            startActivityForResult(intent, CROP_IMAGE);

        } catch (ActivityNotFoundException e) {
            Common.showToast(this, "Your device doesn't support the crop action!");
        }
    }

    public Bitmap CompressResizeImage(Bitmap bm)
    {
        int bmWidth = bm.getWidth();
        int bmHeight = bm.getHeight();
        int ivWidth = imgViewCamera.getWidth();
        int ivHeight = imgViewCamera.getHeight();


        int new_height = (int) Math.floor((double) bmHeight *( (double) ivWidth / (double) bmWidth));
        Bitmap newbitMap = Bitmap.createScaledBitmap(bm, ivWidth, new_height, true);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        newbitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();

        Bitmap bm1 = BitmapFactory.decodeByteArray(b, 0, b.length);

        return bm1;
    }
}




As you can see i am calling crop method from both the case when user take using camera or select image from gallery. one more thing you have to note that if user take new image using camera i am deleting that original file and just storing cropped image so it won't create space issue.

It is best practice that first you resize image and then compress it so it won't get stretched.

Step - 3

AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />

Paste above code in manifest file. it required to use camera in your app.

That's it from my side. now run the app and see the result. if you have any query please let me know in below comment box.

keep coding...

Source code

View Pager With Circular Indicator (without any library)

There are number of libraries available to create circular indicator for view pager. But i think you don't require that all heavy weight libraries. They all filled with so much congested and non used code in it. It may happen you may come across some odd issue with those libs. So to save your time and even with easy to understand code i have written this tutorial. Go through full tutorial and you find how easy it is.

I have created View pager for introduction of the application (Current trend of application start screen almost in all Google apps). But you can use it as per your requirement.

viewpager demo


Steps

Step -1
Create activity (welcome screen) which holds pager to display images and give proper name to it. In this tutorial it is ViewPagerDemo Activity. now put below code inside into xml file (layout file).

activity_viewpager_demo.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.androprogrammer.tutorials.samples.ViewPagerDemo">

    <android.support.v4.view.ViewPager
        android:id="@+id/pager_introduction"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:listitem="@layout/pager_item" />

    <RelativeLayout
        android:id="@+id/viewPagerIndicator"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:layout_alignParentBottom="true"
        android:layout_marginTop="5dp"
        android:gravity="center">

        <LinearLayout
            android:id="@+id/viewPagerCountDots"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:orientation="horizontal" />

        <ImageButton
            android:id="@+id/btn_next"
            android:layout_width="42dip"
            android:layout_height="42dip"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dip"
            android:background="@drawable/btn_round_semitransperant"
            android:src="@mipmap/ic_navigation_arrow_forward" />

        <ImageButton
            android:id="@+id/btn_finish"
            android:layout_width="42dip"
            android:layout_height="42dip"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dip"
            android:background="@drawable/btn_round_semitransperant"
            android:contentDescription="Let's start"
            android:src="@mipmap/ic_navigation_check"
            android:visibility="gone" />

    </RelativeLayout>

</RelativeLayout>


Step - 2
Above code will show error but don't worry it is for drawable files. so below are drawable files put the code in appropriate file and your layout is set.

pager_item.xml
<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:src="@mipmap/abc1"
        android:id="@+id/img_pager_item"
        android:scaleType="fitXY"
        android:adjustViewBounds="true"
        android:clickable="false"/>

</LinearLayout>


drawable/selecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="12dip" android:width="12dip"/>

    <solid android:color="@color/primary"/>
</shape>


drawable/nonselecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="6dip" android:width="6dip"/>

    <solid android:color="@color/activity_bg"/>
</shape>




Step - 3
For View pager, layout part is done. you can find sample images from here. now let's move to code part where i have created circular dots on the basis of data size. So if you have let say 10 images it will create 10 dots with first one as selected by default. put the code in to activity and make changes as per your project implementation.

ViewPagerDemo.java
package com.androprogrammer.tutorials.samples;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.adapters.ViewPagerAdapter;

public class ViewPagerDemo extends Baseactivity implements ViewPager.OnPageChangeListener, View.OnClickListener{

    protected View view;
    private ImageButton btnNext, btnFinish;
    private ViewPager intro_images;
    private LinearLayout pager_indicator;
    private int dotsCount;
    private ImageView[] dots;
    private ViewPagerAdapter mAdapter;

    private int[] mImageResources = {
            R.mipmap.abc1,
            R.mipmap.abc2,
            R.mipmap.abc3,
            R.mipmap.abc4,
            R.mipmap.abc5
    };

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        // To make activity full screen.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        super.onCreate(savedInstanceState);

        setReference();

        toolbar.setVisibility(View.GONE);

    }

    @Override
    public void setReference() {
        view = LayoutInflater.from(this).inflate(R.layout.activity_viewpager_demo,container);

        intro_images = (ViewPager) view.findViewById(R.id.pager_introduction);
        btnNext = (ImageButton) view.findViewById(R.id.btn_next);
        btnFinish = (ImageButton) view.findViewById(R.id.btn_finish);

        pager_indicator = (LinearLayout) view.findViewById(R.id.viewPagerCountDots);

        btnNext.setOnClickListener(this);
        btnFinish.setOnClickListener(this);

        mAdapter = new ViewPagerAdapter(ViewPagerDemo.this, mImageResources);
        intro_images.setAdapter(mAdapter);
        intro_images.setCurrentItem(0);
        intro_images.setOnPageChangeListener(this);
        setUiPageViewController();
    }

    private void setUiPageViewController() {

        dotsCount = mAdapter.getCount();
        dots = new ImageView[dotsCount];

        for (int i = 0; i < dotsCount; i++) {
            dots[i] = new ImageView(this);
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
            );

            params.setMargins(4, 0, 4, 0);

            pager_indicator.addView(dots[i], params);
        }

        dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_next:
                intro_images.setCurrentItem((intro_images.getCurrentItem() < dotsCount)
                        ? intro_images.getCurrentItem() + 1 : 0);
                break;

            case R.id.btn_finish:
                finish();
                break;
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        for (int i = 0; i < dotsCount; i++) {
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));
        }

        dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));

        if (position + 1 == dotsCount) {
            btnNext.setVisibility(View.GONE);
            btnFinish.setVisibility(View.VISIBLE);
        } else {
            btnNext.setVisibility(View.VISIBLE);
            btnFinish.setVisibility(View.GONE);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}


This is code for view pager adapter.which fills all images into view pager and display like gallery.
adapters/ViewPagerAdapter.java
package com.androprogrammer.tutorials.adapters;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.androprogrammer.tutorials.R;

/**
 * Created by Wasim on 11-06-2015.
 */
public class ViewPagerAdapter extends PagerAdapter {

    private Context mContext;
    private int[] mResources;

    public ViewPagerAdapter(Context mContext, int[] mResources) {
        this.mContext = mContext;
        this.mResources = mResources;
    }

    @Override
    public int getCount() {
        return mResources.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((LinearLayout) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.pager_item, container, false);

        ImageView imageView = (ImageView) itemView.findViewById(R.id.img_pager_item);
        imageView.setImageResource(mResources[position]);

        container.addView(itemView);

        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout) object);
    }
}


That's it from my side. now run the app and see the result. and at the end i am replacing next button with finish button. if you have any query please let me know in below comment box.

Keep coding...

Source code

Android Wear: How to send data from Android Wear to Mobile Device ?

Android Wear or Let say Smart Watches are new and trending technology. Android apps are updating and they all comes with Android wear support. if you want it is in your app you can find simple Helloworld wear app tutorials easily on Google. but what if you want to explore it more let say you want to display a List view in android wear or get some kind of input from android wear app. so these tutorial is for you. In this tutorial i have created simple list in android wear app in which user click on list item and an app in mobile device gets open. for example you want to display list of songs in android wear app and on the click of that you want to change song in your device or let say you can display to do list on android wear and on the click of list item you can open to do item details inside your mobile app. this list can be infinite and its totally depends on you and apps in android.

Android Wear sample


Steps

Step - 1
First of let i start with adding a android wear module in development. If you have already added android wear module in you app you can skip this step. To add right click on your app root folder (name of your app folder) and go to New > Module. Select Android Wear Module and click on next. Give same name in Application name (Mobile app name) and in Module Name write wear. so you can differentiate them. Make sure you give same package name also. because when you send some data through mobile app or wear app MessageApi will check for the same package and pass that data. so if you give different name you won't be able to send or receive data. On the next screen select Blank Wear Activity and on the next screen give proper name to it.

Note - Above steps are for Android studio wizard. Sorry for eclipse developers (Please migrate to AS)

Step - 2
So our android wear module is added. I hope you have no issue in above steps. in the main activity or launcher activity i have created a List (basically list of my tutorials). For learning purpose you can start with same and after that you can change it is as you want. so put below code in appropriate layout files.

wear/layout/activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub 
   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/watch_view_stub"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e4e5e5"
    app:rectLayout="@layout/rect_activity_list"
    app:roundLayout="@layout/round_activity_list"
    tools:context=".ListActivity"
    tools:deviceIds="wear">

</android.support.wearable.view.WatchViewStub>


wear/layout/rect_activity_list.xml & wear/layout/round_activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".ListActivity"
    tools:deviceIds="wear_round">

        <android.support.wearable.view.WearableListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:overScrollMode="never" />

        <TextView
            android:id="@+id/tv_header"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_gravity="top|center"
            android:textSize="30sp"
            android:layout_marginTop="10dp"
            android:textColor="#52bf90"
            android:fontFamily="sans-serif-light"
            android:text="@string/app_name"/>

</android.support.wearable.view.BoxInsetLayout>



Step - 3
List layout is done in Step -2. now let's jump to coding part where i have initialize WearableListView with Array adapter. Using GoogleApiClient i have checked if there is a connection to a android wear from an app or not. we can get all connected nodes or devices using Wearable.NodeApi.getConnectedNodes method. check below code and make sure you understand or go through it for one time so you know what is actually going on. otherwise you will get confused.

wear/java/ListActivity.java
package com.androprogrammer.tutorials;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.support.wearable.view.WearableListView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;

import java.util.ArrayList;

public class ListActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,WearableListView.ClickListener {

    private WearableListView mListView;

    private ArrayList<String> listItems;

    Node mNode; // the connected device to send the message to
    GoogleApiClient mGoogleApiClient;
    private boolean mResolvingError=false;

    public static String SERVICE_CALLED_WEAR = "WearListClicked";
    public static String TAG = "WearListActivity";


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

        //Connect the GoogleApiClient
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        initializeListItems();
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mListView = (WearableListView) stub.findViewById(R.id.listView1);

                mListView.setAdapter(new MyAdapter(ListActivity.this, listItems));
                mListView.setClickListener(ListActivity.this);

            }
        });
    }

    private void initializeListItems() {

        listItems = new ArrayList<>();
        listItems.add("Async File Read");
        listItems.add("Battery Status");
        listItems.add("Volume Setting");
        listItems.add("Frame Animation");
        listItems.add("Video Player");
        listItems.add("Circular Image View");
        listItems.add("Track User Location");
        listItems.add("Take Image");
        listItems.add("Image Grid View");
        listItems.add("Image Switcher");
        listItems.add("Tabs with Toolbar");
        listItems.add("Icon Tabs with Toolbar");
        listItems.add("Push Notification");


    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!mResolvingError) {
            mGoogleApiClient.connect();
        }
    }

    /**
     * Resolve the node = the connected device to send the message to
     */
    private void resolveNode() {

        Wearable.NodeApi.getConnectedNodes(mGoogleApiClient)
                .setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                    @Override
                    public void onResult(NodeApi.GetConnectedNodesResult nodes) {
                        for (Node node : nodes.getNodes()) {
                    mNode = node;
                }
            }
        });
    }

    @Override
    public void onConnected(Bundle bundle) {
        resolveNode();
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    /**
     * Send message to mobile handheld
     */
    private void sendMessage(String Key) {

        if (mNode != null && mGoogleApiClient!= null && mGoogleApiClient.isConnected()) {
            Log.d(TAG, "-- " + mGoogleApiClient.isConnected());
            Wearable.MessageApi.sendMessage(
                    mGoogleApiClient, mNode.getId(), SERVICE_CALLED_WEAR + "--" + Key, null).setResultCallback(

                    new ResultCallback<MessageApi.SendMessageResult>() {
                        @Override
                        public void onResult(MessageApi.SendMessageResult sendMessageResult) {

                            if (!sendMessageResult.getStatus().isSuccess()) {
                                Log.e(TAG, "Failed to send message with status code: "
                                        + sendMessageResult.getStatus().getStatusCode());
                            }
                        }
                    }
            );
        }

    }

    @Override
    public void onClick(WearableListView.ViewHolder viewHolder) {
        TextView view = (TextView) viewHolder.itemView.findViewById(R.id.row_tv_name);
        String Key = view.getText().toString();
        Log.d(TAG, Key);
        sendMessage(Key);
    }

    @Override
    public void onTopEmptyRegionClick() {
        Toast.makeText(this, "You tapped on Top empty area", Toast.LENGTH_SHORT).show();
    }


    private class MyAdapter extends WearableListView.Adapter {
        private final LayoutInflater mInflater;
        private ArrayList<String> data;

        private MyAdapter(Context context, ArrayList<String> listItems) {
            mInflater = LayoutInflater.from(context);
            data = listItems;
        }

        @Override
        public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new WearableListView.ViewHolder(
                    mInflater.inflate(R.layout.row_wear_list, null));
        }

        @Override
        public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
            TextView view = (TextView) holder.itemView.findViewById(R.id.row_tv_name);
            view.setText(data.get(position));
            holder.itemView.setTag(position);
        }

        @Override
        public int getItemCount() {
            return data.size();
        }
    }
}


wear/layout/row_wear_list.xml
<?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="80dp"
    android:orientation="horizontal"
    android:padding="8dp"
    android:gravity="center">

    <TextView
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:textStyle="bold"
        android:ellipsize="end"
        android:maxEms="15"
        android:padding="10dp"
        android:ems="15"
        android:background="@android:color/white"
        android:textColor="@android:color/black"
        android:fontFamily="sans-serif-condensed-light"
        android:gravity="center"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:textSize="16sp"
        android:id="@+id/row_tv_name" />

</LinearLayout>

wear/AndroidManifest.xml
<meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

Please add above lines of code in manifest file of wear module. because we are using google play service to communicate. otherwise it will give error.

Step - 4
Now android wear module is ready. you can run it separately on emulator and check it. now we require a bridge which can pass android wear message to android mobile app. so when user click on list item in android wear a service get some sort of message and on the basis of that message we start appropriate activity. Using WearableListenerService we will create service which will do same for our app.

mobile/java/WearListCallListenerService.java
package com.androprogrammer.tutorials.services;

import android.content.Intent;
import android.util.Log;

import com.androprogrammer.tutorials.activities.Listactivity;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;

/**
 * Created by Wasim on 08-05-2015.
 */
public class WearListCallListenerService extends WearableListenerService {

    public static String SERVICE_CALLED_WEAR = "WearListClicked";


    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        super.onMessageReceived(messageEvent);

        String event = messageEvent.getPath();

        Log.d("Listclicked", event);

        String [] message = event.split("--");

        if (message[0].equals(SERVICE_CALLED_WEAR)) {

            startActivity(new Intent((Intent) Listactivity.getInstance().tutorials.get(message[1]))
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
        }
    }
}


Step - 5
In Mobile app put below code to register your service.

mobile/AndroidManifest.xml
<service android:name=".services.WearListCallListenerService">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
            </intent-filter>
        </service>

That's it...
Now run wear module in android wear emulator and mobile module in device. make sure you are connected. I hope you understand the full tutorial. you can get full source code from my Github repo. if you find it helpful please share this tutorial.

Keep coding...

Material Design: Tabs with Toolbar

Action bar is deprecated in android 5.0 known as Android Lollipop and new toolbar is introduced by Android(Google) developers. Toolbar is also a simple view like others but to enhance UI and UX of apps they have introduced it with some enhancement. In Android 5.0 Tabs are also recreated with some enhancement. because toolbar doesn't support direct tabs like actionbar. In action bar you can add tabs using method called addTab() but with tabs you can't use same method. now you even don't require Tab host or Tab widget to add tabs. so how ?

Well go through full tutorial and you can implement nice tabs like google play, google music and many other apps have. Tabs are mostly used to display two different views in same page or activity. most of the developer load different fragments in tabs so they can have control over tabs and views associated with it. Tabs can be of two types.

1. Tabs with label
2. Tabs with icons




Steps

Step - 1
Create activity which holds tabs inside view part and give proper name to it. In this tutorial it is TabViewDemo Activity. To create tabs first we have to create SlidingTabLayout and SlidingTabStripe custom view. So put below both class code in your project.
Get it from github

SlidingTabLayout.java
SlidingTabStripe.java

Step - 2 a)
Now put below code in activity which you have created in Step - 1. this activity is Demo activity which will display tabs with labels(type -1). Below you can find layout and class file code put the code inside your project.

activity_tabview_demo.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize"
    tools:context="com.androprogrammer.tutorials.samples.TabViewDemo">

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

        <com.androprogrammer.tutorials.customviews.SlidingTabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tab_layout_header"
            android:elevation="8dp"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/tab_layout_container"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:background="@color/activity_bg" />

    </LinearLayout>

</RelativeLayout>



TabViewDemo.java
package com.androprogrammer.tutorials.samples;

import android.app.ActionBar;

import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.transition.Slide;
import android.transition.Transition;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;


import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.adapters.TabFragmentAdapter;
import com.androprogrammer.tutorials.customviews.SlidingTabLayout;
import com.androprogrammer.tutorials.fragments.FragmentOne;
import com.androprogrammer.tutorials.fragments.FragmentThree;
import com.androprogrammer.tutorials.fragments.FragmentTwo;

import java.util.ArrayList;

public class TabViewDemo extends Baseactivity implements ActionBar.TabListener {

    protected View view;
    protected SlidingTabLayout tabs_header;
    protected android.support.v4.view.ViewPager mPager;
    protected ArrayList<fragment> fragments;
    protected TabFragmentAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            getWindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);

            //set the transition
            Transition ts = new Slide();
            ts.setDuration(3000);
            getWindow().setEnterTransition(ts);
            getWindow().setExitTransition(ts);

        }

        super.onCreate(savedInstanceState);

        setReference();

        setToolbarSubTittle(this.getClass().getSimpleName());

        setToolbarElevation(0);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        fragments.add(new FragmentOne());
        fragments.add(new FragmentTwo());
        fragments.add(new FragmentThree());

        String[] titles = {"One", "Two", "Three"};

        mAdapter = new TabFragmentAdapter(getSupportFragmentManager(), fragments, titles);

        mPager.setAdapter(mAdapter);

        tabs_header.setBackgroundColor(getResources().getColor(R.color.primary));
        tabs_header.setTitleColor(Color.WHITE);
        tabs_header.setFittingChildren(true);
        tabs_header.setTabType(SlidingTabLayout.TabType.TEXT);
        tabs_header.setViewPager(mPager);
    }

    @Override
    public void setReference() {

        view = LayoutInflater.from(this).inflate(R.layout.activity_tabview_demo,container);

        tabs_header = (SlidingTabLayout) view.findViewById(R.id.tab_layout_header);
        mPager = (android.support.v4.view.ViewPager) view.findViewById(R.id.tab_layout_container);
        fragments = new ArrayList<fragment>();

        SetTabSelector();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                finish();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    private void SetTabSelector()
    {
        tabs_header.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position)
            {
                int ColorId = 0;

                switch (position)
                {
                    case 0:
                        ColorId = Color.WHITE;
                        break;

                    case 1:
                        ColorId = Color.MAGENTA;
                        break;
                    case 2:
                        ColorId = Color.RED;
                        break;
                }

                return ColorId;

            }

            @Override
            public int getDividerColor(int position) {
                return 0;
            }
        });

    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }
}


Step - 2 b)
This is second sub part of tutorial. if you want to create tabs with icons(type -2) then put below code for tabs with simple text put above code in your activity. to create tabs with icon you have to give name to images like this, ic_one, ic_two etc. because i have fetched images from drawable using tab title. check below code.

private int getResourceIdByName(String resourceName) {
        // get images from mipmap folder
        return getResources().getIdentifier(resourceName, "mipmap", getContext().getPackageName());
    }

if your project consist old drawable pattern then replace mipmap with drawable in SlidingTabLayout file.

ImageTabViewDemo.java
package com.androprogrammer.tutorials.samples;

import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.transition.Slide;
import android.transition.Transition;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;

import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.adapters.TabFragmentAdapter;
import com.androprogrammer.tutorials.customviews.SlidingTabLayout;
import com.androprogrammer.tutorials.fragments.FragmentOne;
import com.androprogrammer.tutorials.fragments.FragmentThree;
import com.androprogrammer.tutorials.fragments.FragmentTwo;

import java.util.ArrayList;

public class ImageTabViewDemo extends Baseactivity implements ActionBar.TabListener {

    protected View view;
    protected SlidingTabLayout tabs_header;
    protected android.support.v4.view.ViewPager mPager;
    protected ArrayList<fragment> fragments;
    protected TabFragmentAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            getWindow().requestFeature(android.view.Window.FEATURE_CONTENT_TRANSITIONS);

            //set the transition
            Transition ts = new Slide();
            ts.setDuration(3000);
            getWindow().setEnterTransition(ts);
            getWindow().setExitTransition(ts);


        }

        super.onCreate(savedInstanceState);

        setReference();

        setToolbarSubTittle(this.getClass().getSimpleName());

        setToolbarElevation(0);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        fragments.add(new FragmentOne());
        fragments.add(new FragmentTwo());
        fragments.add(new FragmentThree());

        String[] titles = {"one", "two", "three"};

        mAdapter = new TabFragmentAdapter(getSupportFragmentManager(), fragments, titles);

        mPager.setAdapter(mAdapter);

        tabs_header.setBackgroundColor(getResources().getColor(R.color.primary));
        tabs_header.setTitleColor(Color.WHITE);
        tabs_header.setFittingChildren(true);
        tabs_header.setTabType(SlidingTabLayout.TabType.ICON);
        tabs_header.setViewPager(mPager);
    }

    @Override
    public void setReference() {

        view = LayoutInflater.from(this).inflate(R.layout.activity_tabview_demo,container);

        tabs_header = (SlidingTabLayout) view.findViewById(R.id.tab_layout_header);
        mPager = (android.support.v4.view.ViewPager) view.findViewById(R.id.tab_layout_container);
        fragments = new ArrayList<fragment>();

        SetTabSelector();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                finish();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    private void SetTabSelector()
    {
        tabs_header.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position)
            {
                int ColorId = 0;

                switch (position)
                {
                    case 0:
                        ColorId = Color.WHITE;
                        break;

                    case 1:
                        ColorId = Color.MAGENTA;
                        break;
                    case 2:
                        ColorId = Color.RED;
                        break;
                }

                return ColorId;

            }

            @Override
            public int getDividerColor(int position) {
                return 0;
            }
        });

    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }
}



Resources of my project is available at Github so please get images from there. to load three different views i created adapter which extends FragmentPagerAdapter class. below is code of adapter of view pager.

TabFragmentAdapter.java
package com.androprogrammer.tutorials.adapters;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.ArrayList;

/**
 * Created by Wasim on 28-04-2015.
 */
public class TabFragmentAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> fragments;
    private String[] titles;

    public TabFragmentAdapter(FragmentManager fm, ArrayList <Fragment> fragments, String [] title) {
        super(fm);
        this.fragments = fragments;
        this.titles = title;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return super.getItemPosition(object);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles[position];
    }
}


Step - 3
In this tutorial i have even used three fragments to load on three different tabs.the fragments have no logic or code so i don't put that code here. you can find code from here.

That's it. I hope you its clear to you. now run your app. hope it will work fine. if you have any query
or have problem in code implementation write it in below comment box.

Keep coding...

Track user location in android

In android you can get user's latitude and longitude using two different providers.
  1. Using Network
  2. Using GPS
Using Location Listener interface you can get perfect location. but there is no method which actually tells you which provider is best so its good practice to use both. Network provide lat long with good accuracy so i have used it as first option and after that gps.
This tutorial is comprise of get user location and also display it in map. so if you want both the thing go through full tutorial or if you want only users latitude and longitude then skip step 2. which is actually about getting Google map key and setup it in manifest file.



gps in android application, androprogrammer.com


Steps 

Step - 1 : First of all we will create Location listener which actually gives us user location. It is service class which runs in background and give us data on the basis of location change. you can get user location every seconds but it will increase app crash chances so it is better to define time interval and distance interval. i have used 1 min as time interval and 20 meter distance interval so my app won't make call for location each and every seconds. so now create a new class file and put below code inside it.

GetUserLocation.java 

package com.androprogrammer.tutorials.services;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

/**
 * Created by Wasim on 21-03-2015.
 */
public class GetUserLocation extends Service implements LocationListener
{
    private Context context;

    private static final String TAG = "GPSGetUserLocation";

    // The maximum time that should pass before the user gets a location update.
    private static final long DEFAULT_DURATION = 1000 * 60 * 1; // 1 min

    // The default search radius when searching for places nearby.
    private static final long DEFAULT_RADIUS = 20; // 20 meters

    private LocationManager mLocationManager = null;

    private double latitude;
    private double longitude;

    // flag for GPS status
    //private boolean isGPSEnabled = false;

    // flag for network status
    //private boolean isNetworkEnabled = false;


    private Location location; // location values


    public GetUserLocation(Context context, boolean isGPSEnabled, boolean isNetworkEnabled)
    {
        this.context = context;
        getUserLocation(isGPSEnabled, isNetworkEnabled);
    }


    public GetUserLocation() {
    }

    public Location getUserLocation(boolean isGPSEnabled, boolean isNetworkEnabled)
    {
        try {

            if (mLocationManager == null)
            {
                mLocationManager = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);
            }

                // First get location from Network Provider
                if (isNetworkEnabled)
                {
                    mLocationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            DEFAULT_DURATION,
                            DEFAULT_RADIUS, this);

                    Log.d(TAG, "Network");

                    if (mLocationManager != null) {
                        location = mLocationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            setLatitude(location.getLatitude());
                            setLongitude(location.getLongitude());
                        }
                    }
                }

                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null)
                    {
                        mLocationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                DEFAULT_DURATION,
                                DEFAULT_RADIUS, this);

                        Log.d(TAG, "GPS Enabled");

                        if (mLocationManager != null) {
                            location = mLocationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                setLatitude(location.getLatitude());
                                setLongitude(location.getLongitude());
                            }
                        }
                    }
                }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onLocationChanged(Location location)
    {
        if (location != null)
        {
            setLongitude(location.getLongitude());
            setLatitude(location.getLatitude());
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        Log.d(TAG, "" + latitude);
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        Log.d(TAG, "" + longitude);
        this.longitude = longitude;
    }

    @Override
    public void onDestroy()
    {
        Log.e(TAG, "onDestroy");
        super.onDestroy();

        if (mLocationManager != null)
        {
            // Remove update listener when you don't require
            mLocationManager.removeUpdates(this);
            mLocationManager = null;
        }
    }
}


Step - 2 : To display Google map fragment inside your app you have to register your app at Google Developer console. and then get Map key. you need to set this key inside Android manifest file. otherwise your app may crash. For complete setup of Google Map api v2 you can find here.


if you have already registered your project you can find Map key at
Project > Apis & auth > Credentials.

google map key
Please do not use this key


Step - 3 : Now we need a class which actually start this service. so create a activity which start this service and get location data.in this activity i have used Google map fragment to show user location if you don't want to display lat long then toast it so you can verify that service is working and you are getting user location data.

TrackUserDemo.java 

package com.androprogrammer.tutorials.samples;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.transition.Slide;
import android.transition.Transition;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.widget.Toast;

import com.androprogrammer.tutorials.R;
import com.androprogrammer.tutorials.activities.Baseactivity;
import com.androprogrammer.tutorials.services.GetUserLocation;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class TrackUserDemo extends Baseactivity
{

    protected View view;

    // Google Map Object
    private GoogleMap googleMap;

    private LatLng userLatLng;

    private boolean IsFirstTimeLoad = true;

    private LocationManager mLocationManager;

    private static final String TAG = "TrackUserDemo";

    private static String RefreshMenu = "Refresh Map";


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

            //set the transition
            Transition ts = new Slide();
            ts.setDuration(5000);
            getWindow().setEnterTransition(ts);
            getWindow().setExitTransition(ts);
        }

        super.onCreate(savedInstanceState);

        setReference();

 getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        setToolbarTittle(this.getClass().getSimpleName());

        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        initilizeMap();

    }

    @Override
    protected void onResume()
    {
        super.onResume();
        if (!IsFirstTimeLoad)
        {
            if(!mLocationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
                showGpsAlertDialog();
            }
            else {
                Intent intent = new Intent(this, GetUserLocation.class);
                startService(intent);
                initilizeMap();
            }
        }
        else {
            IsFirstTimeLoad = false;
        }
    }

    private void initilizeMap()
    {
        try {
  // Display Toast message if you don't want to display google map using service.getLatitude(), service.getLongitude() methods
            if (googleMap == null) {
                googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
                // check if map is created successfully or not
                if (googleMap == null)
                {
                    Toast.makeText(TrackUserDemo.this, "Sorry! unable to create maps", Toast.LENGTH_LONG).show();
                }
            }

            // getting GPS status
            boolean isGPSEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            boolean isNetworkEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            GetUserLocation service = new GetUserLocation(this,isGPSEnabled,isNetworkEnabled);

            if (!isGPSEnabled)
            {

                showGpsAlertDialog();

            }

            userLatLng = new LatLng(service.getLatitude(), service.getLongitude());

            MarkerOptions usermarker = new MarkerOptions().position(userLatLng);

            // To remove old marker
            googleMap.clear();

            googleMap.addMarker(usermarker);

            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(service.getLatitude(), service.getLongitude()),
                    10.0f));

            googleMap.getUiSettings().setZoomControlsEnabled(true);

        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            //e.printStackTrace();
        }
    }

    private void showGpsAlertDialog() {

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(TrackUserDemo.this);
        alertDialogBuilder.setTitle("Gps Setting");
        alertDialogBuilder.setMessage("Location data provider is disabled.\nPlease enable it to track location.");

        alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                Intent myIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(myIntent);
            }
        });


        alertDialogBuilder.setNegativeButton(android.R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        dialog.dismiss();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();

        alertDialog.show();
    }

    @Override
    public void setReference()
    {
        view = LayoutInflater.from(this).inflate(R.layout.activity_trackuser_demo,container);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // To display refresh button
        SubMenu btnRefresh = menu.addSubMenu(RefreshMenu);
        btnRefresh.setIcon(android.R.drawable.ic_popup_sync);
        btnRefresh.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

        super.onCreateOptionsMenu(menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle Toolbar item clicks here. The Toolbar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                finish();
                break;
        }


        if (item.getTitle() == RefreshMenu)
        {
            initilizeMap();
        }

        return super.onOptionsItemSelected(item);
    }
}

activity_trackuser_demo.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="?attr/actionBarSize"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.androprogrammer.tutorials.samples.TrackUserDemo">

    <fragment
        android:id="@+id/map"
        class="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>


Step - 4 : well now add/define service and google play meta data in AndroidManifest.xml file. put below code inside it.

AndroidManifest.xml
 
<!-- IMPORTANT ! DO NOT FORGET THIS META-DATA !!! -->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="your_key" />

        <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true" />
<service android:name=".services.GetUserLocation" />

Step - 5 : One More thing you have to add dependencies in app > build.gradle file. so put below code in it.

build.gradle 

dependencies {
 // To add toolbar and material theme.
compile 'com.android.support:appcompat-v7:21.0.3'
compile fileTree(include: ['*.jar'], dir: 'libs')
 // To use Google map and other services.
compile 'com.google.android.gms:play-services:6.1.71'

well now run the app if you are testing in emulator then make sure you have Google apps inside it. other wise Google Map will not work. i hope you understand full tutorial. if you have any questions let me know in below comment box. if you like this share it with your friends.

Get code from Github

Keep coding...

Creating New App... WAIT !


Model-View-Controller (MVC) have made our work so much easy. before this coding were too much congested. business logic and design were in same file. imagine how it was. well now we have MVC Structure in all(Many of them) programming language. In which we have different files for different purpose. but still few things you have to consider if you want clean and nit code.

well, what are those things ?


If your app have user interface mobile or web interface the first thing i think most important for you.

1. Font Size

Define font size for Header, labels and detail text. what ever app you have you may require decent and same look through out the app. so this will help you. one more thing define them in Constant Class(where you can define all static and Constant variables) so you can use them through out the app. and please use even proper name also. like header_text_size or text_header_size so you can even recognize for long time.

2. Padding / Margin

One more thing you have to consider for app style and for its decent look. 

well you are thinking how ?


androprogrammer.com


3. Style

After above steps create a style according to you app colors (Theme). so if your client want to change theme you just have to change at one place no more
Ctrl + f for old color code and replace it with new.

4. Define Constants or Strings
 

You may require text like "OK" , "Save" , "Yes/No" at many place so why to write it again and again. define them once and use them through out the app. this will even help when your app is in two or more languages. so according to language you can change them.



5. Use access specifier

Private, protected, public these are the access specifier which acts like a guard. how ?
In hacking or spiffing hackers use programs which can change values of your app variables. but if you have defined access specifier before variable declaration, they are not acceessible by out side the class. So they can not change the value of that. so if you know scope of the variable define them with appropriate access specifiers.

6. Comments

Give or write proper comments for each class or method that you have defined or created. now a days editor have so many plugins which auto generate comment block so use them. you are not only working on the app or you may not work it on life time so your code must be understandable by others. so that proper comments require which clarify what it actually do.

7. Create proper directory structure

Now a days MVC have already separated our files but still we require some files to put in different folders. like in web app we have java script and css file so put them in different folders.
in mobile app create different folders for activities and services and for all others so if any error or change comes you can directly go there and find problem/change.

8. Background colors

Don't use dark or gradient colors as background use light or single color as a background. mostly we use white or light gray as a background. you can give all effects with this color and even it is more acceptable. as it will effect user experience and you may see dig ration in your app popularity.

Well these all are the points which is based on Kiss(Keep it Simple stupid). i hope you know it.
well i think i have covered all basics that you need to consider before creating any app weather it is web app or mobile app. if i forgot any point let me know in below comment box. i am really happy to know your thoughts on this article.

If you liked my blog please share and subscribe with it.

Navigation Drawer With Transparent Status bar

It is second part of  Let's Start with Material Design Series. In this series i will explain how you can give Material over haul to your existing app or how you can create it with Material design. in first part i have created the main layout of the app so if you want to know about it head over to it. Part -1 is about using Recycler view and Toolbar in Pre - Lollipop device using appcompat v21 library. In this part i am going to explain about navigation drawer. how you can implement navigation drawer as per material design guidelines.This tutorial even includes hamburger animation used in Google apps.

According to android documentation If you have hierarchy of views(More than 3 top-level views) then only you have to implement nav drawer in your app. and all top level views must be displayed in nav drawer for quick jumps to the top-level of your app. As nav drawer can be used from all views of app, you can incorporate or display important lower-level views also. but make sure child view indicate its parent view so user won't get confused.

You can use list view or expandable list view for navigation drawer but make sure for each row you use only one text view. for this tutorial i am going to create nav drawer as you can see in google apps (not the same). but as per Material design guidelines, as guidelines suggest drawer should spans the full height of the screen and the drawer should below the status bar. to span full space we need to customize frame layout. That actually Making DrawerLayout behind the system bars using fitSystemWindows property. one more thing we are using toolbar in place of action bar (that look same as action bar) that's how we will overlapping nav drawer above the action bar. as i am using appcompat library this app will look like same on pre-lollipop android device also.

As per doc the width of the side nav is equal to the width of the screen minus the height of the action bar, or 56dp from the right edge of the screen.
Mobile: Width = screen width - app bar height (No wider than 320dp on phones and 400dp on tablets).

Step -1 : As we have already created project in Part -1 we are directly going to change the main layout of project. so put below code inside Main.xml file. as it consist ScrimInsetsFrameLayout which will give error but don't worry it is customized frame layout. as you go through full tutorial you will get class file for it also. The same is used in Google I/O app. why they have given such name even i can't understand.  you can give name what ever you want. Below xml files are layout for main(content view) and navigation drawer view.
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <!-- Setting this one to true makes the status bar
        to have a non-transparent shitty background -->

    <!--
         As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions.
    -->

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="false">

        <include layout="@layout/actionbarlayout"></include>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_marginTop="?attr/actionBarSize"
            android:layout_marginRight="4dp"
            android:layout_marginLeft="4dp"
            android:elevation="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/addButton"
            android:text="+"
            android:textSize="25sp"
            android:textColor="@android:color/white"
            android:textAlignment="center"
            android:layout_marginRight="15dp"
            android:layout_marginBottom="15dp"
            android:background="@drawable/circlebtn"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:stateListAnimator="@animator/anim"
            android:elevation="4dp"
            style="?android:buttonStyleSmall"
            android:layout_gravity="right|bottom" />
        

    </FrameLayout>

    <com.androprogrammer.test.materialapp1.ScrimInsetsFrameLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:elevation="8dp"
        android:layout_gravity="start"
        app:insetForeground="#4000">

        <ListView
            android:id="@+id/list_drawer"
            android:layout_width="@dimen/drawer_width"
            android:layout_height="match_parent"
            android:choiceMode="singleChoice"
            android:background="@android:color/white"
            android:fitsSystemWindows="true" />
       

    </com.androprogrammer.test.materialapp1.ScrimInsetsFrameLayout>
</android.support.v4.widget.DrawerLayout>
actionbarlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:minHeight="?attr/actionBarSize"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/toolbar"
    android:elevation="4dp"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    android:background="@color/primary"/>

drawerlist_header.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:id="@+id/imageView"
        android:scaleType="centerCrop"
        android:clickable="false"
        android:src="@drawable/headerbg"
        android:layout_gravity="center_horizontal|top" />
</FrameLayout>

Step -2 : Now layouts are set for main view. now we will create style for app so it will look same threw out the app.
values/styles.xml
    

    

    
values/attrs.xml

    
        
    

values/color.xml

    #fe2e2e
    #EFcb2424

values/dimens.xml

    2dp
    4dp
    320dp
    56dp


values/strings.xml


    My Application1
    Settings
    open
    close


values-v21/styles.xml


Step - 3 : Now we will move forward to code section of the app which was also know as dirty or magical section of the app.  put below code in ScrimInsetsFrameLayout classor what ever you named it in xml layout. 
ScrimInsetsFrameLayout.java
package com.androprogrammer.test.materialapp1;

/**
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.widget.FrameLayout;

/**
 * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
 * (status and navigation bars, overlay action bars).
 */
public class ScrimInsetsFrameLayout extends FrameLayout {
    private Drawable mInsetForeground;

    private Rect mInsets;
    private Rect mTempRect = new Rect();
    private OnInsetsCallback mOnInsetsCallback;

    public ScrimInsetsFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ScrimInsetsView, defStyle, 0);
        if (a == null) {
            return;
        }
        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
        a.recycle();

        setWillNotDraw(true);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        mInsets = new Rect(insets);
        setWillNotDraw(mInsetForeground == null);
        ViewCompat.postInvalidateOnAnimation(this);
        if (mOnInsetsCallback != null) {
            mOnInsetsCallback.onInsetsChanged(insets);
        }
        return true; // consume insets
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        int width = getWidth();
        int height = getHeight();
        if (mInsets != null && mInsetForeground != null) {
            int sc = canvas.save();
            canvas.translate(getScrollX(), getScrollY());

            // Top
            mTempRect.set(0, 0, width, mInsets.top);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Bottom
            mTempRect.set(0, height - mInsets.bottom, width, height);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Left
            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Right
            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            canvas.restoreToCount(sc);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(null);
        }
    }

    /**
     * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
     * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
     * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
     * clipToPadding to false.
     */
    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
        mOnInsetsCallback = onInsetsCallback;
    }

    public static interface OnInsetsCallback {
        public void onInsetsChanged(Rect insets);
    }
}


It is copyrighted by Google developer so if you copy it please give proper reference to them.
MainActivity.java
package com.androprogrammer.test.materialapp1;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity implements ListView.OnItemClickListener
{
    private android.support.v7.widget.RecyclerView mRecyclerView;
    private android.support.v7.widget.RecyclerView.Adapter mAdapter;
    private android.support.v7.widget.RecyclerView.LayoutManager mLayoutManager;
    private android.support.v7.widget.Toolbar toolbar;
    private android.support.v4.widget.DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;
    private ListView leftDrawerList;
    private ArrayAdapter<string> navigationDrawerAdapter;
    private Button fab;
    private String[] leftSliderData = {"Home", "Android", "Sitemap", "About", "Contact Me"};
    protected String[] myDataset = {"facebook", "Google+", "twitter", "Linkdin", "pintrest"};


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

        setRef();

        //Set the custom toolbar
        if (toolbar != null)
        {
            toolbar.setTitle(R.string.app_name);
            setSupportActionBar(toolbar);
        }

        drawerToggle = new ActionBarDrawerToggle(
                this,
                drawerLayout,
                toolbar,
                R.string.open,
                R.string.close
        )

        {
            public void onDrawerClosed(View view)
            {
                Log.d("MainActivity", "OnDrawerClosed");
                super.onDrawerClosed(view);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                Log.d("MainActivity", "OnDrawerOpened");
                super.onDrawerOpened(drawerView);
                invalidateOptionsMenu();
            }
        };

        drawerLayout.setDrawerListener(drawerToggle);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    private void setRef()
    {
        mRecyclerView = (android.support.v7.widget.RecyclerView) findViewById(R.id.my_recycler_view);
        fab = (Button) findViewById(R.id.addButton);
        drawerLayout = (android.support.v4.widget.DrawerLayout) findViewById(R.id.drawer_layout);
        drawerLayout.setStatusBarBackground(R.color.primarydark);

        toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
        leftDrawerList = (ListView) findViewById(R.id.list_drawer);

        View list_header = getLayoutInflater().inflate(R.layout.drawerlist_header, null);
        leftDrawerList.addHeaderView(list_header);
        navigationDrawerAdapter = new ArrayAdapter<string>(MainActivity.this, android.R.layout.simple_expandable_list_item_1, leftSliderData);
        leftDrawerList.setAdapter(navigationDrawerAdapter);
        leftDrawerList.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id)
    {
        Toast.makeText(getApplicationContext(), "Clicked on " + leftSliderData[position - 1], Toast.LENGTH_LONG).show();
    }

}


Screen Shots

android navigation drawer android navigation drawer

Step - 4 : Now every thing done but please apply theme in manifest.xml in application tag.
android:theme="@style/AppTheme"
And one more thing is that to run app you need to add libraries in app.gradle file it is in app folder named as build.gradle
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:support-v4:21.0.0'
    compile 'com.android.support:recyclerview-v7:21.0.+'
    compile 'com.android.support:appcompat-v7:21.0.2'


Well that's it from my side now run the app and check how it works. hope you learned from this tutorial if find it useful please hare it with your friends or in circle. if i miss any thing or you have any query please let me know in below comment box.

Keep coding...