androidkotlinandroid-recyclerviewnestednestedrecyclerview

Fetching all edit text from all input box of nested recylerview is fetching latest recylerview item instead all data


I am adding code here where i am trying to get all input field value (all nested recyler view items) on textview click . So if I have 2 parent recylerview and inside first parent 3 child recyler item and inside second parent recylerview 4 child item. then how i can fetch all 7 item details on textview click of parent or from mainactivity. I am only getting last added 4 item while first parent items are not fetched. what i am missing? Thanks in advance.

//Main class
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    createMockData()

}

@SuppressLint("WrongConstant")
private fun bindDataWithUi(itemData: ArrayList<HashMap<String, String>>) {
    // Create vertical Layout Manager
    val locationDatesList = findViewById<RecyclerView>(R.id.locationDatesList)
    val tv = findViewById<TextView>(R.id.tv)

    locationDatesList.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)

    // Access RecyclerView Adapter and load the data
    val adapter = MainAdapter(itemData)
    locationDatesList.adapter = adapter
    tv.setOnClickListener(View.OnClickListener {
        try {
            var data = adapter.getAllItemDetails()
            for(result in data){
                System.out.println(result)
            }
        }catch (e:Exception){
            e.printStackTrace()
        }

    })
}

private fun createMockData() {
    // Initialize test locations
    val items: ArrayList<HashMap<String, String>> = ArrayList()
    val time = System.currentTimeMillis()
    // Load items into ArrayList
    items.add(hashMapOf("A" to "B", "C" to "D", "time" to time.toString()))

    val tomorrowTime = time + (1000 * 60 * 60 * 24 * 3)
    items.add(hashMapOf("E" to "F", "G" to "H", "time" to tomorrowTime.toString()))
     // Bind items to RecyclerView
    bindDataWithUi(items)
}


}

//parent adapter

class MainAdapter(var locationList: ArrayList<HashMap<String, String>>): 
RecyclerView.Adapter<MainAdapter.ViewHolder>() {

val byDates = locationList.groupBy { it["time"] }
lateinit var childAdapter : PropertyAdapter
lateinit var parentItemHolder: MainAdapter.ViewHolder
@SuppressLint("WrongConstant")
override fun onBindViewHolder(holder: MainAdapter.ViewHolder, position: Int) {
    // Update date label
    parentItemHolder = holder
    val sdf = SimpleDateFormat("MM/dd/yyyy")
    val dateList = byDates.values.toMutableList()
    holder.date?.text = sdf.format(dateList[position][0].get("time")?.toLong())
    holder.childRv?.layoutManager = LinearLayoutManager(holder.childRv.context, LinearLayout.VERTICAL, false)
    var properyDataList:ArrayList<propertyDataClass> = ArrayList<propertyDataClass>()

    // Create vertical Layout Manager
    holder.date?.setOnClickListener(View.OnClickListener {
        // Access RecyclerView Adapter and load the data
        properyDataList.add(propertyDataClass())
        childAdapter = PropertyAdapter(properyDataList)
        holder.childRv?.adapter = childAdapter
        childAdapter.updateList(propertyDataClass())
    })
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainAdapter.ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item_dates, parent, false)
    return ViewHolder(v)
}

override fun getItemCount(): Int {
    return byDates.count()
}

class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
    val date = itemView.findViewById<TextView>(R.id.locationDate)
    val childRv = itemView.findViewById<RecyclerView>(R.id.childList)
}

 interface onClickItemAction{
    public fun productItemList() {

    }
}

fun getAllItemDetails():ArrayList<String>{
    var stringList = ArrayList<String>()
    try {
        for (i in 0 until locationList.size) {
            //val view = parentItemHolder.childRv.findViewHolderForLayoutPosition(i)//locationDatesList
              //val view = parentItemHolder.childRv.findViewHolderForAdapterPosition(i);
            val view = parentItemHolder.childRv.findViewHolderForLayoutPosition(i)
                val etLabel: EditText? = view?.itemView?.findViewById(R.id.etLabel)
                val etValue: EditText? = view?.itemView?.findViewById(R.id.etValue)
                //stringList.add(etLabel?.text.toString())
                stringList.add(etValue?.text.toString())

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

    return stringList
}

}
//child adaoter
class PropertyAdapter(
val propertyList: ArrayList<propertyDataClass>,
): RecyclerView.Adapter<PropertyAdapter.ViewHolder>() {
lateinit var vHolder :ViewHolder
override fun onBindViewHolder(holder: PropertyAdapter.ViewHolder, position: Int) {
    vHolder = holder
    val propertyItem = propertyList[position]
    holder.etLabel?.text = propertyItem.inputName
    holder.etValue?.text = propertyItem.inputValue
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PropertyAdapter.ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item_locations, parent, false)
    return ViewHolder(v)
}

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

class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
    val etLabel = itemView.findViewById<TextView>(R.id.etLabel)
    val etValue = itemView.findViewById<TextView>(R.id.etValue)
}

fun updateList(propertyItem: propertyDataClass){
    //propertyList.add(propertyDataClass())
    notifyDataSetChanged()
}

fun getAllItemDetails(pos:Int){
    val propertyListValue = ArrayList<propertyDataClass>()
    for (i in 0 until propertyList.size){
        var  propertyDataClass = propertyDataClass()
    }
}

fun getItemDetailsbyView(rootView: View){
    var stringList = ArrayList<String>()

    for (i in propertyList){
        //val view = vHolder.findViewHolderForLayoutPosition(i)
        //val etLabel: EditText? = view?.itemView?.findViewById(R.id.etLabel)
        //val etValue: EditText? = view?.itemView?.findViewById(R.id.etValue)
        //stringList.add(etLabel?.text.toString())
        //stringList.add(etValue?.text.toString())
    }
}

}

//main.xml

   <?xml version="1.0" encoding="utf-8"?>
  <androidx.constraintlayout.widget.ConstraintLayout 
 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"
tools:context=".MainActivity">
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
<TextView
    android:id="@+id/tv"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:text="@string/app_name"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/locationDatesList"
    tools:layout_editor_absoluteX="8dp"
    tools:layout_editor_absoluteY="8dp"/>
  <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/locationDatesList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp" >

 </androidx.recyclerview.widget.RecyclerView>
 </LinearLayout>

 </androidx.constraintlayout.widget.ConstraintLayout>

//parent recylerview

<?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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/locationDate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginTop="16dp"
            android:gravity="center_vertical"
            android:text="Date"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
            android:textColor="#009688"
            android:textSize="18sp" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/childList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </androidx.recyclerview.widget.RecyclerView>

    </LinearLayout>

</androidx.cardview.widget.CardView>

 </LinearLayout>

//child recylerview

  <?xml version="1.0" encoding="utf-8"?>

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="10dp">

        <TextView
            android:id="@+id/locationBadge"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@drawable/ic_launcher_background"
            android:gravity="center_vertical|center_horizontal"
            android:text="✓"
            android:textColor="#fff"
            android:textStyle="bold" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="10dp">

            <EditText
                android:id="@+id/etLabel"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="Name"
                android:maxLines="1"
                android:editable="false"
                android:focusable="false"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/etValue"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="Address"
                android:maxLines="1"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
                android:textSize="16sp" />

        </LinearLayout>

    </LinearLayout>

    </LinearLayout>

Solution

  • just needed to hold the view holder in seprate arraylist then finding viewholder by position solved my problem.

    in main adapter I added and fetched after click.

             viewHolderList.add(holder)
    
    
     fun getAllItemDetails():ArrayList<String>{
        var stringList = ArrayList<String>()
        try {
            for (i in 0 until locationList.size) {
                //val view = parentItemHolder.childRv.findViewHolderForLayoutPosition(i)//locationDatesList
                  var viewHolder = viewHolderList.get(i)
                for (i in 0 until 3) {
                    val view = viewHolder.childRv.findViewHolderForAdapterPosition(i);
                    //val view = parentItemHolder.childRv.findViewHolderForLayoutPosition(i)
                    val etLabel: EditText? = view?.itemView?.findViewById(R.id.etLabel)
                    val etValue: EditText? = view?.itemView?.findViewById(R.id.etValue)
                    //stringList.add(etLabel?.text.toString())
                    stringList.add(etValue?.text.toString())
                }
    
            }
        }catch (e:Exception){
            e.printStackTrace()
        }
    
        return stringList
    }