Fragment advice is misleading. #10

Open
jacobtabak opened this Issue Oct 29, 2014 · 4 comments

Projects

None yet

5 participants

@jacobtabak

I use Activities, Fragments, and custom views, depending on the context. I don't think it's wise to recommend the Fragment approach as a catch-all solution.

Proper screen-to-screen communication. Android's API does not provide a proper way of sending complex data (e.g., some Java Object) from one activity to another activity. With fragments, however, you can use the instance of an activity as a channel of communication between its child fragments.

If you're relying on non-parcelable/serializable POJOs, how do you retain instance state if the user switches to another application? Speaking of that, there's no mention of instance state, parcelable, or serializable in the doc.

Many Android classes expect fragments. The API for tabs on the ActionBar[1] expects the tab contents to be fragments. Also, if using Google Maps API v2, the recommended solution is MapFragment, even though MapView exists.

The ActionBar Tabs API is now deprecated. There's no benefit to use MapFragment over MapView.

Easy to implement swiping transitions between screens. If a UI screen is a fragment in your application, you can use FragmentPagerAdapter to contain a collection of fragments and implement smooth and interactive transitioning between them. For instance, horizontal swiping of screens.

ViewPager has nothing to do with Fragments. It's trivial to implement your own PagerAdapter, the only reason why one is provided in the support lib for fragments is because fragments have such a complex lifecycle.

Also, Fragments don't support some complex transitions. "The Z adjustment only works for window animations. I thought this was documented, but apparently not." This means you can't do things like fade out one fragment and slide in the other from the right, because the outgoing fragment might be rendered above the incoming one.

Intelligent behavior for "back"

The fragment back stack is far from intelligent. You can't remove an item from the back stack unless it's on top, you can't pop the back stack without triggering an animation without hackish workarounds.

@Wapples
Wapples commented Oct 29, 2014

@jacobtabak I agree 100%.

This section sounded like it was written by the dev who wrote the Android Plugins for Eclipse.
Fragments are powerful and flexible no doubt. But they should not be seen as a silver bullet for every UI.

@staltz
Member
staltz commented Oct 29, 2014

Thanks @jacobtabak for the "other side of the coin" type of feedback. A couple of developers from our company gathered to discuss how a typical app should be structured, and we converged on a Fragment-based architecture. This is not to mean it's a silver bullet for every situation, and it's true the advice can be misleading.

The whole Activities vs Fragments vs custom is a hot debatable issue in the Android community, so we try to give a "good enough" starting point for new developers. We'll talk about this internally in our company, but we're open for PRs and suggestions on what to advise.

@jacobtabak

There's certainly a benefit to having a consistent architecture in your application, and the fragment approach is not a bad one, but I take issue with many of the points you've listed for the reasons above. I feel like the only two points that stand up to scrutiny.

I'm not suggesting that you withdraw your recommendation for the fragment approach, but I think you should prune your list to only the arguments that stand under scrutiny.

Specifically, I'd revise or remove the following, and I'll differentiate this from my criticism above with more specific feedback about what I believe should be changed and why.

Many Android classes expect fragments. The API for tabs on the ActionBar expects the tab contents to be fragments. Also, if using Google Maps API v2, the recommended solution is MapFragment, even though MapView exists.

Definitely remove the comment about ActionBar Tabs since it's been deprecated and perhaps find another example that's more relevant. Maybe go into detail about why the MapFragment solution is easier to use than MapView - with MapFragment, you don't need to explicitly invoke the lifecycle methods (onCreate, onResume, onPause, etc), but there's no advantage other than that.

Easy to implement swiping transitions between screens. If a UI screen is a fragment in your application, you can use FragmentPagerAdapter to contain a collection of fragments and implement smooth and interactive transitioning between them. For instance, horizontal swiping of screens.

What you're describing is the ViewPager class which has no dependency or relationship to fragments other than that there are Fragment pager adapter. I object because it's perpetuating beginners' misconception that ViewPagers only work with fragments.

Intelligent behavior for "back". The FragmentManager allows you to perform transactions to change the fragments inside an activity. Hence, the FragmentManager manages the "state" of fragments. The back button/action will be handled by the FragmentManager to go back to the previous "fragments state". This is more advanced than the activity stack.

What specifically makes it "more advanced" than the activity back stack? In my opinion, the activity back stack is much more flexible with different activity launch modes. I personally haven't found a use case for the fragment back stack, it is way too inflexible, and works very poorly when replacing fragments.

Even the ActionBar can be managed from within fragments. You can choose to have one Fragment without a UI with the sole purpose of managing the ActionBar, or you can choose to have each currently visible Fragment add its own action items to the parent Activity's ActionBar. Read more here.

I don't believe this is an advantage, managing the action bar with fragments doesn't provide you with anything that managing the action bar from an activity does not.

@staltz staltz added the bug label Nov 3, 2014
@andreidiaconu

The part about Fragments was a "surprise" for me.
So for an app that has a couple of screens (list of products, product details, product search, checkout, profile) I should consider having one, big MainActivity with lots of Fragments?
Doesn't this activity become a God class really fast? Am I not going to have problems when the activity gets killed, recreated, etc? I know, a non-ui fragment can be used - but what about activity-kill situations not related to configuration changes?
If every screen I see is a Fragment, aren't nested fragments going to be something very common, for any non-trivial layout(consider having a gallery in the product page or having a screen with multiple tabs)? And after telling us to use fragments for everything you tell us to avoid nesting fragments; that is just funny.

I would dial it down to the point where this is a good idea, just to keep the code DRY; but to have a single activity for the whole app is a bit of a stretch. Why not just use the Application class for the POJOs if having them available across the app was the problem?

Anyway, the rest of the document is really good and I just ate it up, but I'm quite sure that the part about fragments is at best an opinion - and not even a very popular one, according to all the StackOverflow disputes on the subject.

Sorry if my opinion upsets you in any way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment