Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
here is my scenario I have 2 fragment A, A consists of recyclerView Adapter to display list of items, and fragment B has 4 edit texts, and an add button, when the user clicks on add button it will navigate back to fragment A, here I'm confused how do i bind the Args from fragment B and add them to the recyclerView as a new item.

here is my code
class ContactListFragment : Fragment() { //Fragment A 

    private var _binding: FragmentContactListBinding? = null
    private val binding get() = _binding!!

    private   var adapter: ListAdapter? = null

    private  var listOfStudents: MutableList<StudentInfo>? = null

//    private val sharedViewModel: SharedViewModel by viewModels()



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

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        //Inflate the layout

        _binding = FragmentContactListBinding.inflate(layoutInflater)

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
//i tried this but it didn't work
//        loadStudents()

        adapter = ListAdapter(mutableListOf(),requireContext())

        binding.rvListContact.adapter = adapter



        binding.fabAddItem.setOnClickListener {
            val action =
                ContactListFragmentDirections
                    .actionContactListFragmentToAddItemFragment()
            it.findNavController().navigate(action)

        }




    }

    /**
     * here i tired to make this function to add a new item to the list with new args,
     * but it didn't work
     */

//    private fun loadStudents(){
//
//        val name = ContactListFragmentArgs.fromBundle(requireArguments()).studentName
//        val number = ContactListFragmentArgs.fromBundle(requireArguments()).studentNumber
//        val country = ContactListFragmentArgs.fromBundle(requireArguments()).studentCountry
//
//
//        listOfStudents = mutableListOf(
//            StudentInfo(
//                name,
//                number,
//                country
//            )
//        )
//
//
//
//    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

}



AddItemFragment.kt
Kotlin
<pre>class AddItemFragment : Fragment() {//Fragment B

    private var _binding: FragmentAddItemBinding? = null
    private val binding get() = _binding!!

 


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

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentAddItemBinding.inflate(layoutInflater)

        return binding.root

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)





        binding.apply {

            /** Navigate from [AddItemFragment],
             *  To [AddItemFragment], only if the condition is true.
             * */
            btnAddNewContact.setOnClickListener {

                /* if name/phoneNumber field is empty it will give an error,
                 and return when clicking on ADD button,
                 and it will not navigate back to the screen.
                 */
                if (edAddName.text!!.isEmpty()) {
                    edAddName.error = "name is required!"
                   toastMessage("missing required fields!")
                    return@setOnClickListener
                }
                if (edAddPhoneNumber.text!!.isEmpty()) {
                    edAddPhoneNumber.error = "phone number is required"
                   toastMessage("missing required fields!")
                    return@setOnClickListener
                }

                if (edCountry.text!!.isEmpty()) {
                    edCountry.error = "country is required"
                 toastMessage("missing required fields!")
                    return@setOnClickListener
                }

                 val studentName = binding.edAddName.text.toString()
                 val studentNumber = binding.edAddPhoneNumber.text.toString()
                 val studentCountry = binding.edCountry.text.toString()

                val student = StudentInfo(studentName,studentNumber,studentCountry)

                findNavController().navigate(
                    AddItemFragmentDirections.actionAddItemFragmentToContactListFragment(
                        studentName,
                        studentNumber,
                        studentCountry,
                    )
                )
//                listAdapter?.addStudentCard(mutableListOf<StudentInfo>().add(student))
            }

            //Dialog to alert if the user is sure to cancel.
            val alertDialog = AlertDialog.Builder(requireContext())
                .setTitle("CANCEL DIALOG")
                .setMessage("Do you want to cancel adding new card o your list?")
                .setPositiveButton("YES"){_,_ ->
                    //if user clicks yes then navigate back to the [ContactListFragment]
                    findNavController().navigate(
                        AddItemFragmentDirections.actionAddItemFragmentToContactListFragment())
                toastMessage("adding new contact is cancelled!")
                }

                .setNegativeButton("DISMISS"){dialogInterface,_ ->
                    dialogInterface.dismiss()
                }.create()

            btnCancel.setOnClickListener {

                //if fields are empty then the condition is true,
                //if it is true then navigate back to the ContactListFragment.
                if (edAddPhoneNumber.text!!.isEmpty() && (edAddName.text!!.isEmpty())){
                    findNavController().navigate(
                        AddItemFragmentDirections.actionAddItemFragmentToContactListFragment()
                    )
                   toastMessage("adding new contact is cancelled!")
                }
                //if the user clicks on cancel Button,and texts fields is not empty then show the dialog.
                 if(edAddPhoneNumber.text!!.isNotEmpty() && (edAddName.text!!.isNotEmpty())){
                    alertDialog.show()
                }
            }

        }
    }
    //function represents toast message.
    fun toastMessage(text: String) {
        Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
    }


}


RecylcerViewAdaptyer.kt

class ListAdapter(private var studentInfo: MutableList<StudentInfo>, private val context: Context): RecyclerView.Adapter<ListAdapter.ItemViewHolder>(){


    inner class ItemViewHolder(val binding: ItemViewBinding): RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {

        val binding = ItemViewBinding.inflate(LayoutInflater.from(parent.context), parent,false)

        return ItemViewHolder(binding)
    }




    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val currItem = studentInfo[position]
        holder.binding.apply {
            tvName.text = currItem.name
            tvNumber.text = currItem.number
            tvCountry.text = currItem.country
        }

    }

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



}


What I have tried:

I created new function to add the item to the list in the Adapter, and notify it when new item is inserted, and i called the function in Fragment A and passed in the args.


Kotlin
<pre>   
    fun addStudent(studentCard: StudentInfo){
       studentInfo.add(studentCard)
        notifyItemInserted(studentInfo.size - 1)
    }
Posted
Updated 28-May-22 0:41am

1 solution

There are a number of possible routes to this, see Communicating with fragments  |  Android Developers[^].
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900