How to add a fragment to a programmatically generated layout?

AndroidAndroid FragmentsAndroid Linearlayout

Android Problem Overview


I have the following code working which generates fragments, but only if I am adding them to a linear layout which exists in my XML file.

LinearLayout fragmentsLayout = (LinearLayout) findViewById(R.id.foodItemActvity_linearLayout_fragments);
FragmentManager fragMan = getFragmentManager();
FragmentTransaction fragTransaction = fragMan.beginTransaction();

Fragment myFrag= new ImageFragment();
fragTransaction.add(R.id.foodItemActvity_linearLayout_fragments, myFrag , "fragment" + fragCount);
fragTransaction.commit();

Now what if I want to add that fragment to a linear layout that does not already exist in the XML file such as

LinearLayout rowLayout = new LinearLayout();

Part 2:

    Fragment frag1 = generateAppropriateFragment(type1);
	Fragment frag2 = generateAppropriateFragment(type2);

    LinearLayout fragmentsLayout = (LinearLayout) findViewById(R.id.foodItemActvity_linearLayout_fragments);
	LinearLayout rowLayout = new LinearLayout(this);
    rowLayout.setId(12345); // add counter to end

	fragmentsLayout.addView(rowLayout);		
	getFragmentManager().beginTransaction().add(rowLayout.getId(), frag1, "fragment_grandchild" + fragCount).commit();
	fragCount++;
	getFragmentManager().beginTransaction().add(rowLayout.getId(), frag2, "fragment_grandchild" + fragCount).commit();
	fragCount++;

Android Solutions


Solution 1 - Android

At some point, I suppose you will add your programatically created LinearLayout to some root layout that you defined in .xml. This is just a suggestion of mine and probably one of many solutions, but it works: Simply set an ID for the programatically created layout, and add it to the root layout that you defined in .xml, and then use the set ID to add the Fragment.

It could look like this:

LinearLayout rowLayout = new LinearLayout();
rowLayout.setId(whateveryouwantasid);
// add rowLayout to the root layout somewhere here

FragmentManager fragMan = getFragmentManager();
FragmentTransaction fragTransaction = fragMan.beginTransaction();   

Fragment myFrag = new ImageFragment();
fragTransaction.add(rowLayout.getId(), myFrag , "fragment" + fragCount);
fragTransaction.commit();

Simply choose whatever Integer value you want for the ID:

rowLayout.setId(12345);

If you are using the above line of code not just once, it would probably be smart to figure out a way to create unique-IDs, in order to avoid duplicates.

UPDATE:

Here is the full code of how it should be done: (this code is tested and works) I am adding two Fragments to a LinearLayout with horizontal orientation, resulting in the Fragments being aligned next to each other. Please also be aware, that I used a fixed height and width of 200dp, so that one Fragment does not use the full screen as it would with "match_parent".

MainActivity.java:

public class MainActivity extends Activity {

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);		
		
		LinearLayout fragContainer = (LinearLayout) findViewById(R.id.llFragmentContainer);
		
		LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.HORIZONTAL);
		
		ll.setId(12345);
		
		getFragmentManager().beginTransaction().add(ll.getId(), TestFragment.newInstance("I am frag 1"), "someTag1").commit();
        getFragmentManager().beginTransaction().add(ll.getId(), TestFragment.newInstance("I am frag 2"), "someTag2").commit();
		
		fragContainer.addView(ll);
	}
}

TestFragment.java:

public class TestFragment extends Fragment {
	
	public static TestFragment newInstance(String text) {
		
        TestFragment f = new TestFragment();

        Bundle b = new Bundle();
        b.putString("text", text);
        f.setArguments(b);
        return f;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		
		View v =  inflater.inflate(R.layout.fragment, container, false);
		
		((TextView) v.findViewById(R.id.tvFragText)).setText(getArguments().getString("text"));		
		return v;
	}
}

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rlMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <LinearLayout
        android:id="@+id/llFragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="19dp"
        android:orientation="vertical" >
    </LinearLayout>
</RelativeLayout>

fragment.xml:

  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="200dp" >

    <TextView
        android:id="@+id/tvFragText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="" />

</RelativeLayout>

And this is the result of the above code: (the two Fragments are aligned next to each other) result

Solution 2 - Android

Below is a working code to add a fragment e.g 3 times to a vertical LinearLayout (xNumberLinear). You can change number 3 with any other number or take a number from a spinner!

for (int i = 0; i < 3; i++) {
            LinearLayout linearDummy = new LinearLayout(getActivity());
            linearDummy.setOrientation(LinearLayout.VERTICAL);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {

                Toast.makeText(getActivity(), "This function works on newer versions of android", Toast.LENGTH_LONG).show();

            } else {
                linearDummy.setId(View.generateViewId());
            }
            fragmentManager.beginTransaction().add(linearDummy.getId(), new SomeFragment(),"someTag1").commit();

            xNumberLinear.addView(linearDummy);
        }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZapnologicaView Question on Stackoverflow
Solution 1 - AndroidPhilipp JahodaView Answer on Stackoverflow
Solution 2 - AndroidFarmakerView Answer on Stackoverflow