【问题标题】:No adapter attached;recycler view skipping layout [duplicate]未连接适配器;回收器视图跳过布局[重复]
【发布时间】:2021-06-17 16:34:18
【问题描述】:

所以我在Recyclerview 中遇到错误。

activity_main.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"
tools:context=".MainActivity">

<!--edit text for entering the pin code-->
<EditText
android:id="@+id/idEdtPinCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_toStartOf="@id/idBtnSearch"
android:layout_toLeftOf="@id/idBtnSearch"
android:hint="Enter PinCode"
android:inputType="number" />

<!--button for searchng the data-->
<Button
android:id="@+id/idBtnSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="5dp"
android:background="@color/Purple_200"
android:text="Search"
android:textAllCaps="false" />

<!--progress bar for loading indicator-->
<ProgressBar
android:id="@+id/idPBLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />

<!--recycler view for displaying results in the form of list-->
<androidx.recyclerview.widget.RecyclerView
 android:id="@+id/sessionsRV"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_below="@id/idEdtPinCode"
  tools:listitem="@layout/center_rv_item" />



</RelativeLayout>

CenterRvmodel.kt

so this is my `CenterRvmodel`.kt file

package com.gtappdevelopers.finalvaac

data class CenterRvModel (
val sessionsName: String,

val sessionsAddress: String,

// string variable for center opening time.
val sessionsFromTime: String,

// string variable for center closing time.
val sessionsToTime: String,
var fee_type: String,

var ageLimit: Int,
var vaccineName: String,
var availableCapacity: Int)

center_rv_item.xml 所以这是我的 center_rv_item 用于 lising recyclerview

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--text view for displaying center name-->
    <TextView
        android:id="@+id/idTVCenterName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:drawableLeft="@drawable/ic_hospital"
        android:drawablePadding="4dp"
        android:padding="3dp"
        android:text="Center Name"
        android:textColor="@color/black" />

    <!--text view for displaying center address-->
    <TextView
        android:id="@+id/idTVCenterAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/idTVCenterName"
        android:layout_margin="3dp"
        android:drawableLeft="@drawable/ic_location"
        android:drawablePadding="4dp"
        android:padding="3dp"
        android:text="Center Address"
        android:textColor="@color/black" />

    <!--text view for displaying center timings-->
    <TextView
        android:id="@+id/idTVCenterTimings"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/idTVCenterAddress"
        android:layout_margin="3dp"
        android:drawableLeft="@drawable/ic_time"
        android:drawablePadding="4dp"
        android:padding="3dp"
        android:text="Timings"
        android:textColor="@color/black" />

    <LinearLayout
        android:id="@+id/idLL1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/idTVCenterTimings"
        android:orientation="horizontal"
        android:weightSum="2">

        <!--text view for displaying vaccine name-->
        <TextView
            android:id="@+id/idTVVaccineName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:layout_weight="1"
            android:drawableLeft="@drawable/ic_vaccine"
            android:drawablePadding="4dp"
            android:padding="3dp"
            android:text="Vaccine Name"
            android:textColor="@color/black" />

        <!--text view for displaying center fees type-->
        <TextView
            android:id="@+id/idTVFeeType"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="3dp"
            android:layout_weight="1"
            android:padding="3dp"
            android:text="Fee Type"
            android:textAlignment="center"
            android:textColor="@color/black" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/idLL2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/idLL1"
        android:orientation="horizontal"
        android:weightSum="2">

        <!--text view for displaying age limit-->
        <TextView
            android:id="@+id/idTVAgeLimit"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="3dp"
            android:layout_weight="1"
            android:padding="3dp"
            android:text="Age Limit"
            android:textAlignment="center"
            android:textColor="@color/black" />


        <!--text view for displaying center availability-->
        <TextView
            android:id="@+id/idTVAvaliablity"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="3dp"
            android:layout_weight="1"
            android:padding="3dp"
            android:text="Avaliablity"
            android:textAlignment="center"
            android:textColor="@color/black" />


    </LinearLayout>

</RelativeLayout>


</androidx.cardview.widget.CardView>

CenterRvAdapter.kt

package com.gtappdevelopers.finalvaac
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.recyclerview.widget.RecyclerView

// on below line we are creating our adapter class
// in this class we are passing our array list
// and our View Holder class which we have created.
class CenterRvAdapter(private val firebaseKotlinVersion:List 
<CenterRvModel>):RecyclerView.Adapter<CenterRvAdapter.CenterRVViewHolder>() {
class CenterRVViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val centerNameTV: TextView = itemView.findViewById(R.id.idTVCenterName)
    val centerAddressTV: TextView = itemView.findViewById(R.id.idTVCenterAddress)
    val centerTimings: TextView = itemView.findViewById(R.id.idTVCenterTimings)
    val vaccineNameTV: TextView = itemView.findViewById(R.id.idTVVaccineName)
    val centerAgeLimitTV: TextView = itemView.findViewById(R.id.idTVAgeLimit)
    val centerFeeTypeTV: TextView = itemView.findViewById(R.id.idTVFeeType)
    val avalabilityTV: TextView = itemView.findViewById(R.id.idTVAvaliablity)

}

// below method is for on Create Vew Holder.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CenterRVViewHolder {
    // this method is use to inflate the layout file
    // which we have created for our recycler view.
    // on below line we are inflating our layout file.
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.center_rv_item, 
   parent, false)
    

    // at last we are returning our view holder
    // class with our item View File.
    return CenterRVViewHolder(itemView)

}

// this method is to count the size of our array list.


// below method is to set the data to each view of our recycler view item.
override fun onBindViewHolder(holder:CenterRVViewHolder, position: Int) {

    // on below line we are getting item
    // from our list along with its position.
    val currentItem = firebaseKotlinVersion[position]

    // after getting current item we are setting
    // data from our list to our text views.
    holder.centerNameTV.text = currentItem.sessionsName
    holder.centerAddressTV.text = currentItem.sessionsAddress
    holder.centerTimings.text = ("From :" + currentItem.sessionsFromTime + " To : " + 
   currentItem.sessionsToTime)
    holder.vaccineNameTV.text = currentItem.vaccineName
    holder.centerAgeLimitTV.text = "Age Limit :" + currentItem.ageLimit.toString()
    holder.centerFeeTypeTV.text = currentItem.fee_type
    holder.avalabilityTV.text = "Availability :" + currentItem.availableCapacity.toString()

}
override fun getItemCount(): Int {

    // on below line we are returning
    // the size of our array list.
    return firebaseKotlinVersion.size
 }
}

mainactivity.kt

package com.gtappdevelopers.finalvaac
import android.app.DatePickerDialog
 import android.os.Bundle
 import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
 import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import org.json.JSONException
 import java.util.*
import kotlin.collections.ArrayList


class MainActivity : AppCompatActivity() {

// creating a variable for our button.
 lateinit var searchButton: Button

// creating variable for our edit text.
lateinit var pinCodeEdt: EditText

// creating a variable for our recycler view.
lateinit var sessionsRV: RecyclerView

// creating a variable for adapter class.
lateinit var CenterRvAdapter: CenterRvAdapter

// creating a variable for our list
lateinit var centerList: List<CenterRvModel>

// creating a variable for progress bar.
 lateinit var loadingPB: ProgressBar

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

    // inside on create method we are initializing
    // all our variables which we have declared.
    searchButton = findViewById(R.id.idBtnSearch)
    pinCodeEdt = findViewById(R.id.idEdtPinCode)
    sessionsRV = findViewById(R.id.sessionsRV)
    loadingPB = findViewById(R.id.idPBLoading)
    centerList = ArrayList <CenterRvModel>()

    // on below line we are adding on
    // click listener to our button.
    searchButton.setOnClickListener {

        // inside on click listener we are getting data from
        // edit text and creating a val for ite on below line.
        val pinCode = pinCodeEdt.text.toString()

        // on below line we are validating
        // our pin code as 6 digit or not.
         if (pinCode.length != 6) {

            // this method is called when users enter invalid pin code.
            Toast.makeText(this@MainActivity, "Please enter valid pin code", 
    Toast.LENGTH_SHORT).show()
        } else {

            // if the pincode is correct.
            // first of all we are clearing our array list this
            // will clear the data in it if already present.
            (centerList as ArrayList<CenterRvModel>).clear()

            // on below line we are getting instance of our calendar.
            val c = Calendar.getInstance()

            // on below line we are getting our current year, month and day.
            val year = c.get(Calendar.YEAR)
            val month = c.get(Calendar.MONTH)
            val day = c.get(Calendar.DAY_OF_MONTH)

            // on below line we are creating our date picker dialog.
            val dpd = DatePickerDialog(this,
                DatePickerDialog.OnDateSetListener { view, year, monthOfYear, dayOfMonth ->
                    loadingPB.setVisibility(View.VISIBLE)

                    // on below line we are creating a date string for our date
                    val dateStr: String = """$dayOfMonth - ${monthOfYear + 1} - $year"""

                    // on below line we are calling a method to get
                    // the appointment info for vaccination centers
                    // and we are passing our pin code to it.
                    getAppointments(pinCode, dateStr)
                },
                year,
                month,
                day
            )
            // calling a method to display
            // our datepicker dialog.
            dpd.show()
        }
    }
    }

    // below is the method for getting data from API.
    private fun getAppointments(pinCode: String, date: String) {
    val url = "https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByPin? 
   pincode="+pinCode+"&date="+date
    val queue = Volley.newRequestQueue(this@MainActivity)
    val request = JsonObjectRequest(Request.Method.GET, url, null, { response ->
            // this method is called when we get successful response from API.

            // we are setting the visibility of progress bar as gone.
            loadingPB.setVisibility(View.GONE)
            // on below line we are adding a try catch block.
            try {
                // in try block we are creating a variable for center
                // array and getting our array from our object.
                val centerArray = response.getJSONArray("sessions")

                // on below line we are checking if the length of the array is 0.
                // the zero length indicates that there is no data for the given pincode.
                if (centerArray.length().equals(0)) {
                    Toast.makeText(this, "No center Found", Toast.LENGTH_SHORT).show()
                }
                for (i in 0 until centerArray.length()) {

                    // on below line we are creating a variable for our center object.
                    val sessionsObj = centerArray.getJSONObject(0)


                    // on below line we are getting data from our session
                    // object and we are storing that in a different variable.
                    val sessionsName: String = sessionsObj.getString("name")
                    val sessionsAddress: String = sessionsObj.getString("address")
                    val sessionsFromTime: String = sessionsObj.getString("from")
                    val sessionsToTime: String = sessionsObj.getString("to")
                    val fee_type: String = sessionsObj.getString("fee_type")

                    // on below line we are creating a variable for our session object
                    val sessionObj = sessionsObj.getJSONArray("sessions").getJSONObject(0)
                    val ageLimit: Int = sessionObj.getInt("min_age_limit")
                    val vaccineName: String = sessionObj.getString("vaccine")
                    val avaliableCapacity: Int = sessionObj.getInt("available_capacity")

                    // after extracting all the data we are passing this
                    // data to our modal class we have created
                    // a variable for it as center.
                    val center = CenterRvModel(
                        sessionsName,
                        sessionsAddress,
                        sessionsFromTime,
                        sessionsToTime,
                        fee_type,
                        ageLimit,
                        vaccineName,
                        avaliableCapacity
                    )
                    // after that we are passing this modal to our list on the below line.
                    centerList=centerList+center
                }

                // on the below line we are passing this list to our adapter class.
                CenterRvAdapter = CenterRvAdapter(centerList)

                // on the below line we are setting layout manager to our recycler view.
                LinearLayoutManager(this).also { it.also { this.sessionsRV.layoutManager = it 
         } }

                // on the below line we are setting an adapter to our recycler view.
                CenterRvAdapter.also { sessionsRV.adapter = it }

                // on the below line we are notifying our adapter as the data is updated.

                this.CenterRvAdapter.notifyDataSetChanged()
            } catch (e: JSONException) {
                // below line is for handling json exception.
                e.printStackTrace();
            }
        },
            { error ->
                // this method is called when we get any
                // error while fetching data from our API
                Log.e("TAG", "RESPONSE IS $error")
                // in this case we are simply displaying a toast message.
                Toast.makeText(this@MainActivity, "Fail to get response", 
    Toast.LENGTH_SHORT).show()
            })
    // at last we are adding
    // our request to our queue.
    queue.add(request)
 }
}






  

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:
    1. 通过 i 而不是 0

      val sessionsObj = centerArray.getJSONObject(0) val sessionObj = sessionObj.getJSONArray("sessions").getJSONObject(0)

    看起来您将变量名称与实际适配器名称 - CenterRvAdapter 混淆了。 因此,请考虑将您的变量 CenterRvAdapter 重命名为不同的名称,例如 centerRvAdapter 或只是 adapter,在这样做时,请确保您不小心留下该类名,除非变量被初始化。

    【讨论】:

    • 你能告诉我如何创建setadapter
    【解决方案2】:

    当适配器未附加到回收器视图时会发生该错误。

    • 您可以使用空列表将adpter 设置为回收站视图。不会发生该错误。然后稍后添加数据并通知它。

    • 或者在你的代码中你写这个的地方

      // on the below line we are setting an adapter to our recycler view.
      CenterRvAdapter.also { sessionsRV.adapter = it }
      
      // on the below line we are notifying our adapter as the data is updated.
      
      this.CenterRvAdapter.notifyDataSetChanged()
      

    用此代码替换。在 UI 线程中通知,因为您无法在后台线程中访问 UI 元素。请记住检查日志以判断它是否已执行。

       activity?.runOnUiThread {
            Log.d("TAG", "runOnUiThread IS CALLED ")
            sessionsRV.adapter = CenterRvAdapter
            CenterRvAdapter.notifyDataSetChanged()
    
        }
    

    【讨论】:

    • 你能告诉如何将adpater设置为recyclerview plzzzz
    • 这是 kotlin 中的 setadapter sessionRV.adapter = CenterRvAdapter 在 oncreate 期间未附加适配器。这不是主要问题。如果列表为空,您可以使用空列表附加适配器 return 0 在此处覆盖 fun getItemCount(): Int { // 在下面的行中,我们正在返回 // 我们的数组列表的大小。返回 firebaseKotlinVersion.size }
    猜你喜欢
    • 2015-04-15
    • 2016-09-09
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 2021-05-04
    • 1970-01-01
    相关资源
    最近更新 更多