How to model cross fragment transaction (ongoing process) in Android MVVM application? - android

I am developing an app that has some ongoing process that almost all screens depend on.
Let's call it ActiveTransaction. So, one fragment prepares items, the other fragment prepares payment, another adds discounts, etc... If one part fails, everything needs to rollback.
So, basically, I need to achieve atomicity across multiple fragments. I've tried to use shared ViewModel for this, but since each fragment adds its own stuff, that shared ViewModel has become too big.
So, I wonder what would be the best way to handle those processes that stretch over multiple fragments.
Should I have perhaps a singleton object ActiveTransaction that is injected in each viewModel?
Is this maybe what other technologies call the app State?
I haven't found anything in the MVVM architecture guidelines.

You can create Tabbed Activity - blank Activity with tabs. New project -> Tabbed Activity.
You will have one activity and multiple fragments.
So all functionality will be in MainActivity. Your fragments will contain views, which will call methods from MainActivity. All objects and calculations will be in main activity, so if it fails (because of memory lack), everything will collapse too.
For Example:
You have one Tabbed activity MainActivity and 3 fragments: Item Fragment, PaymentFragment and DiscountFragment. MainActivity contains multiple methods, let's say prepareItems(), preparePayment(), addDiscount(). User can go through Tabs, opening fragments. MainActivity methods can be called only via fragments. So if MainActivity collapses, the whole process will collapse.
So you will achieve atomicity and user can see changes by going through tabs. You can replace Tabs Activity by other scenario with single activity and multiple fragments which don't have functionality but contain views which will call methods from MainActivity

Related

Is it a good practice to use a single fragment to display the UI instead of the activity?

As the title states, does it considered as a good practice to use a single fragment within an activity to display the content? I began to notice that more and more developers start to use the fragment as an insulation layer to separate the lifecycle logic from UI that activity (sorry, fragment) displays. The most recent example that I stumble on is the architecture blueprints provided by Google developers. They use just one single fragment for UI while the activity handles ViewModel and all the navigation between screens.
So, is this a good practice or just a personal preference? Would you care to share your opinion on the subject?
Using Fragments as your UI is a good practice.
Activity can hold all common logic, while you can use different fragments to show different UI for mobile vs tablet.
If the UI is in Fragment, you can reuse it in multiple activities.
If you have a workflow scenario like Registration flow, using a single activity with multiple fragments will help you out a lot.
Manipulation of fragment backstack is a lot easier than trying to do the same with activities.
Use fragment for display the UI is good,Reason is listed below:-
1.You can create one activity,and display multiple fragment inside that activity.
2.Handling back press is easy as you can override onBackpress() in main activity class and handle back key event from fragment(s) as check its(fragment) visibility and handle event.
3. Reusability of layout.
4. Reusability of fragment.
5. Handling different action menu is very easy for different fragment(s).

Multiple Activity or Single Activity and multiple fragments

I have one very general question, I did not find a concrete answer for my question hence putting it again.
I want to decide between two approaches
Dedicated activities for various various screens and tasks to avoid complexity and issues
Single Activities and multiple fragments for different tasks and user can navigate like Activity holding Fragment A user will navigate to Fragment B, Fragment C , this can be back and forth transaction.
What I want to know?
Is Activity transition is that costly for processor or to achieve simplicity memory overhead is negligible ?
Fragment has overhead of managing life cycle with transition, so what all problem can come with this life cycler management?
How easy is to deal with fragment transaction with saving state of the fragment?
We don't know right now what amount data will be there for fragment to hold.
Well, it totally depends on the application's design, flow and it's navigation.
Here are some benefits of using Single Activity and Multiple Fragments:
Performance fragment transactions are fast than creating new activities.
Navigation Drawer and Toolbar, it's easy to manage with Single activity.
Same Context can be used everywhere.
Fragment's setRetainInstance is very helpful while managing orientation changes.
with it, here comes few drawbacks:
Activity gets really messy with a lots of code.
Handling button backpress is tedious as only Activity can handle that not Fragments.
I personally use Multiple activities with multiple fragments in which I separate activities based on the modules. In same module, submodules can be created in fragments. I found it easy to manage in different scenarios as if application gets closed, reopens, in notifications, orientation changes.
My question is same, till now in my all app, there is only one Activity, and the rests are Fragments. I agree it is hard to maintain Fragment, but using Fragment will increase your Performance.
Suppose, take one example,
I have 10 Activities, in each Activity, I'm calling Async Task to perform some background operations. In each Async Task's onPostExecute() you are updating your UI. But before completing the doInBackground() you switched the Activity and that Activity is destroyed, but remember the doInBackground() is still in progress, and once it is finished, onPostExecute will be called, and in onPostExecute() we are updating the UI, but the Activity is destroyed, so this will create a leak in your app.
But if you are maintaining only one Activity then it will be easy to maintain.
Waiting for others opinion also.
Apart from answers above, few points which I would add which can help in deciding when to use a Fragment and when to use an Activity.
If you're supporting larger screen sizes, fragments are definitely preferred over activities.
When you've some code which you think can be reusable in multiple screens, you can use a fragment which can be reused across different places
A small point to add in support of "single Activity multiple fragments".
Sometimes you may need a component (a banner ad for example) to persist between different pages/screens of your app. If you have multiple Activities, you'll need to recreate that component on each of the Activities. But if you have a single Activity, you just add that component to the Activity layout and can forget about it.

Fragment/Activity Best Practice

I set up my application in the following way and am curious if it's considered "best practice." I have two activities and two fragments. Activity 1 launches and immediately uses Fragment 1 to display a RecyclerView of items. An Item is clicked in the Fragment, it's communicated back to the Activity through an interface, some logic occurs and Activity 2 is launched, which immediately uses Fragment 2 to display the detail of the selected item.
I did this because A)I like the logical flow of Activities within an application and 2) I needed to create tablet layouts in which I could use both the Fragments to fill the screen.
The more I'm looking at this thing, I'm thinking why not simply have 1 Activity that manages both of these Fragments? Activity 1 launches Fragment 1, item is clicked, info goes back to Activity, FragmentManager replaces Fragment 1 with Fragment 2.
My question does one of these ways adhere more to "best practices" or are they both fine and it's a matter of choice?
You've not described your problem clear enough to use more than one Activity, other than unrelated data to the list and what happens when you click there.
What you described is a "master-detail" flow, and that is a good use case for one Activity and two (or more) Fragments - a list + some detail page. This especially makes sense on larger screens when you can show those Fragments side-by-side.
For example, you can have an Activity that holds a navigation screen (whether that be tabs, a drawer, or a bottom view), then everything you navigate to within there is a Fragment.
Otherwise, you redirect to some "settings" page, for example, that is a new Activity, which demonstrates the "Single responsibility principle" in your UI.
Well you can go with the single activity - multiple fragments. You can pass data between fragments using bundle as well. Matter of choice also depends on the use case. But fragments are made to use as light weight activity that requires less resources then activity. Most of the things are possible with fragments. So unless it is not required to use activity my choice goes with single activity - multiple fragments.

Upgrade/Migrate from Multiple Activity Intents to Single ViewPager & Fragments

I used to have 3 activities with 3 layouts.
1. HomeActivity.java (activity_home.xml)
2. HelpActivity.java (activity_help.xml)
3. SettingsActivity.java (activity_settings.xml)
Whenever i had to open other activities, i used animated slide-in-out intents using overridePendingIntent. In this way, all the variables of HomeActivity stayed in itself and HelpActivity's variables/methods were in itself and same for SettingsActivity. I used onCreate() in these to perform some activity specific code. and, android:onClick="fetchSarcasm" from activity_home.xml was calling specified method in HomeActivity.java. So, there were no conflicts. All the normal things, that happen in an AndroidProject with 3 activities and used intents to switch to one another, were happening as i wanted.
But now, I wanted to migrate to ViewPager instead of slide-in-out intent transitions. In this way, there will be only one Activity with an XML of ViewPager. This ViewPager and its FragmentPagerAdapter gets the Pages from 3 classes extending Fragment with relative XML layouts.
I want to ask: Where do i write my Page Specific Code for onCreate(), layoutView's onClick="" and for onChangeListeners. Because, 3 classes extending Fragment do not have any Context or findViewById() and they do not respond to android:onClick="method" in different layouts.
Do i need to mix all that code of three activities into one containing ViewPager? If so, this makes ViewPager activity pretty heavy. and, writing if(page=2){ dothis(); } seems absurd for all pages at every code point. Any checkbox(view) that is in page 3, becomes null in other pages.
I know this might be a stupid question. I have spent almost 4 days trying to achieve something but i can't. Also, this is just my 2nd month in android, so i am new. I do not use Action Bars, Tabbed Bars or Navigation Drawers.
I am available on SO Chat too if you want to ask something more.
I just want to know how do i merge all the work i did when I was not using ViewPager.
If you're only reading the Preferences once for each Fragment, you can move your previous Activity.onCreate() logic to each Fragments onViewCreated() or onCreateView(). Read your shared Preferences there and set your Checkboxes accordingly.
Fragments inside a ViewPager aren't necessarily recreated on each page change. You can change how many Fragments are instantiated at a time with ViewPager.setOffscreenPageLimit(int).
Fragment Lifecycles explained

Android Navigation Drawer with many fragments

I've been struggling with this for a while now, I want to start off with a diagram of my problem:
The three navigation drawer buttons are part of my Base Activity. Each purple block below the three buttons are fragments, and the descendants of each of those blocks are in turn fragments. I'll use the master and detail fragments as a demonstration of the issue I am having...The user clicks the nav drawer button, which opens the master fragment that hosts a list of articles. Once a user clicks one of those articles, I then open the detail fragment inside of the master fragment. So If I find myself at the detail, and I decide to open the nav drawer and click the third button for instance, then click the second button again, I want the detail to be open still, and if I hit the phone's back button I want it to move back to the master fragment, and end there. Any tips will be helpful, as I am probably going to use a similar pattern for the first button, it's main fragment and it's children fragments as well.
In my opinion, the cleanest way to handle what you are describing would be to have three separate FragmentActivity classes that implement the DrawerLayout instead of one monolithic BaseActivity.
Each button in the drawer should start it's respective FragmentActivity using launchMode singleTask. This ensures that you launch the same activity instance each time, instead of a new one, which will maintain your back stack for each activity as you switch between them using the drawer buttons. See Android Developer Guide Activity:launchMode for more details.
Each of the three FragmentActivity instances should be responsible for starting and managing it's fragments using listener interfaces. For example, where you have your Master fragment opening a Detail fragment directly, you should instead have your Master fragment tell it's FragmentActivity that it needs to open the Detail fragment. See Android Developer Guide: Communicating with Other Fragments for recommended practices in implementing this type of decoupled communication between FragmentActivity and Fragment. It will make your life much easier down the road when you want different layouts for tablets, etc.
Each of the three main drawer "tasks" seem to be unique enough that isolating each within it's own FragmentActivity seems the best way to implement what you are trying to do. You can apply this same approach for each of your main sections.
I had the same problem and didn't want to go to multiple activities since that would complicate the back navigation of my application. Your fragments won't save their state automatically unless the activity lifecycle events are being called.
In our case those don't happen since we're not leaving the activity. You can use FragmentManager's saveFragmentState on the fragment you are replacing to manually trigger the state saving and get a Fragment.SavedState object. You can keep a list of your SavedState objects and when pushing a fragment check if you have a saved state for it. If so you can call Fragment setInitialSavedState which will cause your fragment to load the previous state.
Now in my app as a user toggles between fragments with their own child fragments the state is retained when they come back.

Categories

Resources