06 January, 2016

Android JSON Parsing Using okHttp Example with Custom View (ImageView + TextView)

Hello Androiders, Today I will show you demo about "How to Parse JSON using okHttp and Bind data with Custom View (ImageView + TextView) (Loading Image using Picasso)". 

In Last Post We have seen Android JSON Parsing Using okHttp Example with New Material Design Library in which you have learn How to Parse JSON using okHttp.

I hope you know how to Create Project in Android Studio and add gradle dependency:


In this Project we required following Dependency in your build.gradle:

compile 'com.squareup.okhttp:okhttp:2.4.0'  
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'  
compile 'com.squareup.picasso:picasso:2.4.0'

Don't forget to take permission of Internet Connection.

<uses-permission android:name="android.permission.INTERNET" />
Our Project Structure will be like:





To Check InternetConnection.java:

 public class InternetConnection {  
   
           /** CHECK WHETHER INTERNET CONNECTION IS AVAILABLE OR NOT */  
           public static boolean checkConnection(@NonNull Context context) {  
                     return ((ConnectivityManager) context.getSystemService  
                                         (Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;  
           }  
 }  


Now First of all we will get JSON from http://pratikbutani.x10.mx/json_data.json which provides following type of data.

JSON DATA:

 {  
   "contacts": [  
     {  
         "id": "c200",  
         "name": "Pratik Butani",  
         "email": "pratik13butani@gmail.com",  
         "address": "xx-xx-xxxx,x - street, x - country",  
         "gender" : "male",  
                     "profile_pic" : "http://lorempixel.com/100/100/",  
         "phone": {  
           "mobile": "+91 0000000000",  
           "home": "00 000000",  
           "office": "00 000000"  
         }  
     },  
     {  
         "id": "c201",  
         "name": "Johnny Depp",  
         "email": "johnny_depp@gmail.com",  
         "address": "xx-xx-xxxx,x - street, x - country",  
         "gender" : "male",  
         "profile_pic" : "http://lorempixel.com/105/105/",  
         "phone": {  
           "mobile": "+91 0000000000",  
           "home": "00 000000",  
           "office": "00 000000"  
         }  
     },  
     {  
         "id": "c202",  
         "name": "Leonardo Dicaprio",  
         "email": "leonardo_dicaprio@gmail.com",  
         "address": "xx-xx-xxxx,x - street, x - country",  
         "gender" : "male",  
         "profile_pic" : "http://lorempixel.com/110/110/",  
         "phone": {  
           "mobile": "+91 0000000000",  
           "home": "00 000000",  
           "office": "00 000000"  
         }  
     }  
   ]  
 }  


Constant Keys defined in on Keys class:

 public class Keys {  
   public static final String KEY_CONTACTS = "contacts";  
   public static final String KEY_NAME = "name";  
   public static final String KEY_PHONE = "phone";  
   public static final String KEY_MOBILE = "mobile";  
   public static final String KEY_PROFILE_PIC = "profile_pic";  
   public static final String KEY_EMAIL = "email";  
 }  


Now we will make Model for this Data so we can set or get the values of particular fields.


MyDataModel.java

 public class MyDataModel {  
   
   private int id;  
   
   private String name;  
   
   private String image;  
   
   private String email;  
   
   private String phone;  
   
   public int getId() {  
     return id;  
   }  
   
   public void setId(int id) {  
     this.id = id;  
   }  
   
   public String getName() {  
     return name;  
   }  
   
   public void setName(String name) {  
     this.name = name;  
   }  
   
   public String getImage() {  
     return image;  
   }  
   
   public void setImage(String image) {  
     this.image = image;  
   }  
   
   public String getEmail() {  
     return email;  
   }  
   
   public void setEmail(String email) {  
     this.email = email;  
   }  
   
   public String getPhone() {  
     return phone;  
   }  
   
   public void setPhone(String phone) {  
     this.phone = phone;  
   }  
 }


Now Its time to create XML file for layout which will display data like NAME, IMAGE, EMAIL.

layout_row_view.xml

<?xml version="1.0" encoding="utf-8"?>  
 <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="wrap_content"  
   android:orientation="vertical">  
   
   <ImageView  
     android:id="@+id/imageView"  
     android:layout_width="100dp"  
     android:layout_height="100dp"  
     android:layout_margin="5dp"  
     android:src="@mipmap/ic_launcher" />  
   
   <LinearLayout  
     android:layout_width="match_parent"  
     android:orientation="vertical"  
     android:layout_centerVertical="true"  
     android:layout_height="wrap_content"  
     android:layout_toRightOf="@+id/imageView">  
   
     <TextView  
       android:id="@+id/textViewName"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:layout_margin="5dp"  
       android:textAppearance="?android:textAppearanceLarge"  
       tools:text="TextView" />  
   
     <TextView  
       android:id="@+id/textViewEmail"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:layout_margin="5dp"  
       android:textAppearance="?android:textAppearanceMedium"  
       tools:text="TextView" />  
   
   </LinearLayout>  
 </RelativeLayout> 


Its fine we have created Layout for Particular row of ListView. Now We have to create Custom Adapter to bind Data in that row.

I found best tool Android Layout Finder to create that type of Adapters Quickly.

MyArrayAdapter.java

 import android.content.Context;  
 import android.view.LayoutInflater;  
 import android.view.View;  
 import android.view.ViewGroup;  
 import android.widget.ArrayAdapter;  
 import android.widget.ImageView;  
 import android.widget.RelativeLayout;  
 import android.widget.TextView;  
   
 import com.androidbuts.jsonparsing.R;  
 import com.androidbuts.jsonparsing.model.MyDataModel;  
 import com.squareup.picasso.Picasso;  
   
 import java.util.List;  
   
 public class MyArrayAdapter extends ArrayAdapter<MyDataModel> {  
   
   List<MyDataModel> modelList;  
   Context context;  
   private LayoutInflater mInflater;  
   
   // Constructors  
   public MyArrayAdapter(Context context, List<MyDataModel> objects) {  
     super(context, 0, objects);  
     this.context = context;  
     this.mInflater = LayoutInflater.from(context);  
     modelList = objects;  
   }  
   
   @Override  
   public MyDataModel getItem(int position) {  
     return modelList.get(position);  
   }  
   
   @Override  
   public View getView(int position, View convertView, ViewGroup parent) {  
     final ViewHolder vh;  
     if (convertView == null) {  
       View view = mInflater.inflate(R.layout.layout_row_view, parent, false);  
       vh = ViewHolder.create((RelativeLayout) view);  
       view.setTag(vh);  
     } else {  
       vh = (ViewHolder) convertView.getTag();  
     }  
   
     MyDataModel item = getItem(position);  
   
     vh.textViewName.setText(item.getName());  
     vh.textViewEmail.setText(item.getEmail());  
     Picasso.with(context).load(item.getImage()).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(vh.imageView);  
   
     return vh.rootView;  
   }  
   
   /**  
    * ViewHolder class for layout.<br />  
    * <br />  
    * Auto-created on 2016-01-05 00:50:26 by Android Layout Finder  
    * (http://www.buzzingandroid.com/tools/android-layout-finder)  
    */  
   private static class ViewHolder {  
     public final RelativeLayout rootView;  
     public final ImageView imageView;  
     public final TextView textViewName;  
     public final TextView textViewEmail;  
   
     private ViewHolder(RelativeLayout rootView, ImageView imageView, TextView textViewName, TextView textViewEmail) {  
       this.rootView = rootView;  
       this.imageView = imageView;  
       this.textViewName = textViewName;  
       this.textViewEmail = textViewEmail;  
     }  
   
     public static ViewHolder create(RelativeLayout rootView) {  
       ImageView imageView = (ImageView) rootView.findViewById(R.id.imageView);  
       TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);  
       TextView textViewEmail = (TextView) rootView.findViewById(R.id.textViewEmail);  
       return new ViewHolder(rootView, imageView, textViewName, textViewEmail);  
     }  
   }  
 }


JSONParser.java (Copy and Paste this class in your Package): (Same as Previous Post)

 import android.support.annotation.NonNull;  
 import android.util.Log;  
 import com.squareup.okhttp.FormEncodingBuilder;  
 import com.squareup.okhttp.OkHttpClient;  
 import com.squareup.okhttp.Request;  
 import com.squareup.okhttp.RequestBody;  
 import com.squareup.okhttp.Response;  
 import org.json.JSONException;  
 import org.json.JSONObject;  
 import java.io.IOException;  
 /**  
  * @author Pratik Butani  
  */  
 public class JSONParser {  
   /********  
    * URLS  
    *******/  
   private static final String MAIN_URL = "http://pratikbutani.x10.mx/json_data.json";  
   /**  
    * TAGs Defined Here...  
    */  
   public static final String TAG = "TAG";  
   /**  
    * Key to Send  
    */  
   private static final String KEY_USER_ID = "user_id";  
   /**  
    * Response  
    */  
   private static Response response;  
   /**  
    * Get Data From WEB  
    *  
    * @return JSON Object  
    */  
   public static JSONObject getDataFromWeb() {  
     try {  
       OkHttpClient client = new OkHttpClient();  
       Request request = new Request.Builder()  
           .url(MAIN_URL)  
           .build();  
       response = client.newCall(request).execute();  
       return new JSONObject(response.body().string());  
     } catch (@NonNull IOException | JSONException e) {  
       Log.e(TAG, "" + e.getLocalizedMessage());  
     }  
     return null;  
   }  
 }  


activity_main.xml (Same as Previous Post) :

 <?xml version="1.0" encoding="utf-8"?>  
 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:app="http://schemas.android.com/apk/res-auto"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:id="@+id/parentLayout"  
   android:layout_height="match_parent"  
   android:fitsSystemWindows="true"  
   tools:context=".MainActivity">  
   
   <android.support.design.widget.AppBarLayout  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:theme="@style/AppTheme.AppBarOverlay">  
   
     <android.support.v7.widget.Toolbar  
       android:id="@+id/toolbar"  
       android:layout_width="match_parent"  
       android:layout_height="?attr/actionBarSize"  
       android:background="?attr/colorPrimary"  
       app:popupTheme="@style/AppTheme.PopupOverlay" />  
   
   </android.support.design.widget.AppBarLayout>  
   
   <ListView app:layout_behavior="@string/appbar_scrolling_view_behavior"  
     android:id="@+id/listView"  
     android:layout_width="fill_parent"  
     android:layout_height="match_parent" />  
   
   <android.support.design.widget.FloatingActionButton  
     android:id="@+id/fab"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_gravity="bottom|end"  
     android:layout_margin="@dimen/fab_margin"  
     android:src="@android:drawable/stat_sys_download" />  
   
 </android.support.design.widget.CoordinatorLayout>  


MainActivity.java:

(Same as Previous Post, Just Created Custom Adapter so Created Class type ArrayAdapter and ArrayList.)

 import android.app.ProgressDialog;  
 import android.os.AsyncTask;  
 import android.os.Bundle;  
 import android.support.annotation.NonNull;  
 import android.support.annotation.Nullable;  
 import android.support.design.widget.FloatingActionButton;  
 import android.support.design.widget.Snackbar;  
 import android.support.v7.app.AppCompatActivity;  
 import android.support.v7.widget.Toolbar;  
 import android.util.Log;  
 import android.view.Gravity;  
 import android.view.View;  
 import android.widget.AdapterView;  
 import android.widget.ListView;  
 import android.widget.Toast;  
   
 import com.androidbuts.jsonparsing.adapter.MyArrayAdapter;  
 import com.androidbuts.jsonparsing.model.MyDataModel;  
 import com.androidbuts.jsonparsing.parser.JSONParser;  
 import com.androidbuts.jsonparsing.utils.InternetConnection;  
 import com.androidbuts.jsonparsing.utils.Keys;  
   
 import org.json.JSONArray;  
 import org.json.JSONException;  
 import org.json.JSONObject;  
   
 import java.util.ArrayList;  
   
 public class MainActivity extends AppCompatActivity {  
   
   private ListView listView;  
   private ArrayList<MyDataModel> list;  
   private MyArrayAdapter adapter;  
   
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
   
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  
     setSupportActionBar(toolbar);  
   
     /**  
      * Array List for Binding Data from JSON to this List  
      */  
     list = new ArrayList<>();  
     /**  
      * Binding that List to Adapter  
      */  
     adapter = new MyArrayAdapter(this, list);  
   
     /**  
      * Getting List and Setting List Adapter  
      */  
     listView = (ListView) findViewById(R.id.listView);  
     listView.setAdapter(adapter);  
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
       @Override  
       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
         Snackbar.make(findViewById(R.id.parentLayout), list.get(position).getName() + " => " + list.get(position).getPhone(), Snackbar.LENGTH_LONG).show();  
       }  
     });  
   
     /**  
      * Just to know onClick and Printing Hello Toast in Center.  
      */  
     Toast toast = Toast.makeText(getApplicationContext(), "Click on FloatingActionButton to Load JSON", Toast.LENGTH_LONG);  
     toast.setGravity(Gravity.CENTER, 0, 0);  
     toast.show();  
   
     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);  
     fab.setOnClickListener(new View.OnClickListener() {  
       @Override  
       public void onClick(@NonNull View view) {  
   
         /**  
          * Checking Internet Connection  
          */  
         if (InternetConnection.checkConnection(getApplicationContext())) {  
           new GetDataTask().execute();  
         } else {  
           Snackbar.make(view, "Internet Connection Not Available", Snackbar.LENGTH_LONG).show();  
         }  
       }  
     });  
   }  
   
   /**  
    * Creating Get Data Task for Getting Data From Web  
    */  
   class GetDataTask extends AsyncTask<Void, Void, Void> {  
   
     ProgressDialog dialog;  
   
     @Override  
     protected void onPreExecute() {  
       super.onPreExecute();  
       /**  
        * Progress Dialog for User Interaction  
        */  
       dialog = new ProgressDialog(MainActivity.this);  
       dialog.setTitle("Hey Wait Please...");  
       dialog.setMessage("I am getting your JSON");  
       dialog.show();  
     }  
   
     @Nullable  
     @Override  
     protected Void doInBackground(Void... params) {  
   
       /**  
        * Getting JSON Object from Web Using okHttp  
        */  
       JSONObject jsonObject = JSONParser.getDataFromWeb();  
   
       try {  
         /**  
          * Check Whether Its NULL???  
          */  
         if (jsonObject != null) {  
           /**  
            * Check Length...  
            */  
           if(jsonObject.length() > 0) {  
             /**  
              * Getting Array named "contacts" From MAIN Json Object  
              */  
             JSONArray array = jsonObject.getJSONArray(Keys.KEY_CONTACTS);  
   
             /**  
              * Check Length of Array...  
              */  
             int lenArray = array.length();  
             if(lenArray > 0) {  
               for(int jIndex = 0; jIndex < lenArray; jIndex++) {  
   
                 /**  
                  * Creating Every time New Object  
                  * and  
                  * Adding into List  
                  */  
                 MyDataModel model = new MyDataModel();  
   
                 /**  
                  * Getting Inner Object from contacts array...  
                  * and  
                  * From that We will get Name of that Contact  
                  *  
                  */  
                 JSONObject innerObject = array.getJSONObject(jIndex);  
                 String name = innerObject.getString(Keys.KEY_NAME);  
                 String email = innerObject.getString(Keys.KEY_EMAIL);  
                 String image = innerObject.getString(Keys.KEY_PROFILE_PIC);  
   
                 /**  
                  * Getting Object from Object "phone"  
                  */  
                 JSONObject phoneObject = innerObject.getJSONObject(Keys.KEY_PHONE);  
                 String phone = phoneObject.getString(Keys.KEY_MOBILE);  
   
                 model.setName(name);  
                 model.setEmail(email);  
                 model.setPhone(phone);  
                 model.setImage(image);  
   
                 /**  
                  * Adding name and phone concatenation in List...  
                  */  
                 list.add(model);  
               }  
             }  
           }  
         } else {  
   
         }  
       } catch (JSONException je) {  
         Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());  
       }  
       return null;  
     }  
   
     @Override  
     protected void onPostExecute(Void aVoid) {  
       super.onPostExecute(aVoid);  
       dialog.dismiss();  
       /**  
        * Checking if List size if more than zero then  
        * Update ListView  
        */  
       if(list.size() > 0) {  
         adapter.notifyDataSetChanged();  
       } else {  
         Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();  
       }  
     }  
   }  
 }  


Output:




YOU CAN VISIT FOR WHOLE CODE: 

JSONParsingUsingOkHTTP on GitHub

#KeepSharing #KeepLearning #KeepReviewing :)

Thank you.