38

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!

Lorenzo Polidori
  • 10,332
  • 10
  • 51
  • 60
nbarraille
  • 9,926
  • 14
  • 65
  • 92

2 Answers2

41
<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) ); 
Mathias Conradt
  • 28,420
  • 21
  • 138
  • 192
  • 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 – nbarraille Oct 29 '10 at 04:17
  • 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. – Mathias Conradt Oct 29 '10 at 04:55
  • 1
    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. – nbarraille Oct 29 '10 at 11:00
  • @MathiasLin : will you please help me for that: http://stackoverflow.com/questions/8818042/android-how-to-add-another-layout-number-of-time-to-my-already-created-linerlay – Shreyash Mahajan Jan 11 '12 at 11:10
  • 2
    I think the order of the method inputs is reversed now: https://developer.android.com/reference/android/view/ViewGroup.html#addView(android.view.View, int) so it should be ```rl.addView(layoutInflater.inflate(R.layout.content_layout, this, false), 1 );``` – tir38 Nov 06 '13 at 19:32
  • The answer works, but some people might find this useful as well: http://stackoverflow.com/questions/8481329/create-view-object-from-xml-file-in-android – cwhsu Oct 01 '14 at 07:39
5

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

This answer discusses using one ViewStub.

Community
  • 1
  • 1
Bryan Denny
  • 27,363
  • 32
  • 109
  • 125
  • 1
    Yes, that's how I do it usually, but apparently, ViewStubs are supposed to be used for elements you do not use often. – nbarraille Oct 28 '10 at 20:09
  • 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). – Bryan Denny Oct 28 '10 at 20:53
  • Unfortunately I have several content layout, and some of them are more complex than that. – nbarraille Oct 29 '10 at 04:15