Android: How to dynamically include a XML Layout?

52,306

Solution 1

<RelativeLayout android:id="@+id/rl" ...

In your code:

// get your outer relative layout
RelativeLayout rl = (RelativeLayout) findById(R.id.rl);


// inflate content layout and add it to the relative layout as second child
// add as second child, therefore pass index 1 (0,1,...)

LayoutInflater layoutInflater = (LayoutInflater) 
        this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);    
rl.addView(1, layoutInflater.inflate(R.layout.content_layout, this, false) ); 

Solution 2

You could try using a ViewStub and just change which layout it is going to inflate programatically.

This answer discusses using one ViewStub.

Share:
52,306
nbarraille
Author by

nbarraille

;

Updated on May 22, 2020

Comments

  • nbarraille
    nbarraille almost 4 years

    I want to decompose my UI into several XML Layouts. The first one would be the main layout, and the other ones would be the content layouts.

    I would like to be able to set which content_layout should be included dynamically at run-time, so I don't want to set a "layout="@+layout/content_layout" in my XML file.

    Here are my layouts:

    main_layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="600dp"
        android:layout_height="800dp" >
    
        <TextView
            android:id="@+id/title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true" />
    
        <include /> <!-- I WANT TO INCLUDE MY CONTENT HERE -->
    
        <Button
            android:id="@+id/cancelButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="Cancel" />
    
    </RelativeLayout>
    

    content_layout.xml:

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

    content_layout2.xml:

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

    How can I do that?

    Thanks!

  • nbarraille
    nbarraille over 13 years
    Yes, that's how I do it usually, but apparently, ViewStubs are supposed to be used for elements you do not use often.
  • Bryan Denny
    Bryan Denny over 13 years
    If you're only changing between two different types of list views, you can just change the adapter that the list view binds from programatically (and therefore use different list view item XMLs).
  • nbarraille
    nbarraille over 13 years
    Unfortunately I have several content layout, and some of them are more complex than that.
  • nbarraille
    nbarraille over 13 years
    I tried using addView in another case, but it looked like both layout where superposing each other. Second child means at the second level, so under my RelativeLayout right? Can I still use references like android:layout_belowe="@+id/title" in my content layout, event if they are not defined in the same XML file? If not, how are they suppose to know how to insert it at the correct place? Thanks
  • Mathias Conradt
    Mathias Conradt over 13 years
    It would be added where you put the commend (// I WANT TO INCLUDE MY CONTENT HERE????). For complex layouts, you can always loop through a view(groups) childs via getChildCount(), getChildAt(), and add the view where you want. Furthermore, you can set an id via view.setId() in code and then refer to that. But of course that would be i.e. a constant in your code, not via R.id.someId, since an id assigned via java code isn't in your R file.
  • nbarraille
    nbarraille over 13 years
    Ok, I got it, the index 1 (second child) actually means that it will be inserted between the title and the button, 0 would have been before the title, etc... Thank you.
  • Shreyash Mahajan
    Shreyash Mahajan over 12 years
    @MathiasLin : will you please help me for that: stackoverflow.com/questions/8818042/…
  • tir38
    tir38 over 10 years
    I think the order of the method inputs is reversed now: developer.android.com/reference/android/view/…, int) so it should be rl.addView(layoutInflater.inflate(R.layout.content_layout, this, false), 1 );
  • cwhsu
    cwhsu over 9 years
    The answer works, but some people might find this useful as well: stackoverflow.com/questions/8481329/…