Friday, 23 December 2016

OkHttp Example in Android

Building Simple app using OkHttp Networking Library to get the users data from https://randomuser.me/ API.
RecyclerView to show the users data in List view,
Square Picasso for image Loading.
DiagonalLayout for showing image in diagonal shape.





Step: 1
======
Add all Libraries to build.gradle file like below

compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.squareup.okhttp3:okhttp:3.5.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.android.support:recyclerview-v7:25.0.1'
    compile 'com.android.support:cardview-v7:25.0.1'
    compile 'com.android.support:design:25.0.1'
    compile 'com.github.florent37:diagonallayout:1.0.2'
    compile 'de.hdodenhof:circleimageview:2.1.0'


Step: 2
======
Create a model class

package com.pratap.okhttpexample.models;

import java.io.Serializable;

/**
 * Created by pratap.kesaboyina on 15-12-2016.
 */

public class User implements Serializable {


    private String firstName;


    private String lastName;
    private String emailId;
    private String phone;
    private String cell;
    private String imageURL;


    public User() {

    }


    public User(String firstName, String lastName, String cell, String phone, String emailId, String imageURL) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.cell = cell;
        this.phone = phone;
        this.emailId = emailId;
        this.imageURL = imageURL;
    }


    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCell() {
        return cell;
    }

    public void setCell(String cell) {
        this.cell = cell;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    public String getImageURL() {
        return imageURL;
    }

    public void setImageURL(String imageURL) {
        this.imageURL = imageURL;
    }
}



Step: 3
======
Create an interface like below to get the reponse or error msg from the service when network request success or failed.


public interface IServiceRequest {

     void onResponse(String response);

     void onError(String errorResponse);


}


Step: 4
======
Create a ServiceHandler Class for all network request to call asynchronously using Okhttp Library.

i used this webservice call to fetch 5 random users, Please check the json response.

https://api.randomuser.me/?results=5


package com.pratap.okhttpexample.network;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * Created by pratap.kesaboyina on 09-12-2016.
 */

public class ServiceHandler {


    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public static OkHttpClient client = new OkHttpClient();

    public static Call post(String url, String json, Callback callback) {
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
        return call;
    }

    public static Call get(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
        return call;
    }


}



Step: 5
======
Create a Activity class with Recyclerview in XML Layout and call the https://randomuser.me/ API to get the users data randomly from the webservice.


package com.pratap.okhttpexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;

import com.pratap.okhttpexample.adapters.UsersAdapter;
import com.pratap.okhttpexample.interfaces.IServiceRequest;
import com.pratap.okhttpexample.models.User;
import com.pratap.okhttpexample.network.ServiceHandler;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;


public class MainActivity extends AppCompatActivity implements IServiceRequest {


    String responseData = "";
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;

    IServiceRequest serviceRequest;

    private List<User> usersList;


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

        getSupportActionBar().setTitle("Contacts");

        serviceRequest = MainActivity.this;
        usersList = new ArrayList<User>();


        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setHasFixedSize(true);
        // use a linear layout manager
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        // create an Object for Adapter
        mAdapter = new UsersAdapter(this, usersList);
        // set the adapter object to the Recyclerview
        recyclerView.setAdapter(mAdapter);


        callService();
    }


    public void callService() {

        ServiceHandler.get("https://api.randomuser.me/?results=5", new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();

                responseData = "No internet Connection";
                serviceRequest.onError(responseData);
            }

            @Override
            public void onResponse(Call call, Response response) {
                try {

                    if (response.isSuccessful()) {

                        responseData = response.body().string();

// jsonParsing
                        JSONObject jsnobject = new JSONObject(responseData);

                        JSONArray jsonArray = jsnobject.getJSONArray("results");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject users = jsonArray.getJSONObject(i);


                            JSONObject nameObject = users.getJSONObject("name");
                            String firstName = nameObject.getString("first");
                            String lastName = nameObject.getString("last");


                            String emailId = users.getString("email");
                            String phone = users.getString("phone");
                            String cell = users.getString("cell");


                            JSONObject pictureObject = users.getJSONObject("picture");
                            String largeImageURL = pictureObject.getString("large");


                            User user = new User(firstName, lastName, cell, phone, emailId, largeImageURL);

                            usersList.add(user);


                        }


                        serviceRequest.onResponse(responseData);
                        Log.i("Response", responseData);
                    } else {

                        responseData = "Something went Wrong";
                        serviceRequest.onError(responseData);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    responseData = "IO Error";
                    serviceRequest.onError(responseData);
                } catch (JSONException e) {
                    e.printStackTrace();
                    responseData = "Parsing Error";
                    serviceRequest.onError(responseData);
                }
            }
        });
    }


    @Override
    public void onResponse(String response) {

        recyclerView.post(new Runnable() {
            @Override
            public void run() {
                mAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    public void onError(String errorResponse) {


        Toast toast = Toast.makeText(this, errorResponse, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();

    }


}


XML Layout for the Main Activity

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        android:scrollbars="vertical" />


</LinearLayout>


Step: 5
======

Create an Adapter for the RecyclerView used in MainActivity to bind the users data.


package com.pratap.okhttpexample.adapters;

/**
 * Created by pratap.kesaboyina on 15-12-2016.
 */

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.pratap.okhttpexample.R;
import com.pratap.okhttpexample.UserDetailActivity;
import com.pratap.okhttpexample.models.User;
import com.squareup.picasso.Picasso;
import java.util.List;

public class UsersAdapter extends
        RecyclerView.Adapter<UsersAdapter.UserViewHolder> {

    private List<User> usersList;

    private Context context;

    public UsersAdapter(Context mContext, List<User> users) {
        this.context = mContext;
        this.usersList = users;

    }


    @Override
    public UserViewHolder onCreateViewHolder(ViewGroup parent,
                                             int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.users_row, null);

        // create UserViewHolder

        UserViewHolder userViewHolder = new UserViewHolder(itemLayoutView);

        return userViewHolder;
    }

    @Override
    public void onBindViewHolder(UserViewHolder userViewHolder, int position) {

        User singleUser = usersList.get(position);

        userViewHolder.user = singleUser;

        userViewHolder.txt_name.setText(singleUser.getFirstName() + " " + singleUser.getLastName());

        userViewHolder.txt_cell.setText(usersList.get(position).getCell());

        // Loads the picture
        Picasso.with(context).load(singleUser.getImageURL()).into(userViewHolder.img_photo);


    }

    // Returns the size
    @Override
    public int getItemCount() {
        return usersList.size();
    }

    public static class UserViewHolder extends RecyclerView.ViewHolder {

        public TextView txt_name;
        public TextView txt_cell;

        public ImageView img_photo;

        public User user;

        public UserViewHolder(View itemLayoutView) {
            super(itemLayoutView);

            txt_name = (TextView) itemLayoutView.findViewById(R.id.txt_name);

            txt_cell = (TextView) itemLayoutView.findViewById(R.id.txt_cell);

            img_photo = (ImageView) itemLayoutView.findViewById(R.id.img_photo);

            itemLayoutView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    //   Toast.makeText(view.getContext(), user.getFirstName() + " " + user.getLastName(), Toast.LENGTH_SHORT).show();


                    Intent userDetails = new Intent(view.getContext(), UserDetailActivity.class);

                    userDetails.putExtra("USER", user);

                    view.getContext().startActivity(userDetails);


                }
            });


        }

    }


}


Create an xml layout for each row item for the Adapter

users_row.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/selectableItemBackground"
    android:clickable="true"
    android:gravity="center_vertical"
    android:padding="16dp">

    <ImageView
        android:id="@+id/img_photo"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_launcher" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/img_photo"
        android:orientation="vertical">

        <TextView
            android:id="@+id/txt_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:paddingLeft="5dp"
            android:text="Pratap Kumar"
            android:textColor="@android:color/black"
            android:textSize="18sp" />


        <TextView
            android:id="@+id/txt_cell"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="5dp"
            android:text="8121390970"
            android:textSize="16sp" />


    </LinearLayout>

</RelativeLayout>


Step: 6
======
Create another Activity to show each user data seperatly in another screen when u click on each user item in RecyclerView List.


package com.pratap.okhttpexample;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

import com.pratap.okhttpexample.models.User;
import com.squareup.picasso.Picasso;


/**
 * Created by pratap.kesaboyina on 15-12-2016.
 */

public class UserDetailActivity extends AppCompatActivity {

    private ImageView img_photo;

    private TextView txt_fullname,txt_emailid,txt_cellnumber,txt_phonenumber;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_userdetails_diagnol);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Contact Details");


        img_photo = (ImageView) findViewById(R.id.img_photo);
        txt_fullname = (TextView) findViewById(R.id.txt_fullname);

        txt_cellnumber = (TextView) findViewById(R.id.txt_cellnumber);
        txt_phonenumber = (TextView) findViewById(R.id.txt_phonenumber);
        txt_emailid = (TextView) findViewById(R.id.txt_emailid);

        User userDetail = (User) getIntent().getSerializableExtra("USER");

        Picasso.with(this).load(userDetail.getImageURL()).into(img_photo);
        txt_fullname.setText(userDetail.getFirstName() + " " + userDetail.getLastName());
        txt_cellnumber.setText(userDetail.getCell());
        txt_emailid.setText(userDetail.getEmailId());
        txt_phonenumber.setText(userDetail.getPhone());

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}


create an xml layout for the user detail activity


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EEEEEE"
    >

    <com.github.florent37.diagonallayout.DiagonalLayout
        android:id="@+id/diagonalLayout"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        app:diagonal_angle="15"
        android:elevation="0dp"
        android:paddingBottom="16dp"
        app:diagonal_gravity="left"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        >




        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/nav_bg"/>

        <TextView
            android:id="@+id/txt_fullname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:textColor="@android:color/white"
            android:layout_gravity="top|left"
            android:textAllCaps="true"
            android:fontFamily="sans-serif-light"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="70dp"
            android:textSize="25sp"
            />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:orientation="horizontal"
            android:layout_marginTop="105dp"
            >

            <TextView
                android:id="@+id/txt_cellnumber"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textColor="@android:color/white"
                android:layout_gravity="top|left"
                android:textStyle="bold"
                android:fontFamily="sans-serif-condensed"
                android:textSize="14sp"
                />


        </LinearLayout>

    </com.github.florent37.diagonallayout.DiagonalLayout>

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/img_photo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="170dp"
        android:elevation="15dp"
        app:civ_border_width="2dp"
        app:civ_border_color="#FFF"
        android:src="@mipmap/ic_launcher"/>


    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/img_photo">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="10dp"
            android:paddingRight="10dp">


            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="8dp"
                android:elevation="5dp"
                app:cardCornerRadius="3dp">

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

                    <View
                        android:layout_width="5dp"
                        android:layout_height="match_parent"
                        android:background="@color/colorPrimaryDark" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="10dp"
                        android:gravity="center_vertical"
                        android:orientation="vertical">

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="Phone Number"
                            android:textColor="#212121"
                            android:textSize="14sp" />

                        <TextView
                            android:id="@+id/txt_phonenumber"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text=""
                            android:gravity="left"
                            android:textColor="#AA212121"
                            android:textSize="12sp" />
                    </LinearLayout>
                </LinearLayout>
            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="8dp"
                android:elevation="5dp"
                app:cardCornerRadius="3dp">

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

                    <View
                        android:layout_width="5dp"
                        android:layout_height="match_parent"
                        android:background="@color/colorPrimaryDark" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="10dp"
                        android:gravity="center_vertical"
                        android:orientation="vertical">

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="EmaiId"
                            android:textColor="#212121"
                            android:textSize="14sp" />

                        <TextView
                            android:id="@+id/txt_emailid"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text=""
                            android:gravity="left"
                            android:textColor="#AA212121"
                            android:textSize="12sp" />
                    </LinearLayout>
                </LinearLayout>
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </ScrollView>

</RelativeLayout>




Step: 7
======
Add permissions, Activities to AndroidManifest.xml



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pratap.okhttpexample">


    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <activity
            android:name=".UserDetailActivity"
            android:label="@string/app_name"

            android:screenOrientation="portrait">

            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />


        </activity>
    </application>

</manifest>



Step: 8
======
styles.xml


<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
  
</resources>



Credits
========
All the credits to respective authors for their awesome library's provided for android community to build better apps.