Search code examples
androidandroid-fragmentskotlinparameter-passingmobile-application

getArguments() always returning null in my second fragment


I know the question has been asked too many times but none proves to be working for me. I'm trying to pass the input in an EditText of Fragment1 to a TextView in Fragment2 using an interface and both sharing one Activity, but I've been stucked at it for more than a day now. The problem is that the argument I'm sending from the MainActivity is always null.

This is my Interface:

interface SendData {
    fun sendData(name: String)
}

And the Fragment1.kt:

class Fragment1 : Fragment() {

    private lateinit var communicator: SendData

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(R.layout.fragment1_layout, container, false)
        communicator = activity as SendData

        rootView.btn_send.setOnClickListener {
            communicator.sendData(rootView.name_ET.text.toString())
        }
        return rootView
    }
}

Fragment2.kt

class Fragment2 : Fragment() {

    var receivedName: String? = ""

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

        receivedName = arguments?.getString("NAME")
        Log.d("Fragment2", "Receiving: ${arguments.toString()}")
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(R.layout.fragment2_layout, container, false)

        rootView.receivedName_TV.text = receivedName

        return rootView
    }
}

And the MainActivity.kt

class MainActivity : AppCompatActivity(), SendData {

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

        supportFragmentManager.beginTransaction().replace(R.id.fragment_container, Fragment1())
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit()
    }

    override fun sendData(name: String) {
        Fragment2().apply {
            arguments = Bundle().apply {
                putString("NAME", name)
            }
            Log.d("Fragment1", "Sending: ${arguments.toString()}")
        }
        supportFragmentManager.beginTransaction().replace(R.id.fragment_container, Fragment2())
            .addToBackStack("Fragment2").setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit()
    }
}

I'm using a resource and I even compared my code with theirs line by line and I can't see what I'm doing wrong. Thanks for helping in advance.


Solution

  • You are calling

    supportFragmentManager.beginTransaction().replace(R.id.fragment_container, Fragment2())
    

    on new fragment not the one you used apply try

    supportFragmentManager.beginTransaction().replace(R.id.fragment_container, Fragment2().apply {
            arguments = Bundle().apply {
                putString("NAME", name)
            })
    

    and deleting this part above

    Fragment2().apply {
            arguments = Bundle().apply {
                putString("NAME", name)
            }
    

    basically what I am trying to say is your function should look like this

    override fun sendData(name: String) {
    
        supportFragmentManager.beginTransaction().replace(R.id.fragment_container, Fragment2().apply {
            arguments = Bundle().apply {
                putString("NAME", name)
            }
        })
            .addToBackStack("Fragment2").setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit()
    }
    

    or

    override fun sendData(name: String) {
        val f =Fragment2().apply {
            arguments = Bundle().apply {
                putString("NAME", name)
            }
            Log.d("Fragment1", "Sending: ${arguments.toString()}")
        }
        supportFragmentManager.beginTransaction().replace(R.id.fragment_container, f)
            .addToBackStack("Fragment2").setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit()
    }