Android - Dynamically Add Views into View

283,903

Solution 1

Use the LayoutInflater to create a view based on your layout template, and then inject it into the view where you need it.

LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);

// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");

// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

You may have to adjust the index where you want to insert the view.

Additionally, set the LayoutParams according to how you would like it to fit in the parent view. e.g. with FILL_PARENT, or MATCH_PARENT, etc.

Solution 2

See the LayoutInflater class.

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup parent = (ViewGroup)findViewById(R.id.where_you_want_to_insert);
inflater.inflate(R.layout.the_child_view, parent);

Solution 3

It looks like what you really want a ListView with a custom adapter to inflate the specified layout. Using an ArrayAdapter and the method notifyDataSetChanged() you have full control of the Views generation and rendering.

Take a look at these tutorials

Solution 4

To make @Mark Fisher's answer more clear, the inserted view being inflated should be a xml file under layout folder but without a layout (ViewGroup) like LinearLayout etc. inside. My example:

res/layout/my_view.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/i_am_id"
    android:text="my name"
    android:textSize="17sp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"/>

Then, the insertion point should be a layout like LinearLayout:

res/layout/activity_main.xml

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

    <LinearLayout
        android:id="@+id/insert_point"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>

</RelativeLayout>

Then the code should be

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shopping_cart);

    LayoutInflater inflater = getLayoutInflater();
    View view = inflater.inflate(R.layout.my_view, null);
    ViewGroup main = (ViewGroup) findViewById(R.id.insert_point);
    main.addView(view, 0);
}

The reason I post this very similar answer is that when I tried to implement Mark's solution, I got stuck on what xml file should I use for insert_point and the child view. I used layout in the child view firstly and it was totally not working, which took me several hours to figure out. So hope my exploration can save others' time.

Solution 5

// Parent layout
LinearLayout parentLayout = (LinearLayout)findViewById(R.id.layout);

// Layout inflater
LayoutInflater layoutInflater = getLayoutInflater();
View view;

for (int i = 1; i < 101; i++){
    // Add the text layout to the parent layout
    view = layoutInflater.inflate(R.layout.text_layout, parentLayout, false);

    // In order to get the view we have to use the new view with text_layout in it
    TextView textView = (TextView)view.findViewById(R.id.text);
    textView.setText("Row " + i);

    // Add the text view to the parent layout
    parentLayout.addView(textView);
}
Share:
283,903

Related videos on Youtube

Josh
Author by

Josh

A man, when confronted with a problem, said "I know! I'll use regular expressions!" Now he has two problems.

Updated on September 27, 2020

Comments

  • Josh
    Josh almost 4 years

    I have a layout for a view -

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="0px"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/items_header"
            style="@style/Home.ListHeader" />
    
        <TextView 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/items_none"
            android:visibility="gone"
            style="@style/TextBlock"
            android:paddingLeft="6px" />
    
        <ListView 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/items_list" />
    
    
    </LinearLayout>
    

    What I want to do, is in my main activity with a layout like this

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="0px"
        android:id="@+id/item_wrapper">
    </LinearLayout>
    

    I want to loop through my data model and inject multiple views consisting of the first layout into the main layout. I know I can do this by building the controls completely within the code, but I was wondering if there was a way to dynamically build the views so that I can continue using a layout instead of putting everything in code.

  • Mark Fisher
    Mark Fisher almost 9 years
    it's where ever you want to put the dynamically generated layout in your main view. that's the bit you have to fill in from your own code.
  • Brendan
    Brendan over 8 years
    For those who want to try this out now - the layout inflator obtained as shown in the first line still resolves but does not appear to work, instead use getLayoutInflater()
  • akarthik10
    akarthik10 over 8 years
    Use LayoutInflater vi = getLayoutInflater(); from an activity to preserve activity theme which you don't get otherwise.
  • pa1pal
    pa1pal about 8 years
    In my View I have text view and image which initially have visibility="gone". Now after adding dynamically I am setting its visibility visible inside of loop but it is not working.
  • yivi
    yivi over 6 years
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
  • Sandeep Pareek
    Sandeep Pareek almost 3 years
    is it working but after that only get last textView ID
  • Kashif Masood
    Kashif Masood about 2 years
    In kotlin while using binding this whole thing can be converted in to just one line like, layoutInflater.inflate(R.layout.layout_you_want_to_add, binding.layoutInWhichYouWanToAdd) and that's it. Thanks for your answer.