Adding multiple fragments in same fragment transaction - android

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();

Related

Android fragment can be clicked when hidden (Maps v2 + Sliding Drawer issue)

Interesting issue here guys, which I hope somebody can shed some light on.
I currently have a Maps v2 fragment with a Sliding Drawer (deprecated - I know) on the same screen. Once the user is finished with their tasks, they can pull the sliding draw up and click "finish". This makes use of SupportFragmentManager and I basically end up replacing the contents of the screen with a brand new fragment.
However, the user is still able to click content on the Sliding Drawer even though it has been replaced with the new fragment. Any hints?
Below is the skeletal structure of the responsible code:
activity_map.xml
<RelativeLayout android:id="#+id/activity_map">
<LinearLayout>
<include layout="#layout/toolbar"/>
<fragment android:id="#+id/fragment_map"
android:name="com.foo.fragment.MapFragment" />
</LinearLayout>
<SlidingDrawer>
...
</SlidingDrawer>
</RelativeLayout>
MapActivity.java
...
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_map, newFragment, TAG);
transaction.addToBackStack(null);
transaction.commit();
You should try to do like this
activity_map.xml
<FrameLayout
android:id="#+id/container>
</FrameLayout>
fragment_map.xml
<RelativeLayout android:id="#+id/activity_map">
<LinearLayout>
<include layout="#layout/toolbar"/>
<fragment android:id="#+id/fragment_map"
android:name="com.foo.fragment.MapFragment" />
</LinearLayout>
<SlidingDrawer>
...
</SlidingDrawer>
</RelativeLayout>
Now inside your activity you should first start a new fragment (lets say AMapFragment) having layout fragment_map inside FrameLayout (activity_map.xml). Please note now the below code will be part of your fragment (AMapFragment)
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_map, newFragment, TAG);
transaction.addToBackStack(null);
transaction.commit();
And change this line transaction.replace(R.id.activity_map, newFragment, TAG); to transaction.replace(R.id.container, newFragment, TAG);
The simplest and most elegant solution in this case was to set clickable="true" on my new fragment in its static xml layout file.
The next step was to manually associate listeners to the new buttons and text edits on this fragment.
Works like a charm!

How to add static Fragments in Android activity

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();

Android ... Can I have 2 fragments on 1 tab, without them overlapping?

I'm using actionbarsherlock to create an app that has tabs, with a list of each tab. I'd like for there to be an admob ad at the bottom of the list on all tabs. I've gotten it close to working, but the fragments are overlapping instead of having the list above the ad. Here's the code:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ListFragment = new FragmentTab1();
ft.add(android.R.id.content, ListFragment);
ft.attach(mFragment);
Fragment adfragment = new AdFragment();
ft.add(android.R.id.content, adfragment);
ft.attach(adfragment);
}
It's almost like I want to concat the 2 fragments before adding them to the transaction, but I can't figure that out.
You need to create a custom layout with two FrameLayout like this . So the Ads will be at the bottom with a fixed height and ListView Fragment will use the remaining height.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/Red"
android:layout_weight="1"/>
<FrameLayout
android:id="#+id/ads_container"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/Yellow"/>
</LinearLayout>
And add the Fragments to each FrameLayout like this
ListFragment = new FragmentTab1();
ft.add(R.id.list_container, ListFragment);
ft.attach(mFragment);
Fragment adfragment = new AdFragment();
ft.add(R.id.ads_container, adfragment);
ft.attach(adfragment);
Try to use ViewPager.
Below is one of the link for ViewPager example
http://www.edumobile.org/android/android-beginner-tutorials/view-pager-example-in-android-development/

Multiple fragments in a vertical Linearlayout

I am facing the following issue in my app. I want to add multiple fragments into a vertical LinearLayout in a certain order.
Here is my layout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
And here is the code I use to add the fragments.
Fragment fragment1 = MyFragment.newInstance(param1);
Fragment fragment2 = MyFragment.newInstance(param2);
FragmentManager fm = getSupportFragmentmanager();
fm.beginTransaction().add(R.id.content, fragment1, "fragment1").commit();
fm.beginTransaction().add(R.id.content, fragment2, "fragment2").commit();
I use one transaction each time so I guarantee that they are placed in that order on screen.
My problem is that when the orientation changes and the Activity is re-created there is no way I can be sure that they will appear on screen in the same order.
Has someone experienced this too? How can I solve the problem? Having two layouts inside the LinearLayout with an specific id for each of the fragments will not help, because the number of fragments I have to add is undetermined (I just used the number 2 for the example)
If there's an indefinite amount of Fragments to add, better use a ViewPager with a FragmentStatePagerAdapter or FragmentPagerAdapter. There you can add inifinite numbers of Fragments in a clean way and don't have to worry about a huge list of Fragments using a large amount of memory.
If you want to stay with your ScrollView approach, you can use FragmentManager.executePendingTransactions() to ensure, that the transaction is completed, before the other:
FragmentManager fm = getSupportFragmentmanager();
fm.beginTransaction().add(R.id.content, fragment1, "fragment1").commit();
fm.executePendingTransactions();
fm.beginTransaction().add(R.id.content, fragment2, "fragment2").commit();
fm.executePendingTransactions();
// etc.

clarification on static vs dynamic fragment

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();

Categories

Resources