Issue
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.
Solution
TL; DR
You can't.
Actual explanation
First thing; the following statement
The thing about these options is that I've read that Parcelable makes use of reflection and it can get quite expensive regarding time.
IS A LIE
Since you implement Parcelable
you're just providing methods on how to serialize and deserialize using basic primitive types: IE: writeBytes
, readBytes
, readInt
, writeInt
.
Parcelable
does NOT use reflection. Serializable
does!
While it's true you are forced to use Parcelable
jet brains developed a very useful annotation that takes away the pain of having to write the parcelable implementation called @Parcelize
.
Sample usage:
@Parcelize
data class User(val username: String, val password: String) : Parcelable
And now you're able to pass instances of the class without writing a single line of Parcelable
implementation.
More info here
Answered By - Some random IT boy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.