Hiten Naresh Vasnani
Hiten Naresh Vasnani

Reputation: 538

How to programatically add multiple Fragments to activity in android

I am trying to display 6 rows inside a linear layout. I want to do this through fragments as the content will be dynamic and the number of rows will also be dynamic later on. I have the following code but only one row appears on the screen. I have SettingsActivity.java, settings.xml ThemeRowFragment,java and theme_row_layout.xml.

SettingsActivity.java

//imports

public class SettingsActivity extends FragmentActivity {

private int NUM_THEMES = 7;

ThemeRowFragment[] view_themes;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.settings);

    view_themes = new ThemeRowFragment[NUM_THEMES];

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();
    for (int i = 0; i < view_themes.length; i++) {
        view_themes[i] = new ThemeRowFragment(COLOR_MAP[i]);
        fragmentTransaction.add(R.id.theme_linear_layout, view_themes[i],
                "Row" + i);
    }
    fragmentTransaction.commit();

}

}

settings.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="@+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/string_theme"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="@string/string_theme"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#cde21c" />

</LinearLayout>

ThemeRowFragment.java

public class ThemeRowFragment extends Fragment {

private int[] colors;

public ThemeRowFragment(int colors[]) {
    super();
    this.colors = colors;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.theme_row_layout, container,
            false);
    return view;
}

}

theme_row_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/pick_colors" >
</TextView>

</LinearLayout>

Upvotes: 0

Views: 4271

Answers (2)

Greg Giacovelli
Greg Giacovelli

Reputation: 10184

Fragments will inflate themselves into the View you add them to. So you really can't do it this way. So you need to have X empty containers, one for each fragment you are going to inflate. Add each fragment to the same container will actually layer them all on top of each other, sort of making them really hard to see and use when the screen renders.

Alternatives: You could do something like the following:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="@+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/string_theme"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="@string/string_theme"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#cde21c" />

 <FrameLayout android:id="@+id/fragment_container1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
 <FrameLayout android:id="@+id/fragment_container2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
 <FrameLayout android:id="@+id/fragment_container3"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
 <FrameLayout android:id="@+id/fragment_container4"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
 <FrameLayout android:id="@+id/fragment_container5"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
 <!-- etc. -->
</LinearLayout>

Or just add each FrameLayout programatically via the LinearLayout's addView() with a unique ID for each FrameLayout.

LinearLayout layout = (LinearLayout)findViewById(R.id.linear);
FragmentTxn txn = getFragmentManager.beginTransaction();
int i = 1; // This seems really fragile though
for (Fragment f : fragments) {
      FrameLayout frame = new FrameLayout(this);
      frame.setId(i);
      layout.addView(frame);
      txn.add(i, f);
      i++;
 }
 txn.commit();

Or the other way would be to just use a listView and add each row that way. Not using Fragments at all.

<TextView
    android:id="@+id/string_theme"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="@string/string_theme"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#cde21c" />

 <ListView android:id="@+id/listview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

</LinearLayout>

then later on do something like this:

ListView view = (ListView)findViewById(R.id.listview);
view.setAdapter(new ArrayAdapter(items) { // items is a collection of objects you are representing
     public View getView(int position, View view, ViewGroup parent) {
           view = LayoutInflator.from(parent.getContext()).inflate(R.layout.theme_row_layout, parent, false);
           // manipulate the view
           return view;
  });

Upvotes: 3

Panther
Panther

Reputation: 9408

You are creating a instance of ThemeRowFragment n number of times. The problem is you are creating this as an fragment and trying to add it dynamically. Since you instantiate the same Fragment i suggest you to use ListView and use a custom adapter and set CustomView and override the getView method of your adapter to adjust your views

Upvotes: 0

Related Questions