0

I am new in kotlin and retrofit, when I run this app it shows nothing in my device. But I check the logcat and found this errorNo adapter attached; skipping layout.Sometimes ago I post this question, some people answer this but this answer not correct

CountryActivity.kt

var recyclerView: RecyclerView = findViewById(R.id.countryRecyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)

var apiInterface: CountryDataInterface = 
CountryApiClient.getApiClient()!!.create(CountryDataInterface::class.java)
apiInterface.getCountryData().enqueue(object : Callback<List<Country>> {
override fun onFailure(call: Call<List<Country>>, t: Throwable) {}

override fun onResponse(call: Call<List<Country>>, response: Response<List<Country>>) {
val countryData = response.body()!!
recyclerView.adapter = CountryDataAdapter(countryData)

CountryDataAdapter.kt

class CountryDataAdapter(var countryDataList: List<Country>?):
RecyclerView.Adapter<CountryDataAdapter.RecyclerViewHolder>() {
class RecyclerViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
var countryName: TextView = itemView.findViewById(R.id.countryName)
var casesTotal: TextView = itemView.findViewById(R.id.casesTotal)
var casesToday: TextView = itemView.findViewById(R.id.casesToday)
var deathTotal: TextView = itemView.findViewById(R.id.deathTotal)
var deathToday: TextView = itemView.findViewById(R.id.deathToday)
var recoveredAll: TextView = itemView.findViewById(R.id.recoveredAll)
var activeAll: TextView = itemView.findViewById(R.id.activeAll)
var criticalAll: TextView = itemView.findViewById(R.id.criticalAll)

fun bindData(countryDataList: List<Country>?, position: Int){
    countryName.text = countryDataList!!.get(position).countryName.toString()
    casesTotal.text = countryDataList!!.get(position).cases.toString()
    casesToday.text = countryDataList!!.get(position).todayCases.toString()
    deathTotal.text = countryDataList!!.get(position).deathTotal.toString()
    deathToday.text = countryDataList!!.get(position).deathToday.toString()
    recoveredAll.text = countryDataList!!.get(position).recovered.toString()
    activeAll.text = countryDataList!!.get(position).activePatient.toString()
    criticalAll.text = countryDataList!!.get(position).critical.toString()
  }
 }

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
var view: View = LayoutInflater.from(parent!!.context).inflate(R.layout.country_row,parent,false)
return RecyclerViewHolder(view)
}

override fun getItemCount(): Int {
return countryDataList!!.size
}
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
holder.bindData(countryDataList,position)
}
}
user10997009
  • 142
  • 8

1 Answers1

1

I think your issue is because you're calling recyclerView.adapter = CountryDataAdapter(countryData) in your Async function.

From what your post shows

override fun onResponse(call: Call<List<Country>>, response: Response<List<Country>>) {
val countryData = response.body()!!
recyclerView.adapter = CountryDataAdapter(countryData)

recyclerView.adapter = CountryDataAdapter(countryData) is in onResponse which is async, when your activity lunch, your adapter isn't set as it waits the result from the network to set it.

It would be better to set it to:

  1. At the beginning of your activity add var countryData: List<Country> = ArrayList()

EDIT after checking Repo:

You get nothing because your call is getting into onFailure. You should add log to see this kind of things.

CountryActivity:

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

        val recyclerView: RecyclerView = findViewById(R.id.cRecyclerView)
        var countryData: List<Country> = ArrayList()
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setHasFixedSize(true)
        recyclerView.adapter = CountryDataAdapter(countryData)
       // recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))

        val apiInterface: CountryDataInterface = CountryApiClient.getApiClient()!!.create(CountryDataInterface::class.java)
        apiInterface.getCountryData().enqueue(object : Callback<List<Country>> {
            override fun onFailure(call: Call<List<Country>>, t: Throwable) {

                val data = Country(1, 2,3,4,5,6,7,8)
                countryData = listOf(data)
                recyclerView.adapter = CountryDataAdapter(countryData)

                Log.d("onFailure", "ERROR")
            }

            override fun onResponse(call: Call<List<Country>>, response: Response<List<Country>>) {
                if (response.isSuccessful) {
                    countryData = response.body()!!
                    recyclerView.adapter = CountryDataAdapter(countryData)
                }
            }

        })

    }

Adapter:

class CountryDataAdapter(private var countryDataList: List<Country>):
    RecyclerView.Adapter<CountryDataAdapter.RecyclerViewHolder>() {
    class RecyclerViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
        val countryName: TextView = itemView.findViewById(R.id.countryName)
        val casesTotal: TextView = itemView.findViewById(R.id.casesTotal)
        val casesToday: TextView = itemView.findViewById(R.id.casesToday)
        val deathTotal: TextView = itemView.findViewById(R.id.deathTotal)
        val deathToday: TextView = itemView.findViewById(R.id.deathToday)
        val recoveredAll: TextView = itemView.findViewById(R.id.recoveredAll)
        val activeAll: TextView = itemView.findViewById(R.id.activeAll)
        val criticalAll: TextView = itemView.findViewById(R.id.criticalAll)

        fun bindData(countryDataList: List<Country>, position: Int){
            val item = countryDataList[position]
            countryName.text = item.countryName.toString()
            casesTotal.text = item.cases.toString()
            casesToday.text = item.todayCases.toString()
            deathTotal.text = item.deathTotal.toString()
            deathToday.text = item.deathToday.toString()
            recoveredAll.text = item.recovered.toString()
            activeAll.text = item.activePatient.toString()
            criticalAll.text = item.critical.toString()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val view: View = LayoutInflater.from(parent.context).inflate(R.layout.country_row,parent,false)
        return RecyclerViewHolder(view)
    }

    override fun getItemCount(): Int {
        return countryDataList.size
    }

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        holder.bindData(countryDataList,position)
    }
}
Biscuit
  • 4,840
  • 4
  • 26
  • 54
  • I follow your suggestion but it's show new error the error is kotlin.KotlinNullPointerException at com.atc.awarenessforthecorona.adapter.CountryDataAdapter.getItemCount(CountryDataAdapter.kt:41) – user10997009 Mar 23 '20 at 16:23
  • Yeah that's because you used `!!` everywhere you should use `?` instead, you don't need it at all for in your Adapter. When you use `!!` if the var you call is null it'll cause a crash of your app – Biscuit Mar 23 '20 at 16:38
  • Any crash ? or logcat? or github repo that I can check ? – Biscuit Mar 23 '20 at 17:10
  • same error No adapter attached; skipping layout and the repo link https://github.com/diptoroy/AwarenessForTheCoronaV1.0 – user10997009 Mar 23 '20 at 17:27
  • My post is updated. You should fix your call and it'll work ;) – Biscuit Mar 23 '20 at 17:42
  • Can you check this please,again i am facing this error,but this one i am working with java and volley.hope you will check this,thank u @Biscuit https://stackoverflow.com/questions/60957032/i-am-facing-no-adapter-attached-skipping-layout-error – user10997009 Apr 01 '20 at 05:04