1

In summary, I have 2 fragments. one is ViewPlacesFragment and the other is MenuFragment. I have a MainActivity class too. inside ViewPlacesFragment there is RecyclerViewAdapter . Inside a RecyclerViewAdapter class, I implemented a callback for when Recyclerview Item is clicked, then it sends the item Id that is clicked to MainActivity. then Main Activity calls MenuFragment for showing it and pass that Id to this fragment. Everything is worked fine except the Id value not received in MenuFragment. I could print the correct Id value in Log.d("debug4", Id) and I checked the code but nothing is wrong. so why is the Id value received null in MenuFragment?

RecyclerAdapterAllPlaces:

Class RecyclerAdapterAllPlaces(var myReceivedData: PlaceModel?=null, val context:Context,val cellClickCallback: (id:String) -> Unit):RecyclerView.Adapter<RecyclerAdapterAllPlaces.Viewholder>(){
...
    override fun onBindViewHolder(holder: Viewholder, position: Int) {
        holder.itemView.setOnClickListener {cellClickCallback(myReceivedData!![position]._id)}
}
}

MainActivity:

 Class MainActivity(){
                                                                       
  //new callback method in kotlin
  val callbackFrominsideFragment=RecyclerAdapterAllPlaces(null,this,::callbackInsideFragment)

private fun callbackInsideFragment(Id:String) {
    Log.d("debug4",Id)
    val fragmentTransaction = getSupportFragmentManager().beginTransaction()
    val args = Bundle()
    val destinationFragment= MenuFragment()
    args.putString("Place_Id", Id)
    destinationFragment.arguments = args
    fragmentTransaction.replace(R.id.frame_container, MenuFragment())
    fragmentTransaction.commit()
}

}

MenuFragment:

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

    val bundle = Bundle()
    val data = bundle.getString("Place_Id")

    Log.d("debug", "it is $data")
    if (data != null)
    {
        P_Id = data
        Log.d("debug",P_Id)
    }

}

Edit:

I edited the code and remove new bundle() but return null.

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val bundle = this.arguments
    if (bundle != null)
    {
        val data = bundle.getString("Place_Id")
        P_Id = data!!
        Log.d("debug",P_Id)
    }}
Biruk
  • 23
  • 1
  • 5
NimaAzhd
  • 162
  • 3
  • 15
  • 1
    Why are you instantiating a new `Bundle`? – Animesh Sahu Nov 19 '20 at 14:49
  • Does this answer your question? [How to transfer some data to another Fragment?](https://stackoverflow.com/questions/7149802/how-to-transfer-some-data-to-another-fragment) – Animesh Sahu Nov 19 '20 at 14:50
  • @AnimeshSahu tnx but I changed it to code above. still returns null. – NimaAzhd Nov 19 '20 at 15:32
  • 1
    Again, you are adding argument to `destinationFragment.arguments = args` but passing a newly instantiated fragment to the fragment transacation `fragmentTransaction.replace(R.id.frame_container, -> MenuFragment() <-)` – Animesh Sahu Nov 19 '20 at 15:36
  • @AnimeshSahu thank you buddy. I changed a code a lot. my mistake. tnx again. – NimaAzhd Nov 19 '20 at 15:53

3 Answers3

4

In callbackInsideFragment method you are creating a destination fragment but in fragmentTransaction.replace you pass a new fragment instance.

mrzbn
  • 497
  • 1
  • 3
  • 15
2

You are creating a new bundle instead of using the provided bundle

//val bundle = Bundle() remove this line, that is instantiating a new bundle
val data = bundle?.getString("Place_Id")

You can do that as you are or you could

val data = arguments?.getString("Place_Id")

The variable arguments is the Kotlin way to get the extra bundle. Is nullable so you have to use the nullable operator ?. You can use arguments practically on any method, by example if you are doing something on onViewCreated or onCreateView, that way if onCreate is not needed you don't need to override it just to get the bundle.

cutiko
  • 9,887
  • 3
  • 45
  • 59
  • Tnx but it both ways return null. I also used " val bundle = this.arguments if (bundle != null) { val data = bundle.getString("Place_Id")}" , nothing changed – NimaAzhd Nov 19 '20 at 15:14
1

@Mahdi M's answer is correct, but I figured I'd elaborate on it a bit. Let's take a look at the code you've posted, slightly rearranged for clarity:

private fun callbackInsideFragment(Id:String) {
    val args = Bundle()
    args.putString("Place_Id", Id)

    val destinationFragment= MenuFragment()
    destinationFragment.arguments = args

    val fragmentTransaction = getSupportFragmentManager().beginTransaction()
    fragmentTransaction.replace(R.id.frame_container, MenuFragment())
    fragmentTransaction.commit()
}

In the transaction, you are creating a second instance of MenuFragment and replacing with that instead of the destinationFragment for which you've correctly set the args. This means that args and destinationFragment are never really used, so you essentially just have this:

private fun callbackInsideFragment(Id:String) {
    val fragmentTransaction = getSupportFragmentManager().beginTransaction()
    fragmentTransaction.replace(R.id.frame_container, MenuFragment())
    fragmentTransaction.commit()
}

Just change the replace() call to use destinationFragment and everything should be fine:

private fun callbackInsideFragment(Id:String) {
    val args = Bundle()
    args.putString("Place_Id", Id)

    val destinationFragment= MenuFragment()
    destinationFragment.arguments = args

    val fragmentTransaction = getSupportFragmentManager().beginTransaction()
    fragmentTransaction.replace(R.id.frame_container, destinationFragment)
    fragmentTransaction.commit()
}
Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Thank you, Yeah , He was right too like @AnimeshSahu .I changed my code a lot & copy it from another page. It caused this misguided. – NimaAzhd Nov 19 '20 at 17:25