3

I think I'm doing it wrong but this is my situation.
I'm getting json data inside a fragment then process it with Gson to a data class and display it. What I need is to use this data again inside another fragment in a custom spinner adapter which is ready.

As much as I understand it's impossible to pass objects so how can I do this !? I have tried to use bundle and it didn't work

the onResponse method (First fragment)

            override fun onResponse(call: Call?, response: Response?) {
            val jsonString = response?.body()?.string()
            val gson = GsonBuilder().create()
            val data = gson.fromJson(jsonString,currancyModel::class.java)
            countryData = data
            activity?.runOnUiThread {
                rootView.recyclerView.adapter = CountryAdapter(data)
                }
        }

the data class

data class currancyModel(val items: List<Item>)
data class Item(val countray :String,val rate:String)

the getView in the custom spinner adapter inside the second fragment (I need my data here)

    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
    val view    = inflater.inflate(R.layout.custome_spinner,null)
    val img = view.findViewById<View>(R.id.spinner_image) as ImageView
    val countary_name     = view.findViewById<View>(R.id.spinner_country) as TextView
    img.setImageResource(R.drawable.us)
    countary_name.setText(country!![p0].countray)
    return view
}
Wael Fadl Ãllåh
  • 167
  • 1
  • 3
  • 10
  • 1
    Its not impossible to pass objects via `Bundle` .You can use `Parcelable` in this case . Follow https://stackoverflow.com/questions/16036572/how-to-pass-values-between-fragments. – ADM Feb 07 '19 at 10:31
  • you can use interface or check with ViewModel to communicate between fragments https://developer.android.com/topic/libraries/architecture/viewmodel#sharing or you can check for passing bundle as argument as per your requirement – Pavan Feb 07 '19 at 10:32

3 Answers3

2
  1. Do you display two fragments in your Activity simultaneously? If so, you can pass the data through it. Or implement some interface/observable/livedata to pass the data between the fragments.

  2. If Fragment A fetches the data and then you change Fragment A to Fragment B, make your data classes Parcelable and then pass it as arguments when creating Fragment B:

companion object {
    fun newInstance(yourData : DataClass) = FragmentB().apply { arguments = Bundle().apply {  putParcelable("dataKey",yourData) }
}

Note: you can annotate your data class with @Parcelize. Compiler will then generate all Parcelable methods and factory class for you.

After you passed the data to Fragment B on creation, retrieve it with, for example:

val data: YourData by lazy { arguments?.getParcelable("dataKey") as YourData }

Kuba Pawłowski
  • 365
  • 2
  • 10
  • the two fragments isn't in the same display so its the second scenario thanks alots , one more question ! as you can see I have two data class one contain a list of the other , which one should I implement the Parcelable in ? – Wael Fadl Ãllåh Feb 07 '19 at 11:40
  • 1
    You should consider passing just `items: List` from `data class currancyModel`. Since `List` collection is not parcelable by itself, you need to pass it as a typed array. Use `putParcelableArray(key, list.toTypedArray)`, then retrieve it with `arguments?.getParcelableArray()`. – Kuba Pawłowski Feb 07 '19 at 11:56
  • something isn't right , I have did everything as you said but I always get null on **data** variable , according to your example the data should be passed from Fragment A like this ` FirstFragment.newInstance(data) ` inside the above onResponse method ?! Right ? – Wael Fadl Ãllåh Feb 07 '19 at 18:51
  • 1
    Have you changed `data` type to `Array`? – Kuba Pawłowski Feb 07 '19 at 21:44
  • yes I did , I just figure out that the problem that **Fragment B** runs before **Fragments A** therefore when try to get the value with parcelabl in **Fragments B** its get null because **Fragments A** didn't put the value yet – Wael Fadl Ãllåh Feb 07 '19 at 21:53
2

Indeed it is possible to pass objects from one fragment to another given your object class should implement Parcelable. And passing the object through the bundle by calling putParcelable on the bundle object.

1. class CurrancyModel : Parcelable {
  //Implement Parcelable 
}

And pass it between the fragments via Bundle.

2.var fragment = YourFragment().apply {
   arguments = Bundle().apply{ putParcelable("dataKey",yourData) }
}
Saurabh Padwekar
  • 3,888
  • 1
  • 31
  • 37
  • This work to me after implement my data class with parcelable, them I am able to pass parcelable data between fragments using putParcelable(), thanks – Rafael Guimarães Apr 22 '19 at 20:40
-1

An idea could be to use a singleton data class, with a HashMap<String, Object> having a key with some kind of ID you create yourself, and then the value being the object you want to be able to retrieve. So in the onResponse you will add your data to the HashMap in the dataclass and then just retrieve it from the other class.

Sagar Poshiya
  • 136
  • 3
  • 11
Thor
  • 519
  • 1
  • 5
  • 16