I've been looking for some time to android architechture components and lately to the Navigation component.
I'm trying to pass as a parameter an object, so the next fragment can retrieve that data, but to do so I'm required to do one of two things:
- Pass it through a Bundle, which will make me implement the Parcelable interface to that object.
- Use the "Safeargs" plugin which I've tried and it looks like behind the hood makes use of Bundles and requires the implementation of the Parcelable interface anyway.
The thing about these options is that I've read that Parcelable makes use of reflection and it can get quite expensive regarding time
I have also tried to build a "SharedMasterDetailsViewModel" but with no luck since the observable callbacks are not being performed on my newly created Fragment. (I think LiveData performs the callback before my fragment is created)
Here's some code about how I've tried to approach this
SharedSessionViewModel
class SessionSharedViewModel : ViewModel() {
var sharedSession: LiveData<Session> = MutableLiveData()
private set
fun setSession(data: Session) {
val casted = this.sharedSession as MutableLiveData<Session>
casted.postValue(data)
}
}
MasterFragment
override fun onItemClicked(item: Session) {
sessionSharedViewModel.setSession(item) // Item is a complex object of mine
[email protected]().navigate(R.id.sessionDetailsFragment)
}
DetailsFragment
class SessionDetailsFragment : Fragment() {
companion object {
fun newInstance() = SessionDetailsFragment()
}
private lateinit var sharedViewModel: SessionSharedViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.session_details_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
Log.d("SESSIONDETAILS","created!")
super.onActivityCreated(savedInstanceState)
sharedViewModel = ViewModelProviders.of(this).get(SessionSharedViewModel::class.java)
sharedViewModel.sharedSession.observe({this.lifecycle},{ handleUI(it!!)})
}
fun handleUI(sharedSession: Session) {
Toast.makeText(activity, "This is inside new activity: ${sharedSession.title()}", Toast.LENGTH_SHORT)
}
}
My last hope is to serialize my object into a JSON string and reparse that object on the onCreateActivity lyfecycle hook of my Detail fragment but I feel like that is not the proper solution.
In the worst case scenerio I would just pass the id of the object and re-fetch it from the network, but since I already have the info I want to show I'd like to pass it as a parameter.
Parcelable does not use ReflectionIn-fact Parcelable was created with a motive of having less fingerprint than Serializable.Anyand then cast it back to its type in the creation of the fragment. But this a filthy dirty trick and I don't want to do that.