Fragment stack: push/pop Fragments from top fragment - android

Support4Demos feature Fragment stacks... but conveniently place the pop/push CountingFragment controls outside of the stack (all takes place in one layout, but the push/pop buttons are below, still in the Fragment that holds the whole layout.
How can the controls be made to work from the top fragment?
[EDIT]
Another way to look at it:
I want to make Fragments on a stack behave like Activities, each can pop itself, or launch another.
How would you alter the "FragmentStack" example from Support4Demos so that the "Go home"/"Add new"/"Pop top" buttons are in the CountingFragments, rather than in FragmentStackSupport which holds the FragmentManager?
A reasonable design - consider "CountingFragments" containing clickable ListViews?
How to do that? Ideally, each stack Fragment would hold a reference to the "stack holder' Fragment, or its (Child)FragmentManager. Those, however, are not Parcelable, and Fragment constructors must not be used (though everything else works great when I do it). Holding a reference to that is also bad, since the "stack holder' Fragment, too, can be destroyed and recreated.
[EDIT2]
All right, here are some ideas I came up with.
For "go home" and "pop top", I suppose I could add those (invisible) buttons to the hosting Fragment, and then access them in the hosted Fragments via getWindow().getDecorView().findViewById or somesuch.
That's ugly enough. But pushing new ones? Only related thing I can think of is adding a custom View class into the hosting layout, that holds a reference to the FragmentManager, to be grabbed by the hosted Fragments.
holding references to the FragmentManager(s) in a static map somewhere
register a BroadcastReceiver in the hosting Fragment, send broadcasts with data from the hosted ones, telling it what to do. But the host Fragment shouldn't have to babysit its children.
Have each stacked Fragment itself be host to either its true content, or the next stacked Fragment. That way, there is always a FragmentManager at hand (except for popping), but 2 fragments are needed per page, not to mention the weirdness of it all.
Please tell me there is a cleaner way.

Related

Transitioning from Fragment A to Fragment B using two recyclerviews?

Right now I've Fragments A with Recyclerview - where I've categories (Image+text).
I want to make Fragment B with Recyclerview - where I've types (Image+text). Same layout, same everything except text/image.
Like this:
https://img.exs.lv/e/z/ezeliitis/frags.png
For instance, I click on Fragments A - first picture (Cars) and it opens Fragments B - in same layout as fragment A, which contains (AUDI, BMW, OPEL ect...). Should I just make copies of fragment A (adapters/viewholders ect.) changing db names/pictures or is there some way to "DRY" the code? Also, isn't it bad having two recyclerviews (performance) ?
Also, movement from one fragment to another is called fragments "..."(what exactly?)
Same layout, same everything except text/image
You must need to replace the RecyclerView adapter, then. No need to start another Fragment, but you're more than welcome to.
isn't it bad having two recyclerviews (performance) ?
Not that I know of. You'd only have one at a time, from what I understand anyways.
movement from one fragment to another is called fragments "..."(what exactly?)
If you do need to switch Fragments, then you want the FragmentTransaction class of the host Activity. That's how you switch. Documentation is pretty good with its example.
https://developer.android.com/training/basics/fragments/communicating.html

Show nested fragment on screen rotation without showing parent fragment

When rotating the screen my nested fragment is shown but for some brief moments, the parent fragment is also shown.
I have my MainActivity that has a FrameLayout with ID activity_base_container.
I'm doing this when my activity starts:
Fragment initialFragment = getInitialFragment();
mFragmentManager.beginTransaction()
.add(R.id.activity_base_container, initialFragment, initialFragment.getClass().getSimpleName())
.commit();
That initialFragment initial fragment is responsible to check some conditions and depending them will launch one of two possible fragments:
fragmentManager.beginTransaction().replace(R.id.activity_base_container, fragment, fragment.getClass().getSimpleName()).commit();
Lets assume it launches FragmentF (whit a root FrameLayout with id fragment_f_root). This fragments layout has a set of options. When the user clicks one of those options, the corresponding fragment is created and is launched like this:
//The example here is an option that displays a google map.
fragment = FragmentMapMultipleActivity.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.fragment_f_root, fragment)
.addToBackStack(fragment.getClass().getSimpleName())
.commit();
At this point all is working as expected. The problem is when I rotate the screen. FragmentF appears briefly and then immediately FragmentMapMultipleActivity, the nested fragment, appears.
Is it possible after rotating the screen show only the nested fragment or I should change my "architecture" to something else?
should change my "architecture" to something else?
Probably, you should.
The brightest Android-minds from Square are even advocating to avoid simple fragments everywhere it's possible: Advocating Against Android Fragments
Nested fragemnts, in its turn, increase complexity exponentially. The only good pattern of using them I've seen so far is ViewPager with it's FragmentPagerAdapter. In majority of other cases, consider using Custom Views instead.
It keeps your app's lifecycle cleaner and more predictable.
I don't think you can do much with this blinking you see, apart from:
setRetainInstance(true) and avoid full re-creation of the Fragment in Activity, so you keep you fragment's data during change of the configuration (and then pass same retained fragment to the fragment manager)
keeping layouts as lightweight as possible
avoid re-creation of already initialized variables
keep onViewCreate() as lightweight as possible
Good luck!

What are the advantages of creating a Fragment vs Extending a View or ViewGroup?

We recently converted an app from a multiple activity based one, to one with a single activity with multiple fragments. The activities that became Fragments used to contain fragments themselves, so we use child fragment managers to host the Fragments in the Fragments (these child fragments I should add, are small and there can be 4 or 5 these on the screen at one time).
This has caused a few issues, namely having to create, and keep track of Unique IDs for the Fragment holders. (Which cause headaches when dealing with the Backstack as well as if any are in any sort of AdapterViews).
We're thinking of just rewriting these components to extend some sort of ViewGroup, likely FrameLayout or LinearLayout. We already do that anyway in some cases, but I was wondering if there are any disadvantages to doing it that way? (I must admit, I don't really see the big deal about Fragments... anything you can do with Fragments, you can do by creating a Custom View. Is this wrong?).
This is a bit of a reverse answer, explaining fragment use. In general you can do most things with Activities, but as the SDK supports fragments, many things will become more cumbersome (ViewPager is an example where fragment use is great).
The advantages (of fragments): code encapsulation, reusable chunks of UI.
The disadvantages (of fragments): more code (e.g. FragmentManager, FragmentTransaction).
Your original use of activities was good, it's not a case where I would have switched to fragments.
Let's say I designed a mobile phone app with two activities: ContactList and ContactDetails. So far so good, no reason to use fragments yet. If I wanted to support a larger device, it would behoove me to display both screens side by side. This is where fragments come in handy. In terms of exactly how to structure your activities/fragments, there's some good advice here:
https://developer.android.com/guide/practices/tablets-and-handsets.html#Fragments
Here are the important bits:
Multiple fragments, one activity:
Use one activity regardless of the
device size, but decide at runtime whether to combine fragments in the
layout (to create a multiple-pane design) or swap fragments (to create
a single-pane design).
Or...
Multiple fragments, multiple activities:
On a tablet, place multiple fragments in one activity; on a handset,
use separate activities to host each fragment. For example, when the
tablet design uses two fragments in an activity, use the same activity
for handsets, but supply an alternative layout that includes just the
first fragment. When running on a handset and you need to switch
fragments (such as when the user selects an item), start another
activity that hosts the second fragment.
.
The approach you choose
depends on your design and personal preferences. The first option (one
activity; swapping fragments) requires that you determine the screen
size at runtime and dynamically add each fragment as
appropriate—rather than declare the fragments in your activity's XML
layout—because you cannot remove a fragment from an activity if it's
been declared in the XML layout. When using the first technique, you
might also need to update the action bar each time the fragments
change, depending on what actions or navigation modes are available
for each fragment. In some cases, these factors might not affect your
design, so using one activity and swapping fragments might work well
(especially if your tablet design requires that you add fragments
dynamically anyway). Other times, however, dynamically swapping
fragments for your handset design can make your code more complicated,
because you must manage all the fragment combinations in the
activity's code (rather than use alternative layout resources to
define fragment combinations) and manage the back stack of fragments
yourself (rather than allow the normal activity stack to handle
back-navigation).

Use View or Fragment in ViewPager

I have a question about whether to use View or Fragment with ViewPager.
Background:
I have an Activity A that contains a ListView. Each ListView item opens Activity B. Activity B shows different content depending on which ListView item is tapped in Activity A.
Activity B's content is shown inside a ListView.
Question:
Now, instead of going back and forth between Activity A and B to switch contents, I have a requirement to implement horizontal view swiping to switch contents all within Activity B.
One solution I found (tried it and it works) is to create many instances of Activity B's ListView and use it with ViewPager + PagerAdapter.
Another potential solution found on the doc (haven't tried it) is to bring that ListView into a Fragment, create many instances of the fragment and use it with ViewPager + FragmentPagerAdapter or FragmentStatePagerAdapter.
My question is, what's the benefit of using each approach? Should I go through all the trouble of bringing the ListView into Fragment or just simply use ListView with ViewPager?
Thanks
A Fragment is a useful approach, I think, when you want to tie some UI business logic to a particular View (or group of). As you know, that individual Fragment has its own lifecycle callbacks and so forth, just as an Activity would.
Rather than having a single Activity host many ListViews through a single PagerAdapter, it may be cleaner to use the Fragment approach because the Fragment only needs to deal with the logic behind driving a single ListView.
This is a very similar situation to one I've just been facing. I'm showing various vertically scrolling forms (consisting of lots of input fields) within a ViewPager. In my case I have gone for the Fragment approach because in my case, it's possible that the ViewPager will actually need to display a completely different kind of view on certain pages. For example, on the first few pages, user input forms might be displayed. But on the final page, a graph will be displayed. A whole separate set of logic is required to drive that graph. To drive those input forms and one graph from a single Activity would get a bit messy, and I would probably need to contain the business logic in several delegate classes or something. So for me, Fragments were the obvious choice in the end. I have my InputFormFragment and a GraphFragment, and they each contain only the applicable logic for the Views that they supply.
Another thing to consider is that in the near future you too may want to display a different kind of View in your ViewPager. Or, you might want to have another UI layout altogether, perhaps one that doesn't use the ViewPager but displays them all side-to-side (e.g. a layout used on a large tablet in landscape mode). With Fragments, things are just far more modular and you could factor the code to do this quicker. If on the other hand you achieved your objective by using a single Activity that contains a simple PagerAdapter and all the logic for the ListViews within, you might find it takes more work in the future to support new kinds of Views or special tablet layouts.
One thing I will say is having implemented Fragments in a ViewPager myself through FragmentPagerAdapter and FragmentStatePagerAdapter, things can get a bit awkward if you have any special requirements; managing Fragments can be tricky sometimes. For example, for my UI I needed to be able to programmatically add and remove the ViewPager containing the Fragments. I also needed to ensure that the adapter in use didn't destroy Fragments once they had been shown, because I needed to collect data from all Fragments simultaneously at a certain point. Furthermore, I had to extend and modify FragmentPagerAdatper to make sure that the Fragments go through their onDestroy() properly and are removed from the FragmentManager when the ViewPager was removed.
Fragments enable a very modular way of constructing UIs for various screen sizes and orientations, and are excellent in how they allow you to encapsulate business logic and lifecycles for individual UI elements. However if your scenario really is just as simple as several ListViews in a ViewPager and you know that you will never need the modularity, then the overhead of Fragments could be an overkill.

Views communicating with fragments

I am trying to make a sudoku application. It's a fragment based design, in which a fragment hosts a custom view which is a board. I am trying to learn how to build an effective communication within FragmentActivity, Fragment and View
Although a view is created using the FragmentActivity context and I can catch a reference to that context within the current view and then call methods inside FragmentActivity I don't want to tie views so directly to a fragment activity. Instead I want to tie the view to use methods inside a fragment. How can i do that, I can I capture a reference to a fragment and call methods inside that fragment from a view?
First of all, I strongly recommend that you read through the documentation on Fragments, as you clearly don't understand the whole concept/purpose of using Fragments in the first place (which is OK, because they are confusing the first time you learn them :P).
A lot of your question doesn't make very much sense to me, because I'm not sure what the View you are speaking of refers to. What I can tell you is that Fragments have their own UI/layout, along with their own separate lifecycle. So it sounds like you don't want your FragmentActivity to interact with the Fragments layouts/methods at all... instead, you should implement the UI's behavior and layout inside of the Fragment itself. That is, the Fragment will be in charge of updating the UI, receiving click/touch events, displaying information on the screen etc. The FragmentActivity will simply hold a reference to the current Fragment(s), and will be in charge of displaying/swapping in and out new Fragments as necessary (via the activity's FragmentManager).
Hope that answers the question somewhat... read through the documentation a couple times, it sounds like you are just misunderstanding the theory/purpose behind Fragments.

Categories

Resources