Programmatically add fragments to viewgroup

25,957

Take a look at these Fragment topics:

Essentially you'll want to have the left fragment tell the parent Activity which item is selected. Then, the Activity can add/remove the correct fragment in the right pane.

Keep in mind that creating/destroying a Fragment is a lot of work for the system. If you can get away with having a single Fragment in the right pane, it will be much more efficient. You can then call methods on that one Fragment instance without building new Fragments.

EDIT (example):

Your Main Activity implementation with custom method:

public class Main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    /** Called by the left fragment */
    public void updateRightPane(long id) {
        // Get the data with the selected item id
        // ...

        // Create a new fragment
        MyFragment fragment = new MyFragment(data);

        // Update the layout
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        // The id specified here identifies which ViewGroup to
        // append the Fragment to.
        ft.add(R.id.view_group_id, fragment);
        ft.commit();
    }
}

The onListItemClick implementation for MenuFragment.java:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    // Get the parent Activity
    Main activity = (Main) getActivity();

    // Pass the selected item id to the Activity method
    // Note: Feel free to update this method to accept additional
    //       arguments (e.g. position).
    activity.updateRightPane(id);
}

Finally, your layout file:

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

    <!-- More views here... -->

</RelativeLayout>
Share:
25,957
Killerpixler
Author by

Killerpixler

Updated on January 03, 2020

Comments

  • Killerpixler
    Killerpixler over 4 years

    basically this is my app(idea) for a tablet landscape orientation: Two Fragments, left fragment is a listfragment populated by a resource.xml file (Got that working).

    Right fragment is supposed to dynamically change fragment and layout based on which list item the user clicks. Googling so far told me that I need to programmatically add and remove fragments to a viewgroup to do that. Is that right?

    Basically the question is/are:

    1. How do I create the viewgroup and where (Main.java or menufragment.java)?
    2. How do I put the dynamic "user clicked ID 3 on the list so add fragment 3 to the viewgroup"
    3. What do I add to my main.xml file? got the fragment for the listfragment in there, what to add for the dynamic viewgroup?

    EDIT:

    So this is what my activity looks like: Main.java

    public class Main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        }
    }
    

    This is my listfragment MenuFragment.java

    public class MenuFragment extends ListFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.listfragment, container, false);
    
    }
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
        setListAdapter(new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1,
                getResources().getStringArray(R.array.listmenu)));
        }    
    
    
    
        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            // TODO Auto-generated method stub
            super.onListItemClick(l, v, position, id);
            Main activity = (Main) getActivity();
        }
    
    
    }
    

    and finally my main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <fragment
        android:id="@+id/list"
        android:layout_width="200dp"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_weight="1"
        class="com.mwerner.fragmentstest.MainMenu" />
    
    <View
        android:id="@+id/contentview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/list" />
    
    </RelativeLayout>
    

    The string array I have in my xml file that populates the list is called "listmenu"

    Please tell me where I need to put in the code you wrote down?

  • Killerpixler
    Killerpixler about 12 years
    Thanks, just a followup: 1) how do i tell the onlistitemclick in my listfragment to change the right pane view to load another fragment and layout? 2) I don't need to destroy fragments, i can just put them in the backstack if that's easier on the memory. Basically I want only one "DetailsFragment" to be shown on the right, namely the last one the user clicked on in the list.
  • twaddington
    twaddington about 12 years
    Your ListFragment has a [getActivity][1] method. You can write a public method on the host Activity that accepts some argument and will change the right pane when invoked. Call getActivity from your left Fragment's onListItemClick listener and cast the result to the parent Activity type. Then invoke your public method. Something like updateDetailsPane(long id) should work. MyActivity activity = (MyActivity) getActivity(); [1]: developer.android.com/reference/android/app/…
  • Killerpixler
    Killerpixler about 12 years
    I posted my code in the edit, i understand logically what you say but not how to implement it codewise. Please help :S
  • twaddington
    twaddington about 12 years
    I updated my answer with an example implementation. Let me know if it works out!
  • Killerpixler
    Killerpixler about 12 years
    @twaddintgton Thanks a lot, couple of nasty red lines thou, 1) i assume whenn you put data in the brackets i assume you mean id not data? i don't see data anywhere defined as a variable, 2)MyFragment cannot be resolved to a type, what does this mean? Should I change it to ViewerFragment? I have a fragment called ViewerFragment.java lying around 3) ft.add(R.id.view_group_id, fragment); it says that view_group_id cannot be resolved or is not a field. A little theory here please... I assume you mean i need to put all possible layouts in the main.xml file for them to be waited to be inflated?
  • Killerpixler
    Killerpixler about 12 years
    But what do I need to put in instead of view_group_id ? Soprry for me beeing so pesky, I appreciate your help
  • twaddington
    twaddington about 12 years
    MyFragment should be replaced with your Fragment class. The data variable is not defined, it's up to you to define what that needs to be. It's whatever your Fragment class needs to start itself up. Finally, the R.id.view_group_id is the id of your ViewGroup layout item (LinearLayout, RelativeLayout, etc). You can see the ViewGroup with the id in the xml layout example I included above.