Search code examples
androidkotlinandroid-fragmentsandroid-recyclerviewadapter

Sending data from recyclerview to fragment without intarface in Kotlin


I'm studying kotlin, and am stuck about recyclerview. The task is simple: show data from recycler (inside activity) item clicked inside a fragment.

The Model:

data class MyModel (
val info1:String,
val info2:String,
val info3:String)

the recyclerView is implemented using the idea I saw in Antonio's book (kotlin for android developers) - no intarface is used:

class RecyclerAdapter(
val myList:List<MyModel>,
val listener:(MyModel)->Unit):RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val itemViewholder = LayoutInflater.from(parent.context).inflate(R.layout.recycler_item,parent,false)
    return MyViewHolder(itemViewholder)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.bind(myList[position],listener)
}

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

class MyViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){

    fun bind(list:MyModel,itemListener: (MyModel) -> Unit) = with(itemView){
        recycler_infor1.text = list.info1
        recicler_infor2.text = list.info2
        setOnClickListener { itemListener(list) }
    }
}}

In Activity:

with(my_recyclerView){
        layoutManager = LinearLayoutManager(this@MainActivity,RecyclerView.VERTICAL,false)
        setHasFixedSize(true)
        adapter = RecyclerAdapter(fakeItens()){
            supportFragmentManager.commit {
                replace(R.id.fragment_container,FragmentDetail()).addToBackStack(null)
            }
        }

}

When the app is run, the recyclerView shows in each item the first and second information as well. Now, I need to show these informations and the third infor inside a Fragment that has three textView:

android:id="@+id/frag_infor1"
android:id="@+id/frag_infor2"
android:id="@+id/frag_infor3"

How can I do this?


Solution

  • Thank's to null_override, I found my solution:

    1 - make MyModel Parcelable

    data class MyModel(val info1:String?,
                       val info2:String?,
                       val info3:String?
    ):Parcelable {
        constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString(),
            parcel.readString()
        )
    
    
        override fun writeToParcel(parcel: Parcel, flags: Int) {
            parcel.writeString(info1)
            parcel.writeString(info2)
            parcel.writeString(info3)
        }
    
        override fun describeContents(): Int {
            return 0
        }
    
        companion object CREATOR : Parcelable.Creator<MyModel> {
            override fun createFromParcel(parcel: Parcel): MyModel {
                return MyModel(parcel)
            }
    
            override fun newArray(size: Int): Array<MyModel?> {
                return arrayOfNulls(size)
            }
        }
    
    }
    

    2 - passing to bundle and set argument to Fragment using apply in both

    with(my_recyclerView){
                layoutManager = LinearLayoutManager(this@MainActivity,RecyclerView.VERTICAL,false)
                setHasFixedSize(true)
                adapter = RecyclerAdapter(fakeItens()){
                    val bundle = Bundle().apply { putParcelable("Key", it) }
                    supportFragmentManager.commit {
                        replace(R.id.fragment_container,FragmentDetail().apply { arguments = bundle }).addToBackStack(null)
                    }
                }
    
            }
    

    3 - get data in Fragment

    lateinit var data:MyModel
    override fun onAttach(context: Context) {
         super.onAttach(context)
         arguments?.getParcelable<MyModel>("Key").let {
              if (it != null) {
                  data = it
              }
               
          }
      }
    

    4 - bind views

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            frag_infor1.text = data.info1
            frag_infor2.text = data.info2
            frag_infor3.text = data.info3
    }