I have this custom component inheriting from activity component, but i save the component holder as a ViewModel, so it would survive its Activity
Is this possible?
Related
I am trying to find a solution in how to define Hilt in a certain fragment related scenario. I have the following setup:
Activity
Parent Fragment 1
Child Fragment 1
Child Fragment 2
...
Child Fragment n-1
Parent Fragment 2
Child Fragment 1
Child Fragment 2
...
Child Fragment n-1
Parent Fragment 1 is using the dependency A. The instance of that dependency is something I want to share only between that parent fragment and all of its child fragments. The parent fragment 2 + its child fragments should use a different instance than the parent fragment 1 + children. Generally his structure should have only two instances of any given dependency - one for the first flow and one for the second.
I can see that a custom scope might work here but I am uncertain about how to use that in regards to Hilt.
You can do this using dagger-hilt by adding #AndroidEntryPoint in each parent Fragment and their child's view. Then your Parent Fragment 1 and Parent Fragment 2 will have different fragment scope with different instances as per the dagger-hilt explanation.
See below note from dagger-hilt:
A common misconception is that all fragment instances will share the
same instance of a binding scoped with #FragmentScoped. However, this
is not true. Each fragment instance gets a new instance of the
fragment component, and thus a new instance of all its scoped
bindings.
Also, see below dagger graph and the scopes hierarchy:
More details in their documentation.
Also, Don't use custom scopes until it's really necessary since it has performance and overhead issues.
I am just thinking about MVVM when it comes to bottom navigation view.
In this case it is one activity which has multiple fragments. If I use the ViewModel then the view model will hold the data for all fragments, right? Wouldn't this cause memory leaks or be bad for performance?
If I don't use the view model then I would be only holding one single Fragment data at a time.
Am I missing something?
There are multiple ways to implement this. Keep in mind, ViewModel doesn't have to be used only by Activity, it can be used by a Fragment or even a custom View.
In your case, if you have multiple fragments, you can create a ViewModel for each of them (if they are different off course).
The only thing that will kind of go out of MVVM pattern is the communication between fragment and activity.
If you still want to give the ViewModel the responsibility of telling the activity when to replace/remove/change a fragment, you can define an interface in each model (or a general interface) that will act as a callback, and you can set this callback on your ViewModel in onAttach or wherever fits for you.
Now your fragment, can pass the responsibility of notifying the activity to the ViewModel. I think this is one way of getting close to the MVVM patter in the case of Activity/Fragment communication, without to much trouble.
I'm refactoring an android component to be adopting MVP architectural pattern. The problem I faced is that I have a fragment nesting other fragments in it.
1- The parent fragment hides/shows one of the nested fragments based on some conditions.
2- The child fragment passes data to the parent fragment which is observing it as here inspired by callback mechanism between fragment and activity.
I've 2 questions:
1- If I consider the fragment as the view of MVP, should I use distinct presenters for the parent fragment & the child fragment (1-to-1 mapping between presenters & views) or only one presenter for both and why?
2- If I'm supposed to use distinct presenters, how should I handle passing data from the child fragment to the parent fragment as I barely know the Cons. and Pros. of:
Using an EventBus framework like Otto
Allow a presenter to have a direct reference on another presenter
Keep the communication in the view layer, away from the presenters as here, by having the nested view delegates calls it receives from its presenter to the parent view.
As with most architectur questions, I honestly think there is no right or wrong way. So please treat this just a suggestion (how I would implement this)
Each MVP unit should contain it's own presenter, which means there is one parent presenter (for the parent fragment) and several child presenters (one for each child fragment).
The child presenters all contain a parentPresenter field, which acts as a way to pass data / messages from the child to the parent. This parentPresenter is NOT the real presenter object, but an interface that includes only the needed calls.
If you need to pass data / messages the other way around (from the parent to the children), this is implemented via interface methodes in the view:
the parentPresenter calls its view
the parentView finds it's childFragment
the childFragment calls the appropriate interface call on the childPresenter
This way the whole communication is hidden behind clean interfaces and is also nicely testable. Hope this helps and let me know if you have any questions...
What I do in my application is using a callback mechanism between parent and child fragments for passing data between.
I also made a different presenters for each child fragment, because if one day I would like to use only one of the child fragments I would only override it's presenter methods.
I’m having an issue with dependency injection with Dagger, and using the MVP architecture, on a view which has dynamic tabs.
My activity is consisted basically of multiple tabs, which each tab has just a list of items (thus they all will be using the same Fragment class), and they all will use the same presenter class too (different instances). The number of tabs that I’ll be showing is based of a response I get from my server.
The problem is because dagger works on top of classes types, and I need to work on some sort of index to correlate the tab view and it's presenter.
I can't use the same instance of the presenter for all fragments because the presenter also keeps an reference to it's own fragment.
How can I achieve this kind of dynamic injection with dagger?
So I have an a presenter that is already tied to an activity. The book says that one presenter should be tied to one view. But now I am adding a few fragments and lots of custom views. I am considering a fragment to be a view as well. The custom views will contain a little bit of logic in them. Both the fragments and custom views are contained in my activity of course.
My question is, should I re-use the same presenter in the fragment and custom views or should each view get its own presenter? I realize this is all opinion based but I want the best approach for testing and keeping code clean.
If i do have one presenter for all these fews then then interface the presenter uses will have many callback methods in it. Meanwhile if i did the opposite and created one presenter for each view it might be easier to read but how would i test it ?
View (Activity) can have multiple Presenters. In case of having multiple CustomViews for Activity, you can have one giant Presenter or Presenter per each CustomView. It depends on this:
If all CustomViews share same needs, one Presenter for all CustomViews is enough. Still two options for Presenter's scope:
Presenter has ActivityScope. Activity uses Presenter and gets called from Presenter. Then sends commands, data to CustomViews
Presenter has ViewScope. Each CustomView creates and destroys same Presenter
In case of CustomViews not sharing same needs, having one Presenter and ViewInterface, they will contain methods of all CustomViews needs, so each CustomView has to implement all declared methods in ViewInterface, leave some empty.
If CustomViews have different needs and method calls to Presenter, they should have their own Presenter.
If CustomViews have different needs and also some common needs, they share common need in one Presenter, specific needs in their own Presenters. Example for this: ActivityOne has CustomViewOne and CustomViewTwo. Common Presenter for both CustomViews can be FeedPresenter(considering both CustomViews have Feed List). Then CustomViewOne will have CustomPresenter1 and CustomViewTwo will have CustomPresenter2 for their specific needs.
Best practice is to create a basepresenter , then create presenter for each view implementing basepresenter