Android Native JSON : ListView Master Detail – Download,Parse,Show

Android Native JSON : ListView Master Detail – Download,Parse,Show







Here in this tutorial,we talk JSON and ListView.We download JSON data from online here : http://jsonplaceholder.typicode.com/ 

This json data we parse natively using org.json classes : JSONArray and JSONObject,no third party library.We then bind this data to our Custom ListView.This,our MainActivity, acts as our Master View. When a ListView item is clicked, we open detail activity passing data.

Cheer.

JSON

Introduction

  • Stands for JavaScript Object Notation.
  • Is a data exchange format that is both light and easy for humans to read and write.
  • Based on a subset of JavaScript Programming language
  • Is text format that’s completely language independent and uses conventions familiar with C-family programming languages.

Structure

  • Can exist as a Collection of name/value pairs.

Each pair translates to Object, struct, dictionary, record, hashtable or associative array. Obviously this depends on the programming language at use.

  • Can also exist as an ordered list of values.

Then this corresponds to an array, vector, list, or sequence.

JSONObject and JSONArray

  • JSONObject – Is an unordered set of name/value pairs.

Typically surrounded with braces i.e.” { }”.

Each name is then followed by a colon i.e. “:”.

Then value of course.

However, name/value pairs are separated by comma.

  • JSONArray – Is an ordered collection of values.

Typically begins with “[“and ends with “]” just as a normal array.

Values are separated by comma.

A value can be String, number, Boolean, null, Object, or an array.

 

 

Section 1 : Our Build.Gradle

apply plugin: 'com.android.application'
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "com.tutorials.hp.jsonlistviewmdetail"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.android.support:design:24.0.0'
    compile 'com.android.support:cardview-v7:24.0.0'
}

Section 2 : AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorials.hp.jsonlistviewmdetail">
    <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:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".DetailActivity"></activity>
    </application>
</manifest>

Section 3 : Our Model Class

package com.tutorials.hp.jsonlistviewmdetail.m_Model;
/**
 * Created by Oclemy on 7/8/2016 for ProgrammingWizards Channel and http://www.camposha.com.
 */
public class User {
    String username,name,email;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

Section 4 : Our Connector Class

package com.tutorials.hp.jsonlistviewmdetail.m_JSON;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
 * Created by Oclemy on 7/7/2016 for ProgrammingWizards Channel and http://www.camposha.com.
 * -------------------ROLES-----------------------
 * 1.SET CONNECTION PROPRTIES
 * 2.ESTABLISH AND RETURN CONNECTION OBJ
 */
public class Connector {
    public static Object connect(String jsonURL)
    {
        try
        {
            URL url=new URL(jsonURL);
            HttpURLConnection con= (HttpURLConnection) url.openConnection();
            //CON PROPS
            con.setRequestMethod("GET");
            con.setConnectTimeout(15000);
            con.setReadTimeout(15000);
            con.setDoInput(true);
            return con;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return "Error "+e.getMessage();
        } catch (IOException e) {
            e.printStackTrace();
            return "Error "+e.getMessage();
        }
    }
}

Section 5 :JSON Downloader Class

package com.tutorials.hp.jsonlistviewmdetail.m_JSON;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
/**
 * Created by Oclemy on 7/7/2016 for ProgrammingWizards Channel and http://www.camposha.com.
 * -----------------------ROLES-------------------------
 * 1.CONNECT TO NETWORK
 * 2.DOWNLOAD DATA IN BACKGROUND THREAD
 * 3.SEND THE DATA TO PARSER TO BE PARSED
 */
public class JSONDownloader extends AsyncTask<Void,Void,String> {
    Context c;
    String jsonURL;
    ListView lv;
    ProgressDialog pd;
    public JSONDownloader(Context c, String jsonURL, ListView lv) {
        this.c = c;
        this.jsonURL = jsonURL;
        this.lv = lv;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Download JSON");
        pd.setMessage("Downloading...Please wait");
        pd.show();
    }
    @Override
    protected String doInBackground(Void... voids) {
        return download();
    }
    @Override
    protected void onPostExecute(String jsonData) {
        super.onPostExecute(jsonData);
        pd.dismiss();
        if(jsonData.startsWith("Error"))
        {
            String error=jsonData;
            Toast.makeText(c, error, Toast.LENGTH_SHORT).show();
        }else
        {
            //PARSER
            new JSONParser(c,jsonData, lv).execute();
        }
    }
    //DOWNLOAD
    private String download()
    {
        Object connection=Connector.connect(jsonURL);
        if(connection.toString().startsWith("Error"))
        {
            return connection.toString();
        }
        try
        {
            HttpURLConnection con= (HttpURLConnection) connection;
            if(con.getResponseCode()==con.HTTP_OK)
            {
                //GET INPUT FROM STREAM
                InputStream is=new BufferedInputStream(con.getInputStream());
                BufferedReader br=new BufferedReader(new InputStreamReader(is));
                String line;
                StringBuffer jsonData=new StringBuffer();
                //READ
                while ((line=br.readLine()) != null)
                {
                    jsonData.append(line+"n");
                }
                //CLOSE RESOURCES
                br.close();
                is.close();
                //RETURN JSON
                return jsonData.toString();
            }else
            {
                return "Error "+con.getResponseMessage();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "Error "+e.getMessage();
        }
    }
}

Section 6 :JSON Parser Class

 

package com.tutorials.hp.jsonlistviewmdetail.m_JSON;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.Toast;
import com.tutorials.hp.jsonlistviewmdetail.m_Model.User;
import com.tutorials.hp.jsonlistviewmdetail.m_UI.CustomAdapter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
 * Created by Oclemy on 7/7/2016 for ProgrammingWizards Channel and http://www.camposha.com.
 * -----------------    ROLES -----------------------
 * 1.RECEIVE DOWNLOADED DATA
 * 2.PARSE IT
 * 3.CALL ADAPTER CLASS TO BIND IT TO CUSTOM gridview
 */
public class JSONParser extends AsyncTask<Void,Void,Boolean>{
    Context c;
    String jsonData;
    ListView lv;
    ProgressDialog pd;
    ArrayList<User> users=new ArrayList<>();
    public JSONParser(Context c, String jsonData, ListView lv) {
        this.c = c;
        this.jsonData = jsonData;
        this.lv = lv;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Parse");
        pd.setMessage("Parsing...Please wait");
        pd.show();
    }
    @Override
    protected Boolean doInBackground(Void... voids) {
        return parse();
    }
    @Override
    protected void onPostExecute(Boolean isParsed) {
        super.onPostExecute(isParsed);
        pd.dismiss();
        if(isParsed)
        {
            //BIND
            lv.setAdapter(new CustomAdapter(c,users));
        }else
        {
            Toast.makeText(c, "Unable To Parse,Check Your Log output", Toast.LENGTH_SHORT).show();
        }
    }
    private Boolean parse()
    {
        try
        {
            JSONArray ja=new JSONArray(jsonData);
            JSONObject jo;
            users.clear();
            User user;
            for (int i=0;i<ja.length();i++)
            {
                jo=ja.getJSONObject(i);
                String name=jo.getString("name");
                String username=jo.getString("username");
                String email=jo.getString("email");
                user=new User();
                user.setName(name);
                user.setUsername(username);
                user.setEmail(email);
                users.add(user);
            }
            return true;
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        }
    }
}

Section 7 : CustomAdapter Class

package com.tutorials.hp.jsonlistviewmdetail.m_UI;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.tutorials.hp.jsonlistviewmdetail.DetailActivity;
import com.tutorials.hp.jsonlistviewmdetail.R;
import com.tutorials.hp.jsonlistviewmdetail.m_Model.User;
import java.util.ArrayList;
/**
 * Created by Oclemy on 7/15/2016 for ProgrammingWizards Channel and http://www.camposha.com.
 */
public class CustomAdapter  extends BaseAdapter{
    Context c;
    ArrayList<User> users;
    public CustomAdapter(Context c, ArrayList<User> users) {
        this.c = c;
        this.users = users;
    }
    @Override
    public int getCount() {
        return users.size();
    }
    @Override
    public Object getItem(int i) {
        return users.get(i);
    }
    @Override
    public long getItemId(int i) {
        return i;
    }
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        if(view==null)
        {
            view=LayoutInflater.from(c).inflate(R.layout.model,viewGroup,false);
        }
        TextView nameTxt= (TextView) view.findViewById(R.id.nameTxt);
        TextView emailTxt= (TextView) view.findViewById(R.id.emailTxt);
        TextView usernameTxt= (TextView) view.findViewById(R.id.usernameTxt);
        User user= (User) this.getItem(i);
        final String name=user.getName();
        final String email=user.getEmail();
        final String username=user.getUsername();
        nameTxt.setText(name);
        emailTxt.setText(email);
        usernameTxt.setText(username);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //OPEN DETAIL ACTIVITY
               openDetailActivity(name,email,username);
            }
        });
        return view;
    }
    ////open activity
    private void openDetailActivity(String...details)
    {
        Intent i=new Intent(c,DetailActivity.class);
        i.putExtra("NAME_KEY",details[0]);
        i.putExtra("EMAIL_KEY",details[1]);
        i.putExtra("USERNAME_KEY",details[2]);
        c.startActivity(i);
    }
}

Section 8 : Detail Activity Class

package com.tutorials.hp.jsonlistviewmdetail;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class DetailActivity extends AppCompatActivity {
    TextView nameTxt,emailTxt, usernameTxt;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        nameTxt = (TextView) findViewById(R.id.nameDetailTxt);
        emailTxt= (TextView) findViewById(R.id.emailDetailTxt);
        usernameTxt = (TextView) findViewById(R.id.usernameDetailTxt);
        //GET INTENT
        Intent i=this.getIntent();
        //RECEIVE DATA
        String name=i.getExtras().getString("NAME_KEY");
        String email=i.getExtras().getString("EMAIL_KEY");
        String username=i.getExtras().getString("USERNAME_KEY");
        //BIND DATA
        nameTxt.setText(name);
        emailTxt.setText(email);
        usernameTxt.setText(username);
    }
}

Section 9 : MainActivity Class

package com.tutorials.hp.jsonlistviewmdetail;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ListView;
import com.tutorials.hp.jsonlistviewmdetail.m_JSON.JSONDownloader;
public class MainActivity extends AppCompatActivity {
    String jsonURL="http://jsonplaceholder.typicode.com/users";
    ListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        lv = (ListView) findViewById(R.id.lv);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new JSONDownloader(MainActivity.this,jsonURL, lv).execute();
            }
        });
    }
}

Section 10 : Layouts

ContentMain.xml

 

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.jsonlistviewmdetail.MainActivity"
    tools:showIn="@layout/activity_main">
    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         />
</RelativeLayout>

 

Model.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_margin="10dp"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="5dp"
    android:layout_height="200dp">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Name"
                android:id="@+id/nameTxt"
                android:padding="10dp"
                android:textColor="@color/colorAccent"
                android:textStyle="bold"
                android:layout_alignParentLeft="true"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Email....................."
                android:lines="3"
                android:id="@+id/emailTxt"
                android:padding="10dp"
                android:layout_alignParentLeft="true"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Username"
                android:textStyle="italic"
                android:id="@+id/usernameTxt" />
    </LinearLayout>
</android.support.v7.widget.CardView>

ActivityDetail.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="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.tutorials.hp.jsonlistviewmdetail.DetailActivity">
    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal" android:layout_width="match_parent"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_margin="5dp"
        card_view:cardCornerRadius="10dp"
        card_view:cardElevation="5dp"
        android:layout_height="match_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:weightSum="1">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <ImageView
                    android:id="@+id/articleDetailImg"
                    android:layout_width="160dp"
                    android:layout_height="wrap_content"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    android:layout_alignParentTop="true"
                    android:scaleType="centerCrop"
                    android:src="@drawable/user" />
                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <TextView
                        android:id="@+id/nameDetailTxt"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textAppearance="?android:attr/textAppearanceLarge"
                        android:padding="5dp"
                        android:minLines="1"
                        android:textStyle="bold"
                        android:textColor="@color/colorAccent"
                        android:text="Title" />
                    <TextView
                        android:id="@+id/usernameDetailTxt"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textAppearance="?android:attr/textAppearanceLarge"
                        android:padding="5dp"
                        android:minLines="1"
                        android:textStyle="bold"
                        android:text="Username" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="?attr/actionBarSize"
                android:orientation="vertical"
                android:paddingLeft="5dp"
                android:paddingRight="5dp"
                android:paddingTop="5dp">
                <TextView
                    android:id="@+id/emailDetailTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:padding="5dp"
                    android:textColor="@color/colorAccent"
                    android:text="DATE" />
                <TextView
                    android:id="@+id/descDetailTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:padding="5dp"
                    android:textColor="#0f0f0f"
                    android:minLines="4"
                    android:text="This user has worked with our company for two years now.He has been dedicated and really a team player.The tasks we have assigned him have been executed expertly.He is a true professional..." />
                <TextView
                    android:id="@+id/linkDetailTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:padding="5dp"
                    android:textColor="@color/colorPrimaryDark"
                    android:textStyle="italic"
                    android:text="Link" />
            </LinearLayout>
        </LinearLayout>
    </android.support.v7.widget.CardView>
</RelativeLayout>

Section 11 : Our Result

Detail Page and Passed DataMaster View With Custom ListView

 



    COMMENTS