Using Fragments instad of separated activities - android

im going to write a little android app. Nothing complicated, with 6 "screens". 4 of them are on the same view navigation hierarchy level. 2 are subscreens of one of those 4.
For example screen A displays a list with information. By clicking on a list item the app will show screen A1. Screen A1 displays details about the previously selected list item. So Screen A1 is a subscreen of screen A. By clicking on the back button the app shows screen A.
Screen B has also a subscreen, called B1. The other screens are C and D which are on the same view navigation hierarchy as A and B (but not A1 and B1). So A, B, C, and D are on the top of the view navigation hierarchy. The App will start with displaying screen A. In the action bar (or in a sliding menu) you will find buttons to jump to screen B, C and D.
I hope you got an idea of what im trying to do. So normally I would say, every screen is a own activity. Im a big fan of fragments and i normally use them everywhere. In fact I caught myself implementing activities that contains only one fragment, that contains the main view layout. And I can say there is absolutely nothing wrong to do so (Fragments bring big advantages ... )
But now I wonder if it would be a good idea to use a single main activity and change only the fragments in this activity. So screen A, B, C, D, A1, B1 are Fragments instead of activities. So by navigating from Screen A to C I would simply replace fragment A with fragment C in the main activity (instead of starting a new Activity that contains the fragment C). The same way I would implement a navigation from screen A to subscreen A1.
So far I can't see nothing wrong with this approach. In my opinion it would be something like a ViewPager, just without swipe gestures to navigate between screens.
The only thing Im not sure about it (and thats my question) is the memory management. Whenever I do a replace fragment transaction (fragment manager) to navigate from screen A to B the fragment A should be destroyed and the memory should be garbage collected (somewhere in the future), right? When do I instantiate Fragment B? When the user clicks on the button to navigate to B (and repalce A)? Could this bring performance issues (time to instantiate the fragment)?
What if I set all fragments A, B, C, D, A1 and B1 to setRetainInstanceState(true)? Than the class member fields of each screen will be hold in the memory until the MainActivity is finished right?
Does anyone of you have experience with that?
A ViewPage uses some kind of "preloading" fragments and loads only the view layout of the next and previous fragment (setOffscreenPageLimit() )
Do you guys think I have to do something similar to avoid memory and performace issues?

Related

How to retain state of a fragment while switching between different fragments

I have an activity consisting of 3 fragments and a bottom navigation view which navigates the user to different fragments.
Let say the fragments are A, B and C.
The issue I am facing is that if I have performed some operation in A, and I navigate to B, then, when I again navigate to A (from bottom navigation view and NOT backpress) , the operations performed on A are lost, which I don't want.
For eg, in Youtube application, after searching something on Home fragment, if I navigate to "Subscriptions" or "Library", then if I renavigate to "Home", the search results are retained and also the state of the screen.
Kindly guide me how to achieve the same in my application

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.

How to scroll to the top of a ListFragment

My situation: I have two ListFragments (call them A and B) managed by one Activity which keeps persistent references to both of these Fragments. When I click a button in Fragment A, I replace that with Fragment B. The problem starts when I do the following flow.
A -> B -> (scroll) -> (back button) -> B
In that case, when I go back to Fragment B the second time, the previous scroll position is maintained, which I don't want. Instead, I would like for Fragment B to start with its ListView at the top of its content.
Things I have tried which do nothing:
Calling setSelection(0) in onActivityCreated
Calling setSelectionAfterHeaderViews() in onActivityCreated
Calling smoothScrollToPosition(0) in onActivityCreated
Interestingly, all of these work if I post them on a Runnable. However, when I do that there is a weird flickering the second time I open Fragment B.
So, how do I get Fragment B to automatically scroll to the top each time it is attached to its parent Activity? I feel like there must be something blindingly obvious that I'm missing, but I'm really stumped right now.
You're calling the right methods, but you're calling them in the wrong place.
I assume you have code that switches between the fragments and you call it when an item is clicked in A. So whenever you do the switch set the scroll to the top, something along these lines:
protected void switchList() {
ListFragment a = (ListFragment) getFragmentManager().findFragmentByTag("a");
ListFragment b = (ListFragment) getFragmentManager().findFragmentByTag("b");
b.getListView().setSelectionAfterHeaderView();
getFragmentManager().beginTransaction().hide(a).show(b).addToBackStack(null).commit();
}
And one important note: never keep persistent references to fragments in your activities. Whenever you need a fragment get it from the FragmentManager. This is crucial since on configuration change (like a device rotation, or when your app is suspended and restored) the fragments are recreated, and the reference you kept leads to a 'dead' fragment. Not only is it a major leak, it will also prevent your code from functioning. any change you make to the saved fragment is not reflected on the screen because the screen holds the newly created fragment.

Android SDK Fragments -- retain State over multiple activities

I am developing an application where i have a main activity consisting on the left of a fragment showing products. Depending on the selection, the right part of the landscape-view shows detailed information, where the product's properties can be thoroughly specified. This is the case if the application's running in landscape-mode. If the orientation changes to portrait-mode, then the user first selects a product and then specifies the product's properties by individual dedicated activities, where each activity contains exactly one fragment of the previously mentioned landscape-view.
The problem now comes when I rotate my screen during runtime. Assume that I started the application in portrait mode, and I select the first product (Activity A, Fragment A). The next screen (separate Activity, call it Activity B) will contain a Fragment B where I can specify Property 1 of the product. Now I rotate the screen. The application will then show the landscape-view where the first product is selected, and ALL fragments dedicated to product configuration are shown at the right. Is there a solution that I can retain the configurations done by the user in the separate activity (i.e. Fragment B, Activity B) in such a manner that the land-scape view receives the state such that the details view can properly show the hitherto done configurations?
To summarize:
I am in Activity A, just containing a list of products (Fragment A)
I select the first
then I get to a new Activity B, where Fragment B is shown
then I rotate my screen
then I get back to Activity A, now containing at the left side Fragment A (the list) and at the right side (among others) Fragment B.
I want the state of Fragment B in Activity B be available in Activity A, Fragment B.
Hope I could completely specify my question.
TIA
Gerald
There are 2 solutions that I could think of right now:
Forget about 2 Activities in this case, and solve this scenario with only 1. I had multiple projects with exactly these requirements. In portrait mode, I used a ViewSwitcher or a ViewFlipper to show Fragment A or Fragment B full-screen. On landscape, things remain the same you described. This way the 2 fragments can communicate with each other, Fragment B may update the selection on Fragment A.
Start Activity B with .startActivityForResult(), so it may supply a result for Activity A, containing the current selection.

Android FragmentTransaction, ActionBar Tabs, and Multiple Fragments

So, I am building a tablet app with the compatibility library and have run into an oddity I can't seem to figure out. All in one activity, I have 2 tabs (Tab A and Tab B), and 3 Fragments (Fragments A1, A2, and B). The ActionBar.TabListener associated with Tab A handles the adding and removing of Fragments A1 and A2, and the ActionBar.TabListener associated with Tab B handles the adding and removing of Tab B. So far so good.
The strange behavior is exhibited when I launch the activity (so Tab A is selected and Fragments A1 and A2 are displayed from left to right, correctly) click on Tab B (so Fragments A1 and A2 are removed and Fragment B is shown, still correctly) and then click back on Tab A!
Now, Fragments A1 and A2 are showing, but in the reversed order: A2 and then A1!
Has anyone experienced this oddity? If I select Tab B and then Tab A again, they reverse again to be in the correct order, and the cycle continues. According to this article, "If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy", which strangely doesn't seem to be the case now does it.
Any ideas? Thanks in advance!
According to this article, "If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy", which strangely doesn't seem to be the case now does it.
Personally, I wouldn't count on that.
For example, let's assume that you are using a horizontal LinearLayout. Your current code presumably is putting both fragments in the LinearLayout. The way I approach it is to have two FrameLayouts already in the LinearLayout, and to put each fragment in one of the FrameLayouts.

Categories

Resources