Android - adding fragments dynamically - android

I have looked around the internet and I have found only examples of Android fragmens, where they are placed on place (like two of them, one as a list, second is diplaying details of a selected item from list). My goal is to have classic android activity and I want to be able to add to it dynamically pre-prepared fragments with particular GUI. I want to add there dome group of EditText elements (editTextFragment), or several radiobuttons (radionbuttonFragment). Is there any example of how to do that? Making stable fragments is not usable for me.
Thanks

This answer is for those who all searching the answer for same question.
The answer is achieved by FragmentManager and FragmentTransaction with the following syntax.
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
then you need to add your fragment to this fragmentTransaction with the following syntax.
fragmentTransaction.replace(R.id.detailFragment, layout1);
And finally you MUST commit your transaction. Otherwise changes will not persist.
fragmentTransaction.commit();

Fragment and views are very similar so think similar... Also look at google api demoes for fragments. If I remember correctly they use a framelayout and adds fragments to it.

You can add and remove fragments to a FrameLayout in an activity's UI programmatically but your activity must extend FragmentActivty. Once you have created fragment classes and corresponding layouts, instantiated fragments can be added and removed via the FragmentManger and FragmentTransaction. See the section "Performing Fragment Transactions" in the Fragment documentation.

Related

Android: Hide viewPager tabs when launching a fragment from one of the viewPager tab fragment

I have a viewPager in my app which has several tabs. In some of the tabs, on clicking an item a new fragment is shown. I want this fragment to cover the tabs. Doing this is possible but the approaches don't look good to me.
1.) one way is that I add the newly created fragment to the activity using getSupportFragmentManager(). This solves the problem but doesn't look like a good idea as it will create problems when using back button etc.
2.) Other way is to hide the tabs manually using Visibilty.GONE but problem with this approach is that this hiding of the tabs is visible, I mean the animation could be seen and looks bad.
Is there a better approach to do this problem?
This is my code. "sub_fragment_container" is present in the activity xml, so I get an error java.lang.IllegalArgumentException: No view found for id 0x7f0e00ff (com.my.app:id/sub_fragment_container) for fragment DetailFragment{
FragmentTransaction fragmentTransaction = getChildFragmentManager()
.beginTransaction();
Fragment profileFragment = new DetailFragment();
profileFragment.setArguments(bundle);
fragmentTransaction
.add(R.id.sub_fragment_container, profileFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Use android:animateLayoutChanges="true"
Or, to fine tune it further, here's a tested method that I've personally used in my app Newslet to solve the exact same problem.
Wrap your Toolbar and TabLayout within an AppBarLayout. This should be easy if you're aware of the Design Support Library. If not, this should get you started.
Add this piece of code in your onCreate():
LayoutTransition layoutTransition = new LayoutTransition();
layoutTransition.setDuration(200);
layoutTransition.setStartDelay(LayoutTransition.CHANGE_APPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.APPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
appBarLayout.setLayoutTransition(layoutTransition);
After this, when you remove the Tabs or add it back, the layout change will animate smoothly.
Hope this helped you!

Android list Fragments overlap

I need to replace one list fragment with another one (also list). But they overlaps.
Fragments were added dynamically:
fragmentManager.beginTransaction().replace(R.id.container,
CatalogFragment.newInstance(position + 1)).addToBackStack(null).commit();
and I'm trying to replace this CatalogFragment with LessonFragment in OnFragmentInteractionListener when the item of CatalogFragment's list item clicked like this:
// fragmentManager = getSupportFragmentManager();
// fragmentManager.popBackStack();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_catalog, LessonsFragment.newInstance());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
I've been trying to pop previous item in backStack. Also tried to give the name of backStack of CatalogFragment and then remove it manually. Doesn't work.
Both of fragments are getting displayed at the same time.
I have tried first 10 solutions of google and tried to use standard developer.android's solution of replacement. Fail.
Please help if you know how. Thanks in advance.
P.S. Tell if some more code needed.
From your code, you added CatalogFragment in a layout: R.id.container, but you replace your LessonsFragment in another layout: R.id.fragment_catalog. I think that it's the reason why 2 fragments display at the same time. You should only use 1 Layout view to display fragments with you want only 1 visible.

Add fragments into a Fragment Activity

I have a FragmentActivity that contains a FrameLayout. I use the following code to add Fragments to the Fragment Activity.
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_content, fragment, fargmentTag);
ft.addToBackStack(null);
ft.commit();
Now R.id.fragment_content is FrameLayout. This adds a Fragment onto the view. But the underlying view still remains visible. Meaning the one lying view is seen through the new fragment ? What am i doing wrong.
Kind Regards
for the next fragment use ft.replace(); so the previous one will be repalced.
Either ft.remove() the old fragment, or use ft.replace() instead of ft.add().
ft.replace() should work fine, otherwise you have to update your question for a better understanding.
Using ft.replace will replace any previously added fragment with this fragment but if the activity has some view added to its layout rather than a fragment ,then the fragment added through add or replace will show its content over it rather than replacing it as it is not a fragment.
either add another layout within your main layout and assign it some id and then add the fragment to that container.
Hope it helps.

Purpose of Container in Fragments for Android

I am learning fragments but I am failing to understand the significance behind why fragments requires a Container.
The way I understand Fragments work is as follows :
FragmentActivity setContentview refers to a xml file which
defines where fragments would be located.
FragmentActivity creates instance of the fragments
Then assigns fragment to container.
FragmentManager then displays them.
The actual Fragment class then inflates a layout, and it is this layout which
contains all of the applications UI components.
(please correct me if I miss something here because I am only learning at the moment).
So why is the purpose of the Container why do we even need since in all the examples I have seen it is just a blank relative layout xml document.
Can different fragments share the same Container (since its just a RelativeLayout xml file)?
So in the example provided by google http://developer.android.com/training/basics/fragments/creating.html
They have a ListFragment and when item is selected through the use of the CallBack interface we eventually get back to this line of code :
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
My other question is:
1) Why does this line of code not replace the ListFragment (left side Fragment) with the article fragment. Since when it was initialised we see:
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
Instead ... the ListFragment remains on the left and the right Fragment is updated.
But the container fragment_container belongs to firstFragment this is the ListFragment.
And this is not the one that gets updated.
Do you see why I have the question ? This is not explained in the tutorial.
Here: http://marakana.com/s/post/1250/android_fragments_tutorial
And here: http://developer.android.com/guide/components/fragments.html
Read this and all will be clear:)
Fragment is a portion of Activity and can exist only inside an Activity. So you need a special type of activity that can handle fragment - it's FragmentActivity.
FragmentActivity without Fragments is almost like a normal Activity. But it has a FragmentManager to manage (add,remove,replace) fragments. When you want to add a Fragment to a FragmetnActivity you should specify where it should be placed (because fragment does not need to be fullscreen, just like GooglePlay-there are multiple small fragments). So this is why you need a container.
Can different fragments share the same Container (since its just a RelativeLayout xml file)?
Yes they can, you can replace one fragment with another within the same container.

Swapping Fragments in a Single Activity?

On the tablet we have two fragments (two different views of the same data) that sit next to each other. On mobile devices we'd like to switch between these two fragments at the push of a button. The mobile layout looks something like this:
<RelativeLayout>
<fragment id="container" name="fragA"/>
<ImageButton onClick="swapFragments" />
</RelativeLayout>
In the activity's swapFragments(View) method, I'm attempting to use the FragmentManager to replace fragA with fragB:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, new FragB());
fragmentTransaction.commit();
...but I can always see fragA through the transparent parts of fragB, leading me to believe that it's just putting fragB on top of fragA, not replacing it.
I'm starting down the path of using hide(Fragment) and similar methods in the transaction, but that doesn't look like the right way to do it.
Any tips on how to swap these fragments the right way?
Edit: I saw the answer to this question. This confuses me, though, as I need to be able to specify a different layout for tablet and phone. If I have to programmatically add fragments, how do I avoid code specific to each layout in the activity (i.e.
if(TABLET) {
addFragmentA();
addFragmentB();
} else {
addFragmentA();
}
Don't mix Fragments created in XML and in Code - bad things will happen. Keep a container view in the layout, then add / replace fragments into it (don't have the first fragment inside it).
Looks OK to me, I'm doing something similar albeit I'm adding my initial fragment from the activity using add rather than having it loaded by referencing it in the layout. There might be a bug there. FYI I'm using the compatibility library.
Might be worth trying:
1) Add the transaction to the back stack to see if that makes a difference, it seems like you may want that functionality anyway.
2) Give your fragment in the layout an id or tag, then use that to perform a remove and add fragB instead.
3) Try loading your fragA from code instead and see if that makes a difference.
well, first of all you can try using the newInstance() factory method for instantiating the fragment B and not just new FragB().
However, I think this is not the problem.
Can you just try not to use in you XML layout the fragment tag?
Just do something like this:
<RelativeLayout>
<Linear/FrameLayout id="container" name="fragA"/>
<ImageButton onClick="swapFragments" />
</RelativeLayout>
So use like a Frame or LinearLayout as container for you fragment and inflate it in the onCreateView callback from the Fragment. Maybe it helps, let me know.
Cheers!
As far as I can see you are not hiding / detaching the previous fragment so both will be displayed. You can implement something like this:
if (mFragment != null) {
ft = mActivity.getSupportFragmentManager().beginTransaction();
ft.hide(mFragment);
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}

Categories

Resources