Zhuinden / simple-stack

[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).
Apache License 2.0
1.36k stars 76 forks source link

[Q] A minimal java example to pass data into fragments #241

Closed omkar-tenkale closed 3 years ago

omkar-tenkale commented 3 years ago

I've read the doc and have browsed other issues to find a way to pass data but I've encountered following issues

  1. The doc mentions Services to share data (Took me a lot of time to realize it's not the android background service, Please clear it in terminology too)
  2. I didn't find the service doc much helpful. https://github.com/Zhuinden/simple-stack/wiki/5.-Scoping,-data-or-state-sharing-between-screens It felt more like describing how things work underneath instead of how to use it guide with too many terms not explained before eg Binding,implicit scopes ,lookup
  3. Example projects were also not much helpful coz they are written in kotlin (Scoping ones) and are more complicated (ViewModel architecture etc)

Can you please provide a minimal pure java Fragment A > Fragment B non serializable data passing example I don't care about data persistance (Orientation locked)

Zhuinden commented 3 years ago

Hey!

So, arguments in the case of Fragments are passed via the key also being Parcelable and containing any argument that is intended to be passed. (I am not sure why the basic-java-fragment sample does NOT pass arguments in ANY of the keys, but the idea is to use AutoValue and a parcelable autovalue extension like auto-parcel).

If the data is loaded from DB and shared between screens, then ScopedServices + backstack.lookupService("serviceTag") can help. by lazy { lookup<T>() } is just a wrapper with a sensible default.

omkar-tenkale commented 3 years ago

From examples i can see that using BaseKey we can pass simple data Is it possible to pass non serializable / non parcelable data between fragments?

Zhuinden commented 3 years ago

Fragments require the key to be Parcelable, because it is used as part of its arguments.

The arguments is a Bundle, so only Bundle-supported types would work.

It is possible to share data between screens using ScopedServices, but then you do need to consider that in an Android app, any screen can technically be "the first screen to show".

However, backstack.lookupService() would find the scoped services of the previous screens as those are recreated in order correctly, after process death. So scoped services can be used to pass non-parcelable things between screens, but you need to consider that the 2nd screen can be the first screen to show in an Android app.

Does that answer the question? 🤔

Zhuinden commented 3 years ago

I'm actually just realizing that while I personally do recall how to use scoped services API in Java, technically most people wouldn't know that because what I'm remembering is the massive amounts of unit tests. Most people don't learn how to use an API by reading their unit tests, and that makes perfect sense.

I think I'll convert the scoping example to Java later today, then.

omkar-tenkale commented 3 years ago

I think I'll convert the scoping example to Java later today, then.

Yup. I personally feel the documentation is not enough and could be improved a lot for beginners

Does that answer the question? 🤔

I already realised that only serializable,simple data can be passed through fragment bundle That's why I was exploring the Scoped Service thing I'd say I still don't hold reliable knowledge to implement shared data between fragments (And also failed to grasp how or where the "the first screen to show" issue will occur) I guess I'll encounter it first and then realize it,lol But If I'll find the example you're going to provide useful,I'll surely try to contribute to wiki for beginner level implementation of this lib Please try to make it as minimal as possible (No dependencies, not even autovalue) Optimizations could be done if base is clear first

Thanks

Zhuinden commented 3 years ago

https://github.com/Zhuinden/simple-stack/tree/2f2419a8c0cc0d959f34a425cf95e5c0a284eb29/samples/scoping-samples/simple-stack-example-scoping-java/src/main/java/com/zhuinden/simplestackexamplescoping

I have converted the scoping example to have a Java version.

There is a case in it where the List<String> is shared between both screens, by having it defined originally by the WordListKey, but scoped services via implicit scope lookup are shared between screens. Also worth noting that I used addAlias to showcase that that's something you can do, theoretically you could just be like addService(WordListViewModel.class.getName(), new WordListViewModel()); and it would still work actually.

Please try to make it as minimal as possible (No dependencies, not even autovalue)

I use AutoValue in the samples for auto-parcel so that Parcelable implementation is not manually done (+ hashCode/equals/toString), so I can't make that promise, but IDE can technically autogenerate Parcelable impl too anyway.

I personally feel the documentation is not enough and could be improved a lot for beginners

I always felt that the Readme.md contains everything to start out, but maybe I'm wrong on that claim 😅


Anyway, with the new Java sample, this is theoretically done?