Kotlin Volley ListView JSON Parser Android Example

kotlin take scrollview screenshot, kotlin generate pdf from view, kotlin take screenshot, kotlin custom camera, kotlin indeterminate horizontal progressbar, kotlin horizontal recyclerview, Kotlin Volley ListView JSON, Kotlin RecyclerView Volley

Welcome to Kotlin Volley ListView JSON Parser Android Example.

We will parse the JSON from URL using volley and then we will show the data in the listview.

Data from the MySQL database server will be in JSON string format.

We will use Listview with image and text to show the data in proper manner.

Volley library will help us to fetch the data from the URL.

First of all, check the following coding lines to see the output.

Fetching the Volley

Make a new project inside the android studio.

Now go to the build.gradle(Module:app) file and add the following lines

implementation 'com.android.volley:volley:1.1.1'
implementation 'com.squareup.picasso:picasso:2.71828'

First line is for the volley. It will allow us to use the volley library in our project.

Second line will integrate the Picasso library in our project.

Picasso will fetch the image from it’s URL withing the fraction of second.

Enabling Internet

To fetch the JSON data from the URL, we need to use the internet.

For this, we need one permission in the AndroidManifest.xml file.

So open up your AndroidManifest.xml file and write the below line in it

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

This permission is usual and not much harmful to user security.

So we do not need to ask for the runtime permission.

Layout File For ListView

Navigate to the app->res->layout directory.

Inside this directory, make a new XML file and give it a name like lv_player.xml

Give the below source code structure to the lv_player.xml file.

<?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="match_parent">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:scaleType="fitXY"
        android:id="@+id/iv"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_marginTop="5dp"
            android:layout_weight="1"
            android:id="@+id/name"
            android:text="ddd"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/country"
            android:text="ddd"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/city"
            android:text="ddd"/>

    </LinearLayout>

</LinearLayout>

Above file is making the layout for the each child row of the listview.

File is containing one image view and three text views.

Data Structure

Now let create a class which will maintain the data structure for the Listview.

Create a new Kotlin file with the name as DataModel.kt

Inside this DataModel.kt file, add some new source lines like the following

class DataModel {

    var name: String? = null
    var country: String? = null
    var city: String? = null
    var imgURL: String? = null

    fun getNames(): String {
        return name.toString()
    }

    fun setNames(name: String) {
        this.name = name
    }

    fun getCountrys(): String {
        return country.toString()
    }

    fun setCountrys(country: String) {
        this.country = country
    }

    fun getCitys(): String {
        return city.toString()
    }

    fun setCitys(city: String) {
        this.city = city
    }

    fun getimgURLs(): String {
        return imgURL.toString()
    }

    fun setimgURLs(imgURL: String) {
        this.imgURL = imgURL
    }

}

Above model file has four string variables : name, country, city and imgURL

For all of these four variables, I have written getter and setter methods.

These methods will save and fetch the data from arraylists.

We will use these methods in the adapter and main activity file.

Adapter of the ListView

Now create a new Kotlin class and give it a name like ListAdapter.kt

You should write the following coding lines into the ListAdapter.kt file.

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.TextView
import com.squareup.picasso.Picasso
import java.util.ArrayList

class ListAdapter(private val context: Context, private val dataModelArrayList: ArrayList<DataModel>) : BaseAdapter() {

    override fun getViewTypeCount(): Int {
        return count
    }

    override fun getItemViewType(position: Int): Int {

        return position
    }

    override fun getCount(): Int {
        return dataModelArrayList.size
    }

    override fun getItem(position: Int): Any {
        return dataModelArrayList[position]
    }

    override fun getItemId(position: Int): Long {
        return 0
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var convertView = convertView
        val holder: ViewHolder

        if (convertView == null) {
            holder = ViewHolder()
            val inflater = context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = inflater.inflate(R.layout.lv_player, null, true)

            holder.iv = convertView!!.findViewById<View>(R.id.iv) as ImageView
            holder.tvname = convertView.findViewById<View>(R.id.name) as TextView
            holder.tvcountry = convertView.findViewById<View>(R.id.country) as TextView
            holder.tvcity = convertView.findViewById<View>(R.id.city) as TextView

            convertView.tag = holder
        } else {
            // the getTag returns the viewHolder object set as a tag to the view
            holder = convertView.tag as ViewHolder
        }

        Picasso.get().load(dataModelArrayList[position].getimgURLs()).into(holder.iv)
        holder.tvname!!.text = "Name: " + dataModelArrayList[position].getNames()
        holder.tvcountry!!.text = "Country: " + dataModelArrayList[position].getCountrys()
        holder.tvcity!!.text = "City: " + dataModelArrayList[position].getCitys()

        return convertView
    }

    private inner class ViewHolder {

         var tvname: TextView? = null
         var tvcountry: TextView? = null
         var tvcity: TextView? = null
        var iv: ImageView? = null
    }

}

This adapter class place the data into each child row of the listview.

See the following line from the getView() method which is in the above code

convertView = inflater.inflate(R.layout.lv_player, null, true)

This line is inflating the lv_player.xml file. So child row of listview will have the layout like lv_player.xml

Now focus on the following coding lines

 Picasso.get().load(dataModelArrayList[position].getimgURLs()).into(holder.iv)
        holder.tvname!!.text = "Name: " + dataModelArrayList[position].getNames()
        holder.tvcountry!!.text = "Country: " + dataModelArrayList[position].getCountrys()
        holder.tvcity!!.text = "City: " + dataModelArrayList[position].getCitys()

First line using the Picasso class. It will help us to fetch the image from the URL.

Second , third and fourth lines will set the text value inside three text views.

Main Files

Inside your activity_main.xml file, add the below line

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
              tools:context=".MainActivity">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Below ListView is populated from JSON Data"
            android:textColor="#000"/>

    <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/lv"
            android:layout_marginTop="10dp">

    </ListView>

</LinearLayout>

Above main layout file have one text view and one listview.

Now write down the code of the below lines inside the MainActivity.kt

import android.app.ProgressDialog
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ListView
import android.widget.Toast
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.VolleyError
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.util.ArrayList

class MainActivity : AppCompatActivity() {

    private val URLstring = "https://demonuts.com/Demonuts/JsonTest/Tennis/json_parsing.php"
    private var listView: ListView? = null
    internal lateinit var dataModelArrayList: ArrayList<DataModel>
    private var listAdapter: ListAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        listView = findViewById(R.id.lv)

        retrieveJSON()

    }

    private fun retrieveJSON() {

        showSimpleProgressDialog(this, "Loading...", "Fetching Json", false)

        val stringRequest = StringRequest(Request.Method.GET, URLstring,
            Response.Listener { response ->
                Log.d("strrrrr", ">>$response")

                try {

                    val obj = JSONObject(response)
                    if (obj.optString("status") == "true") {

                        dataModelArrayList = ArrayList()
                        val dataArray = obj.getJSONArray("data")

                        for (i in 0 until dataArray.length()) {

                            val playerModel = DataModel()
                            val dataobj = dataArray.getJSONObject(i)

                            playerModel.setNames(dataobj.getString("name"))
                            playerModel.setCountrys(dataobj.getString("country"))
                            playerModel.setCitys(dataobj.getString("city"))
                            playerModel.setimgURLs(dataobj.getString("imgURL"))

                            dataModelArrayList.add(playerModel)

                        }

                        setupListview()

                    }

                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            },
            Response.ErrorListener { error ->
                //displaying the error in toast if occurrs
                Toast.makeText(applicationContext, error.message, Toast.LENGTH_SHORT).show()
            })

        // request queue
        val requestQueue = Volley.newRequestQueue(this)

        requestQueue.add(stringRequest)


    }

    private fun setupListview() {
        removeSimpleProgressDialog()  //will remove progress dialog
        listAdapter = ListAdapter(this, dataModelArrayList)
        listView!!.adapter = listAdapter
    }

    companion object {
        private var mProgressDialog: ProgressDialog? = null

        fun removeSimpleProgressDialog() {
            try {
                if (mProgressDialog != null) {
                    if (mProgressDialog!!.isShowing) {
                        mProgressDialog!!.dismiss()
                        mProgressDialog = null
                    }
                }
            } catch (ie: IllegalArgumentException) {
                ie.printStackTrace()

            } catch (re: RuntimeException) {
                re.printStackTrace()
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

        fun showSimpleProgressDialog(
            context: Context, title: String,
            msg: String, isCancelable: Boolean
        ) {
            try {
                if (mProgressDialog == null) {
                    mProgressDialog = ProgressDialog.show(context, title, msg)
                    mProgressDialog!!.setCancelable(isCancelable)
                }

                if (!mProgressDialog!!.isShowing) {
                    mProgressDialog!!.show()
                }

            } catch (ie: IllegalArgumentException) {
                ie.printStackTrace()
            } catch (re: RuntimeException) {
                re.printStackTrace()
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

}

Now focus on the below coding lines

 private val URLstring = "https://demonuts.com/Demonuts/JsonTest/Tennis/json_parsing.php"
    private var listView: ListView? = null
    internal lateinit var dataModelArrayList: ArrayList<DataModel>
    private var listAdapter: ListAdapter? = null

First line defining a variable which holds the URL to the JSON data in the string format.

Second line is defining an object of the ListView class.

Third is the arraylist with the objects of the DataModel class.

Fourth one is the object of the ListAdapter class.

Look at the retrieveJSON() method inside the onCreate() method.

Compiler will first show the loading dialog using the showSimpleProgressDialog() method.

Then after it will make a GET request to the URL to get the JSON data.

After getting the JSON data, compiler will go through one for loop. This loop will create a data source dataModelArrayList

Below is the JSON data which we are getting from the MySQL database.

{
    "status": "true",
    "message": "Data fetched successfully!",
    "data": [
        {
            "id": "1",
            "name": "Roger Federer",
            "country": "Switzerland",
            "city": "Basel",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/roger.jpg"
        },
        {
            "id": "2",
            "name": "Rafael Nadal",
            "country": "Spain",
            "city": "Madrid",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/nadal.jpg"
        },
        {
            "id": "3",
            "name": "Novak Djokovic",
            "country": "Serbia",
            "city": "Monaco",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/djoko.jpg"
        },
        {
            "id": "4",
            "name": "Andy Murray",
            "country": "United Kingdom",
            "city": "London",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/murray.jpg"
        },
        {
            "id": "5",
            "name": "Maria Sharapova",
            "country": "Russia",
            "city": "Moscow",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/shara.jpg"
        },
        {
            "id": "6",
            "name": "Caroline Wozniacki",
            "country": "Denmark",
            "city": "Odense",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/woz.jpg"
        },
        {
            "id": "7",
            "name": "Eugenie Bouchard",
            "country": "Canada",
            "city": " Montreal",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/bou.png"
        },
        {
            "id": "8",
            "name": "Ana Ivanovic",
            "country": "Serbia",
            "city": "Belgrade",
            "imgURL": "https://demonuts.com/Demonuts/SampleImages/iva.jpg"
        }
    ]
}

setupListview() method will create the adapter using the data source dataModelArrayList

Then after it will attach the adapter to the listview.

Github Code For Download

Download Code with this link