Today, you will learn about Kotlin RecyclerView Volley JSON Parser Android Example
This tutorial will parse the JSON using the Volley library and then it will show this JSON data into the Recycler View.
Our JSON data is stored in the MySQL database and we will use URL to fetch the JSON data from PHP-MySQL server.
First of all, watch the following video as the output presentation for kotlin recyclerview volley example.
You can read all the below steps to create example like the above video.
Writing Gradle
Open your android studio and make a new project with “Kotlin” source language.
Now go to the build.gradle(Module:app) file and add the below lines in it
implementation 'com.android.volley:volley:1.1.1' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support:cardview-v7:28.0.0'
First line is integrating the Volley library in our project.
Second is for Picasso library which will reduce our task of fetching the image from the URL.
Last two lines are giving us the access to the recyclerview and cardview.
Internet Access
Internet is must if you want to fetch the JSON data from the remote server.
So open up your AndroidManifest.xml file and give it a below line
<uses-permission android:name="android.permission.INTERNET" />
This permission is normal so we do need to ask for the runtime permission.
Special Layout
To create the view structure of every child row of the recycler view, we need to have one XML layout file.
So navigate to the app->res->layout directory and make a new file called rv_one.xml
Inside this rv_one.xml file, you need to add the following coding snippet
<?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" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" app:cardCornerRadius="5dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/iv" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:scaleType="fitXY" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="100dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:orientation="vertical"> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_marginTop="5dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> <TextView android:id="@+id/country" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> <TextView android:id="@+id/city" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="ddd" android:textColor="#000" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout>
You can see that above file have one image view and three text views.
All of these widgets are the children of the <cardview> tag.
Thus, each row of the recyclerview will have the cardview background.
Model For Recyclerview
Now for data maintenance in the Recycler view, we need one specific class.
So create a new Kotlin class and set it’s name as the DataModel.kt
DataModel.kt file should have the following source coding lines
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 } }
I have added four variables inside the above model class : name, country, city and imgURL.
You can see that there are getter and setter methods for all the four variables.
These getter and setter methods will help us to maintain the data while filling the Recycler view in the Adapter class.
Our Adapter File
Let us make an adapter which will fetch the data from the Main Activity file and will populate the Recycler view.
Make a new Kotlin file called RvAdapter.kt and write the following coding lines in it
import android.content.Context 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.squareup.picasso.Picasso import java.util.ArrayList class RvAdapter(ctx: Context, private val dataModelArrayList: ArrayList<DataModel>) : RecyclerView.Adapter<RvAdapter.MyViewHolder>() { private val inflater: LayoutInflater init { inflater = LayoutInflater.from(ctx) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvAdapter.MyViewHolder { val view = inflater.inflate(R.layout.rv_one, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: RvAdapter.MyViewHolder, position: Int) { Picasso.get().load(dataModelArrayList[position].getimgURLs()).into(holder.iv) holder.name.setText(dataModelArrayList[position].getNames()) holder.country.setText(dataModelArrayList[position].getCountrys()) holder.city.setText(dataModelArrayList[position].getCitys()) } override fun getItemCount(): Int { return dataModelArrayList.size } inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { var country: TextView var name: TextView var city: TextView var iv: ImageView init { country = itemView.findViewById<View>(R.id.country) as TextView name = itemView.findViewById<View>(R.id.name) as TextView city = itemView.findViewById<View>(R.id.city) as TextView iv = itemView.findViewById<View>(R.id.iv) as ImageView } } }
Look at the onCreateViewHolder() method from the above code snippet.
Inside this method, compiler will inflate the rv_one.xml file so that it can develop layout of each row of recycler view.
Now get your eye on the onBindViewHolder() method.
Inside this method, compiler will first use the Picasso class to fetch the image from the URL.
Then after, it will set the values in the text view using the data source – dataModelArrayList ( we will create this array list in the main activity kotlin file)
Final Coding
Now open up your main XML layout file : activity_main.xml
You need to add the following coding lines in this activity_main.xml file.
<?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" android:background="#cd15e6" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Below RecyclerView is populated from JSON Data Volley" android:textColor="#fff" android:textStyle="bold" /> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_marginTop="15dp"/> </LinearLayout>
Above file have only one text view and one Recycler view as a widgets.
Your MainActivity.kt file should contain the following coding source snippet
import android.app.ProgressDialog import android.content.Context import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.util.Log 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" internal lateinit var dataModelArrayList: ArrayList<DataModel> private var rvAdapter: RvAdapter? = null private var recyclerView: RecyclerView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) recyclerView = findViewById(R.id.recycler) fetchingJSON() } private fun fetchingJSON() { showSimpleProgressDialog(this, "Loading...", "Fetching Json", false) val stringRequest = StringRequest(Request.Method.GET, URLstring, Response.Listener { response -> Log.d("strrrrr", ">>$response") try { removeSimpleProgressDialog() 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) } setupRecycler() } } 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 setupRecycler() { rvAdapter = RvAdapter(this, dataModelArrayList) recyclerView!!.adapter = rvAdapter recyclerView!!.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false) } 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() } } } }
More Information in Main Kotlin
First of all, focus on the following code lines
private val URLstring = "https://demonuts.com/Demonuts/JsonTest/Tennis/json_parsing.php" internal lateinit var dataModelArrayList: ArrayList<DataModel> private var rvAdapter: RvAdapter? = null private var recyclerView: RecyclerView? = null
First line is the URL to the JSON file. This URL will return the JSON data into the string format.
Second line is creating the array list which will have the objects of the DataModel class.
This array list (dataModelArrayList) will work as the data source in our example.
Now third line is making the object of the RvAdapter class and last one is the object of the Recycler view.
Inside the onCreate() method, there is another method called fetchingJSON()
This fetchingJSON() method will first make GET request to the URL.
After getting the JSON response, compiler will make one for loop, which will fill the data source – dataModelArrayList
We will get the below JSON response, which for loop is using to generate dataModelArrayList
{ "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" } ] }
After for loop, compiler will call the setupRecycler() method.
This setupRecycler() method will bind the adapter objet to the Recycler View.
So this is the end of our Kotlin RecyclerView Volley tutorial.
For creating List View with Volley, you should refer :https://demonuts.com/kotlin-volley-listview-json/