When i am adding multiple fragments to a FragmentTransaction and commiting after that only last fragment is added.
getFragmentManager().beginTransaction().add(R.id.main_container,PropertyListFragment.newInstance()).addToBackStack(null)
.add(R.id.main_container, BlankFragment.newInstance("dfghj","fghj")).addToBackStack(null)
.add(R.id.main_container,PropertyListFragment.newInstance()).addToBackStack(null)
.add(R.id.main_container, BlankFragment.newInstance("dfghj","fghj")).addToBackStack(null)
.commit();
Backstack count is also 1.
You can't use fragment in this way you need to use just one fragment per container.
check this:
How do I properly add multiple fragments to a fragment transition?
Above answer is right.
You can't use fragment in this way you need to use just one fragment per container but I gave you a little help here.
You need to define at the XML FrameLayout for each Fragment something like this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<FrameLayout
android:id="#+id/fragment_2"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
And in the Fragment you need to define like this.
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
ListFragment listFragment = new ListFragment();
WebFragment webFragment = new WebFragment();
trans.add(R.id.fragment_1, listFragment, "list_fragment");
trans.add(R.id.fragment_2, webFragment, "web_fragment");
trans.commit();
I have fragment(frag1) and I want to place another fragment(frag2) in it. So in XML file of frag1 I place
<fragment
android:layout_width="wrap_content"
android:layout_height="80dp"
android:id="#+id/fragment4"
tools:layout="#layout/fragment_fragment1" />
but when I start app I get this problem:
Binary XML file line #16: Error inflating class fragment
Can anyone help me with this issue?
Let us say you have a fragment A and fragment B. If you want to put fraagment B inside A do this in Fragment A
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager()
.beginTransaction();
Fragment profileFragment = new FragmentB();//the fragment you want to show
profileFragment.setArguments(null);
fragmentTransaction
.add(R.id.container, profileFragment);//R.id.content_frame is the layout you want to replace
fragmentTransaction.commit();
Just wrap the view around a frame layout on which you need to place your fragment B.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<...> // The view over which you want your fragment
</FrameLayout>
Note that the id of this frame layout is the same which I have passed inside the add method above.
Instead of using Fragment in xml use FrameLayout for replace and add fragment in Activity, see the following link might be helpful
http://developer.android.com/training/basics/fragments/fragment-ui.html
Trying to create Facebook / Gmail style Sliding Navigation Drawer. All I want is to create separate Fragments in XML, and show them when user clicks one of the list items from Drawer Menu. Each Fragment hooked up to one item in the list.
NavigationDrawer is great example app to start with, but it only demos loading fragment dynamically. I want even simpler, just loading those statically. How should (Code snippet please) I be instantiating Fragments within my activity on List menu item click? How would MainActivity XML look like ?
Please read the docs http://developer.android.com/guide/components/fragments.html
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="+#id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Java
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Activity:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();
transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();
Code in the view:
<fragment
android:id="#+id/Fragment1"
android:name="com.landa.fragment.Fragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/include1" />
The problem is, the content doesn't really get replaced - it gets put on top (so it overlaps).
When I click back, the first fragment gets shown properly (without the second), but initially both are visible (I want only the last one to be visible).
What am I missing here?
You are doing two things wrong here:
You cannot replace a fragment that is statically placed in an xml layout file. You should create a container (e.g. a FrameLayout) in the layout and then add the fragment programatically using FragmentTransaction.
FragmentTransaction.replace expects the id of the container that contains the fragment and not the id of the fragment as the first parameter. So you should pass the first argument as the id of the container that you added the first fragment to.
You can refer to this link for more details.
I had a similar problem but my issue was that I was using two different Fragment managers:
One from getSupportFragmentManager() and one from getFragmentManager(). If I added one fragment with the SupportFragmentManager and then tried replacing the fragment with the FragmentManager, the fragment would just get added on top. I needed to change the code so that the same FragmentManager would be used and that took care of the issue.
The android developer site suggests the use of a FrameLayout to load fragments dynamically at run-time. You have hard-coded the fragment in your xml file. So it cannot be removed at run-time as mentioned in this link:
http://developer.android.com/training/basics/fragments/creating.html
this link shows how to add fragments through your program:
http://developer.android.com/training/basics/fragments/fragment-ui.html
I had the same problem and saw all the answers, but none of them contained my mistake!
Before trying to replace the current fragment, I was showing the default fragment in the xml of the container activity like this:
<FrameLayout
android:id="#+id/fragment_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="....ShopFragment"
android:id="#+id/fragment"
tools:layout="#layout/fragment_shop" />
</FrameLayout>
after that, although i was passing the FrameLayout to the fragmentTransaction.replace() but i had the exact problem.
it was showing the second fragment on top of the previous one.
The problem fixed by removing the fragment from the xml and showing it programmatically in the onCreate() method of the container activity for the default preview on the start of the program like this:
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
and the container activity xml:
<FrameLayout
android:id="#+id/fragment_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
You can clear backStack before replacing fragments:
FragmentManager fm = getActivity().getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
fm.popBackStack();
}
// replace your fragments
<FrameLayout
android:id="#+id/fragment_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground">
//Add fragment here
</FrameLayout>
Add android:background="?android:windowBackground"> to the container in which your fragment resides. In in my case I added a FrameLayout, that should help.
I agree with Sapan Diwakar's answer. But I have found a workaround on how to do this.
First, in your activity(e.g. activity_main), where you have all the layouts, Add a FrameLayout. It's height and width should be match parent. Also, give it an id.
Now, in your fragment which is going to replace the current layout, call onPause() and onResume(). Initialise all the all the inner containers in View. And set their visibility to GONE in onResume() and VISIBLE in onPause().
NOTE: Not the FrameLayout which you are replacing with this fragment.
Suppose you have ViewPager, TabLayout, ImageView and a custom <fragment> in activity_main.xml. Add, a FrameLayout as mentioned above.
In abcFragment.java, in onClick() function, add addToBackstack(null) in transaction.
Example code:
in xyzFragment, which is going to replace abcFragment(and everything shown in activity_main.xml), do this
#Override
public void onResume() {
super.onResume();
// On resume, make everything in activity_main invisible except this fragment.
slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
viewPager = getActivity().findViewById(R.id.pager);
miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);
slidingTabs.setVisibility(View.GONE);
viewPager.setVisibility(View.GONE);
miniPlayerFragment.setVisibility(View.GONE);
}
#Override
public void onPause() {
super.onPause();
// Make everything visible again
slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
viewPager = getActivity().findViewById(R.id.pager);
miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);
slidingTabs.setVisibility(View.VISIBLE);
viewPager.setVisibility(View.VISIBLE);
miniPlayerFragment.setVisibility(View.VISIBLE);
}
Happy coding!
Use a container instead of using fragment
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!" />
Now in MainActivity
if(condition)
getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();
else
getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();
Please note that your fragment class should import 'android.app.Fragment'
Make sure, that you use "support.v4" or the "original" implementations and do not mix them. I was getting this problem because I had mixed them.
You can use setTransition method from FragmentTransaction to fix overlapping issue.
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
In Oncreate ()
BaseFragmentloginpage fragment = new BaseFragmentloginpage();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragment);
fragmentTransaction.isAddToBackStackAllowed();
fragmentTransaction.commit();
now this will be always your default fragment ...if you add fragment in xml layout it will always overlap , so set initial content with fragment at run time
i had same problem after using this problem solved
Take frame layout where u are replacing ur fragment
<FrameLayout
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and code for replacement
public void selectFrag(View view) {
Fragment fr;
if(view == findViewById(R.id.button2))
{
fr = new FragmentTwo();
}else {
fr = new FragmentOne();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
if you want whole example i will send you just comment me......
I also had the same issue, but it was because I had not changed the background color of the fragment that I was trying add to my framelayout.
Try doing this, with layout_height and layout_width set to match_parent
I once had this problem and found out that it was because I had accidentally deleted the android:background attribute that is missing on your xml code. I believe it works like when you're painting a wall, android:background is the color that the wall will be and the other views are placed on top of that base color. When you don't paint the wall prior to positioning your views they will be on top of what was already in that wall, in your case, your other fragment. Don't know if that will help you though, good luck.
I have tried above all the case and try to fix the issue but still not got solution. I don't know why its not working for me. I agree with above answers because so many agree with it.
I am just extending the answer and below is the way which is working for me.
I have added this property android:clickable="true" in top parent layout on fragment.xml file.
I hope someone will get help.
Thank you to Sapan Diwakar and others. This answer helped me. I simply created a RelativeLayout without a fragment inside it, used the RelativeLayout as a parent or group view, specified that group view in the transaction to replace, and it worked.
Code:
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_group_view, itemDetailFragment).commit();
XML:
<RelativeLayout
android:id="#+id/content_group_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
Check your frame layout ID and replace it as below
fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();
Good day, trying to clarify this: if i have this layout for a portrait layout
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
android:id="#+id/configFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.settingsFragment">
</fragment>
and this for landscape(mainly for tablets), main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
android:id="#+id/configFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.SettingsFragment" ></fragment>
<fragment
android:id="#+id/detailFragment_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.Example.DetailFragment" >
<!-- Preview: layout=#layout/details -->
</fragment>
</LinearLayout>
now within my SettingFragment, i implement a button to go to the DetailFragment:
DetailFragment fragment = (DetailFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.detailFragment_id);
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
if (fragment != null && fragment.isInLayout()) {
DetailFragment detailfragment = new WallpaperFragment();
fragmentTransaction.add(R.id.detailFragment_id, detailfragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else{
Intent intent = new Intent(getActivity().getApplicationContext(),DetailActivity.class);
startActivity(intent);
}
Am i now implementing a dynamic fragment or am i still using static fragment?.. or do i only use dynamic fragment when i use a viewgroup like FrameLayout in place of the fragment tag element?
Idea is to have a single pane for phones and multi-pane for tablets.I know its a bad idea to mix static and dynamic fragments, but its kind of confusing. Thank you.
You know, I might be wrong here (so feel free to correct me) but it looks like you're using both static AND dynamic fragments. In your XML layouts you've added the fragments then you are re-instancing them via a fragment transaction in your activity. Alternatively, if you had declared a container (FrameLayout for instance) instead of a fragment in your XML you would have to use a FragmentTransaction to add the fragment at run time.
In your example you are just stepping on the fragment that you all ready have. Basically, the OS sees your fragment in the XML when inflating (I think that's when it calls the fragment code?) and executes the code associated with it via the tag in the fragment. Your app then adds that same fragment over the top of itself. A simple way to show this is to add a LogCat call in your Fragment class's onCreateView method. If you see it more than once, then your stepping on the previous fragment with the same fragment (which I'm 99% sure you are). Hope this helps to answer your question!
Static fragments are defined in the layout and are not generally added or removed at runtime. They are referenced by their id in your code. They are generally put as a child element of a layout like below. Once they are defined here, android will know to make a fragment, that's all you have to do.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">
<fragment
android:id="#+id/fooFragment"
android:name="com.example.myapplication.TestFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Dynamic fragments are defined in your code and can be manipulated, added, removed, etc during runtime. They look like this:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.your_placeholder, new TestFragment());
ft.commit();