Correct way to close fragments - android

There're two parts to this question.
Suppose we have an Activity and then two fragments: a ListFragment and a Fragment (which will be shown when you click an item from the ListFragment).
Part 1
Where should I close the fragment? By this I mean what would be considered good from a design point of view. I see two options: one declaring an interface in the fragment and having the activity implementing it, let's call it closeFragment(). This would be a way to communicate from the fragment to the activity like shown in the Dev Site. The other one is probably quite simple and is calling getActivity().getSupportFragmentManager() and using the manager to close it.
Part 2
I know how to create a fragment and replace it since it's on the Dev site but I have doubts about closing one. How should I actually close it? Is something like the following code correct? Suppose that the fragment was added to the BackStack.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
getSupportFragmentManager().popBackStack();
transaction.remove(this);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
transaction.commit();
Thank you very much.

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(this);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
ft.commit();

I would prefer having a dumb fragment , which don't know anything about where it is being used , so that you could use it on any activity you wish , and it would have the precise goal you've set for it . Of course , you can do whatever you wish .
This looks like closing it , but I would prefer replacing it instead . You can also always return to the fragment as long as you have a reference to it .

Related

Fragments lifecycle

I'm learning about fragments I have some doubts. Consider following code:
FragmentManager fm = getFragmentManager();
Fragment MyFragment = new Fragment();
fm.beginTransaction().replace(R.id.my_container, MyFragment).addToBackStack(null).commit();
My question is:
what exactly does replace do?
What happens if I create many fragments this way (to replace previous ones in a container).
Can it in any way be bad for memory usage?
Is it considerably better just to change fragment's content?
Replace removes all the fragments that are in the container and adds the new fragment to the container. (if there isn't a fragment in the container then it just adds the new one).
If you create many fragments this way then every transaction is saved to the backstack so you can reverse the transaction by pressing the back button.
The only thing you can do is to create a variable fragmentTransaction and use the fm.beginTransaction() only once and not every time you want to replace the fragment in the container.
I don't think so, fragments should be modular and reusable.
You can read more here:
https://developer.android.com/guide/components/fragments.html
it simple put another "layer" on container.
appcrash
yes
No, fragment is the easiest way.
Using fragment & backstack tag to reference to a Fragment if you want to call fragment again and process Back button.
fm.beginTransaction().replace(R.id.my_container, MyFragment, "FRAGMENT_TAG").addToBackStack("FRAGMENT_BACKSTACK_TAG").commit();

Android fragments and creating new instances of them. Do you always need a container?

Fragments is something that I am still trying to understand, I get some of it but not all of it.
My question is, do i need a container to start a new fragment instance?
This is what I have been currently doing to launch a fragment from my current activity that i have a container in.
FragmentManager fm = getActivity().getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(container.getId(), new OtherFragment());
ft.commit();
So my main activity has a container where I can switch from 4 fragments. Now lets say I click on one of the list items in my 3rd tab. That launches a new activity that shows another listview. Then if i click on the item on that listview, i launch a new activity. Then, were it says "tap for more information", I will be launching a new activity (I haven't created this yet, and that is why I am asking this).
But I feel like it could just be launching fragments instead of activities. If so, how do I go about doing that, because I feel like I need some type of container to put it in since I have tried launching a newinstance of a dummy fragment class i created it but it doesn't launch. If not, how do i just create a new instance of it without a container, if possible.
Or do I only use fragments whenever they will be similar and will have a container to be put in??
And I could do fragmentActivity, but that is almost the same as Activity. The reason I ask is because we shouldn't have so many activities, right? or does having as many as activities as you want not affect the project performance? Because right now I usually create activities for everything, unless its like the first picture where I will have something similar that can be put into a container.
Thanks.
You're going to to pretty much the same thing that you did to show the first fragment.
FragmentManager fm = getActivity().getFragmentManager();
if (mDetailFragment == null)
{
mDetailFragment = new DetailFragment();
}
FragmentTransaction ft = fm.beginTransaction();
ft.replace(container.getId(), mDetailFragment);
ft.commit();
You're going to want to keep references to your fragments so you're not creating them new every time. To improve the user experience you can add animations to the transition and, if it makes sense, add the fragment to the backstack.
ft.addToBackstack("OtherFragment");
ft.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.popEnter, R.anim.popExit);

how can i back from one fragment to another fragment in android?

I am used to developed my applications fragments I have one problem
I am replacing fragments like
A -->B --> C --> D -->E -->F
How can i return back like
A <--B <-- C <-- D <--E <--F
I am using code like
getActivity().getFragmentManager().popBackStack();
this worked fine but some times closed app without cross
is there any solution i dnot how to slove the problem due have any idea please guide me
Advance thanks all``
With no code available I just post what it's working for me:
when switching from a Fragment to another i use this (if you aren't using the support libraries you have to remove the 'Support' prefix):
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.fragmentContainer,
MyFragment.newInstance());
transaction.addToBackStack(null);
transaction.commit();
The addToBackStack adds the fragment to the backstack... so when you press back button the previous fragment will pop up.
Hope it helps.

Best practice for keeping Fragments for later display

I have an activity with a FrameLayout in it.
The activity should show four steps, and each step is a Fragment. When I want to go back-further, I don't want my fragments to be recreated. I would like to retain them and simply replace their view in my fragment.
I used to first create my Fragments and add them in the backstack like this:
Fragment step= new Frag1ActCompleteFragsCommTrack();
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.add(step, ""+onStepNr);
ft.addToBackStack(null);
ft.commit();
notice that I don't show it, I simply create it and add to the backstack.
So, once I need one of my fragments to show, I add it (in this example I don't remove any fragment from the framelayout just because it's my first add):
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.add(R.id.my_frameLayout, step);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
So: the problem is that I obtain a
Caused by: java.lang.IllegalStateException: Fragment already added: Frag1ActCompleteFragsCommTrack{410dcb20 #0 id=0x7f050041 -1}
But I think I can't add directly into my framelayout the first time, otherwise the next time I replace it, I could lose my fragment. Am I right? So.. what's the best practice for retaining fragments that could interchange each other in a framelayout?
Ladies and gentlemen, I did it!
If you add a Fragment, and you want it to be shown in a framelayout, remember to put it in the Fragment backstack. That's it! If you replace it in the framelayout with another one, no worries: you can put it back by finding it thanks to its tag.
It was easier than I thought actually
//step is an int describing the step associated to the fragment I wanna place
FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
ft.replace(R.id.act_complete_track_frameLayout, f, ""+step);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if(firstAttach)
ft.addToBackStack(null);
ft.commit();
imagine a fragment with tag "1" replaced through the code above by a fragment with tag "2". If I want to go back to step1, I reuse that code by obtaining my old fragment with getSupportFragmentManager().findFragmentByTag("1")
To be short, I thought that FragmentTransaction.replace removed the fragment from the backstack as well. That seems not to be the case (luckily)
You can always do something like fragmentManager.putFragment(yourFragment);
If I understand correctly, you are trying to add all the fragments but not show them until you are ready. FragmentTransaction.add() doesn't exactly do that though. It will also be shown after its added. You should use hide() after adding each fragment, and then later you can use show() to make it visible, and hide() again to make other fragments invisible.
Like this:
Fragment step = new Frag1ActCompleteFragsCommTrack();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(step, ""+onStepNr);
ft.hide(step);
ft.commit();
Then later:
Fragment step = getSupportFragmentManager().findFragmentByTag(""+onStepNr);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.show(step);
// may want to hide other fragments here
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();

Retain the view on fragment tab change

I have a tabbed application, say 2 tabs. It was initially developed using ActivityGroup. However, having realized that multi-panes are not supported in ActivityGroup, I decided to use fragments. Before going to the problem, let me brief you about the application.
So, like I said before it is a tabbed application
TabA---> Activity1---> Activity2---> Activity3
TabB---> Activity4---> Activity5----> Activity6
This is the work pattern of my old activity-group based app.
Now with fragments, this would change into something like below
FragmentActivity---> TabAFragment---> FragmentA1---> FragmentA2
|
---> TabBFragment---> FragmentB1---> FragmentB2
Each fragment connects to server for data on initial load.
And in the transaction, I replace fragment every time I add.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.realtabcontent, fragment);
ft.commit();
What is observed
I have only one activity(FragmentActivity-where tabs are created) for those two tab fragments. I share this activity for all tabs. For instance, I load fragmentB1 in tabB- inflates a view, fetches data from server and displays in a ListView. Then I switch to other tabA and loads fragmentA1. So far so good. Now if I go back to tabB, I want to see the listView which was loaded earlier. What happens is it starts everything from square one.
This is my first-hand experience with fragments. I did a bit of research; however it didn't really help fix mine.
How can I retain already loaded view?
Any thoughts?
Hi I'm fairly new to all the fragments also. However, I was doing something similar and found that I needed to add the current fragment to the back stack like so.
ft.addToBackStack (null);
This line would go just before your comit so your code becomes:
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.realtabcontent, fragment);
ft.addToBackStack (null);
ft.commit();
Hopefully this is of some use.

Categories

Resources