简体   繁体   中英

Display JSON value in Recycler View using Kotlin

I am trying to display items in bottom navigation activity using recycler view I am able to display the items but I am not able display the values in the activity using JSON format. I am using OKHTTP method. The code is working before JSON code. I am using kotlin in my development.

[{"name":"Test1","age":"10"},{"name":"Test2","location":"20"}]

I have three layouts in my project activity_main.xml, list_row.xml and fragment_home.xml. Recycler view is in fragment_home.xml and list_row.xml contains two text views.

Below code is working fine but I am not sure how to add the JSON value into the code for display. I tried below code and if any one have easiest way to do it then let me know. Any help is appreciated.

HomeFragment.kt

class HomeFragment : Fragment() {

    private var adapter:PersonListAdapter?=null
    private var personList:ArrayList<Person>?=null
    private var layoutManager: RecyclerView.LayoutManager?=null


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_home, container, false)
        val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)

        personList=ArrayList<Person>()
        layoutManager= LinearLayoutManager(this.context)
        adapter= PersonListAdapter(personList,this.context!!)

        recyclerView.layoutManager=layoutManager
        recyclerView.adapter=adapter
        for (i in 0..16) {
            val person = Person()
            person.name="Hello" + i
            person.age = 20 + i
            personList!!.add(person)

        }
        adapter!!.notifyDataSetChanged()
fetchJSON()
return view

    }

JSON Code:

    private fun fetchJSON()
    {
        val SchoolDetailUrl="https://www.abc.app/"
        println("School URL: $SchoolDetailUrl")
        val request= Request.Builder().url(SchoolsDetailUrl).build()
        val client= OkHttpClient()

        client.newCall(request).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                val body=response?.body()?.string()

                val gson=GsonBuilder().create()

                val Schoollist=gson.fromJson(body,Array<Person>::class.java)

             //       recyclerView.adapter=PersonDetailAdapter(Schoollist)

                println("Testing School Detail $body")
            }
            override fun onFailure(call: Call, e: IOException) {
                println("Failed to Execute the Request")
            }
        })
    }

}

PersonListAdapter:

class PersonListAdapter(private val list: ArrayList<Person>,
                        private val context: Context)
    : RecyclerView.Adapter<PersonListAdapter.ViewHolder>() {
    override fun getItemCount(): Int {
        return list.size

    }

    override fun onCreateViewHolder(parent: ViewGroup?, position: Int): ViewHolder {
                   val view = LayoutInflater.from(context).inflate(R.layout.list_row, parent, false)

        return ViewHolder(view)


    }

    override fun onBindViewHolder(holder: ViewHolder?, position: Int) {

        holder?.bindItem(list[position])


    }


     inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
         fun bindItem(person: Person) {
             var name: TextView = itemView.findViewById(R.id.name) as TextView
             var age: TextView = itemView.findViewById(R.id.age) as TextView

             name.text = person.name
             age.text = person.age.toString()



             itemView.setOnClickListener {


                 Toast.makeText(context, name.text, Toast.LENGTH_LONG ).show()
             }

         }

    }


}

So What you need is to call the person details API for each click on the person item. Currently the

PersonListAdapter(psersonList: ArrayList<Person>,context Context)

has 2 arguments change that to pass another argument the `fetchJson` Function itself

PersonListAdapter(context Context,psersonList: ArrayList<Person>, fetchJson: (string) -> Unit)

In the fetch JSON I think another view is shown with person details that you have to do,

NOTE: Normally the context will be the first argument and also In the fetchJSON function if you inflate another view that contains the details then change the function name to some meaning full one like ShowDetails()

You code has some problems, but your main one is the way your Adapter uses data.

    personList=ArrayList<Person>()
    adapter= PersonListAdapter(personList,this.context!!)
    [...]
    adapter!!.notifyDataSetChanged()

When you're adding items to the list:

for (i in 0..16) {
    val person = Person()
    person.name="Hello" + i
    person.age = 20 + i
    personList!!.add(person)
}

What you're actually doing is adding to the local list personList , not to private val list: ArrayList<Person> of you're adapter. That's why you get no data to display.

Instead you should add methods like add(person: Person) to your adapter, and let it add to its private val list instead. Keep the data in the Adapter, not your view ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM