androidandroid-recyclerviewfragmentbundleonclicklistener

How to pass data from recyclerview adapter to a fragment?


I am trying to pass a data from my adapter when clicked in recycler view to a fragment. i have implemented the click listener but can't pass data to the fragment and also get the passed data inside fragmentDetail.I am new to android and please help me ? DSAdapter.kt

class DSAdapter(
    private val DSModelList: ArrayList<DSModel>,
    private val listener: RecyclerViewEvent
): RecyclerView.Adapter<DSAdapter.ViewHolder>() {

    private lateinit var context: Context;

    interface RecyclerViewEvent {
        fun onItemClick(position: Int)
    }

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

    override fun onBindViewHolder(holder: DSAdapter.ViewHolder, position: Int) {
        val algorithModel = DSModelList.get(position)
        var algorithmName = algorithModel.name
        var index = algorithModel.index

        holder.algorithm_name.text = algorithmName
        holder.index.text = index
    }

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

    inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView),View.OnClickListener {
        var algorithm_name = itemView.findViewById<TextView>(R.id.algorithm_name)
        var index = itemView.findViewById<TextView>(R.id.rvvPrefix)

        init {
            itemView.setOnClickListener(this)
        }

        override fun onClick(view: View?) {
            val position = adapterPosition
            if (position != RecyclerView.NO_POSITION) {
                listener.onItemClick(position)
            }
        }
    }

}

FragmentAlgorithmDetail.kt

class FragmentAlgorithmDetail : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.algorithm_detail, container, false)
    }
}

FragmentDSList.kt

class FragmentDSList : Fragment() {

    private lateinit var adapter: DSAdapter
    private lateinit var recyclerView: RecyclerView
    private lateinit var DSModelArrayList: ArrayList<DSModel>

    lateinit var algorithmName: Array<String>
    lateinit var algorithmIndex: Array<String>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.algorithm_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dataInitialize()
        val layoutManager = LinearLayoutManager(context)
        recyclerView = view.findViewById(R.id.recycler_view)
        recyclerView.layoutManager = layoutManager
        recyclerView.setHasFixedSize(true)
        adapter = DSAdapter(DSModelArrayList,object: DSAdapter.RecyclerViewEvent {
            override fun onItemClick(position: Int) {
                val navcontroller = findNavController()
                navcontroller.navigate(R.id.action_data_structure_list_to_fragment_AlgorithmDetail)
            }
        })
        recyclerView.adapter = adapter
    }


    private fun dataInitialize(){
        DSModelArrayList = arrayListOf<DSModel>()
        algorithmName = arrayOf(
            getString(R.string.linked_lists),
            getString(R.string.Stacks),
            getString(R.string.Queues),
            
        )

        algorithmIndex= arrayOf("0","1","2")
        for (i in algorithmName.indices){
            val index = algorithmIndex[i].toInt() + 1
            val algorithmodel = DSModel(index.toString(),algorithmName[i])
            DSModelArrayList.add(algorithmodel)
        }
    }
}

I tried to pass the data when item are clicked in the recycler view and pass that data to the fragment and what i am expecting is when an item is clicked pass the data to the fragment


Solution

  • You can pass data from fragment to fragment using the navigation component:

    https://developer.android.com/guide/navigation/use-graph/pass-data

    You can define the data type you are passing in the navigation XML, for instance:

     <fragment android:id="@+id/myFragment" >
         <argument
             android:name="myArg"
             app:argType="integer"
             android:defaultValue="0" />
     </fragment>
    

    The SafeArgs plugin is what makes this magic happen:

    https://developer.android.com/guide/navigation/use-graph/safe-args

    You already have a nice DSModel class. If you can make that a Parcelable class, you can use it as the argument:

     <fragment android:id="@+id/fragmentAlgorithmDetail" >
         <argument
             android:name="algorithm"
             app:argType="com.example.DSModel" />
     </fragment>
    

    Then if you make use the navigation class instead of the id, you could say something like:

    val model = DSModelArrayList[position]
    navcontroller.navigate(action_DataStructureList_to_AlgorithmDetail(model))
    

    Find a tutorial on navigation with SafeArgs to help you understand.