Monday, May 20, 2013

Add and Remove view dynamically

This exercise demonstrate how to add and remove view dynamically at run-time. When user click on the Add button, new view will be added. When user click on Remove button, the corresponding view will be removed.


MainActivity.java
package com.example.androiddynamicview;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.app.Activity;
import android.content.Context;

public class MainActivity extends Activity {
 
 EditText textIn;
 Button buttonAdd;
 LinearLayout container;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  textIn = (EditText)findViewById(R.id.textin);
  buttonAdd = (Button)findViewById(R.id.add);
  container = (LinearLayout)findViewById(R.id.container);
  
  buttonAdd.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    LayoutInflater layoutInflater = 
      (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View addView = layoutInflater.inflate(R.layout.row, null);
    TextView textOut = (TextView)addView.findViewById(R.id.textout);
    textOut.setText(textIn.getText().toString());
    Button buttonRemove = (Button)addView.findViewById(R.id.remove);
    buttonRemove.setOnClickListener(new OnClickListener(){

     @Override
     public void onClick(View v) {
      ((LinearLayout)addView.getParent()).removeView(addView);
     }});
    
    container.addView(addView);
   }});
  
 }

}


activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="Add"/>
        <EditText
            android:id="@+id/textin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@id/add"/>
    </RelativeLayout>
    <LinearLayout 
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    </LinearLayout>

</LinearLayout>


row.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <Button
        android:id="@+id/remove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Remove"/>
    <TextView
        android:id="@+id/textout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@id/remove"/>
</RelativeLayout>



download filesDownload the files.

Related:
- Apply animations on layout changes using LayoutTransition
Get text from dynamically added view
Add and Remove view dynamically, keep views after orientation changed

In more details to show how to keep track of the child views:
Add and Remove view dynamically, details of keeping track of child views
Another approach to share a common OnClickListener between all buttonRemove.

18 comments:

Nayanesh Gupte said...

why to take so much efforts?

when you can manage it by visibility VISIBLE and GONE.
in there any particular reason to use this approach?

Andr.oid Eric said...

hello friend,

- It's asked from another one.
- I think set it VISIBLE/GONE, and dynamic add/remove is differency. At least I can insert un-limited view at run-time according user action. If use VISIBLE/GONE, I have to know number of view while coding.
- Actually, when I see the "another one" question, I also think about use VISIBLE/GONE in first instance:)

Anonymous said...

how to toast the edittext values of inflated layout on clicking a submit button?

DroidLearner said...

I modified some lines of code. I have one extra Submit button. On clicking Submit it has to Toast all EditText values of Inflated layout. But its toasting only the last item.
public class MainActivity extends Activity {

EditText textIn,textOut;
Button buttonAdd, submit;
LinearLayout container;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textIn = (EditText) findViewById(R.id.textin);
buttonAdd = (Button) findViewById(R.id.add);
container = (LinearLayout) findViewById(R.id.container);
submit = (Button) findViewById(R.id.Submit);

buttonAdd.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View addView = layoutInflater.inflate(R.layout.row, null);
textOut = (EditText) addView
.findViewById(R.id.editText);

Button buttonRemove = (Button) addView
.findViewById(R.id.remove);
buttonRemove.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
((LinearLayout) addView.getParent())
.removeView(addView);
}
});

container.addView(addView);
}
});

submit.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
String s1 = textOut.getText().toString();
Toast.makeText(getBaseContext(), ""+s1, Toast.LENGTH_SHORT).show();
}
});

}

}

Andr.oid Eric said...

hello DroidLearner said,

You have many textOut, but with one submit button only. How can you select which textOut to submit?

You define EditText textOut as a global variable, for sure it keep the last value.

Anonymous said...

How to get the all textout value??Please Help ASAP..

Anonymous said...

Thank you very much, this is exactly what I was searching for! :)
But how do I get the values out of all the TextViews the user adds?

Andr.oid Eric said...

Please read Get text from dynamically added view.

Anonymous said...

hey can v reload the whole dynamic view on some condition .. i tried but it threw up some error

Anonymous said...

When portrait to Landscape or Landscape to portrait, the added views are gone. how can we prevent it?

Andr.oid Eric said...

Hello Anonymous,

please check Add and Remove view dynamically, keep views after orientation changed.

RTAC said...

Thanks buddy, can resolve my problem, I share my code to create a dynamic form based on your method

private static void createFormularioTipo1(String Nombre, final String ParametroRespuesta,ScrollView scv_container){
LayoutInflater layoutInflater =
(LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View addView = layoutInflater.inflate(R.layout.layout_tipo_1, null);
TextView etiqueta = (TextView)addView.findViewById(R.id.tv_layout_tipo_1_etiqueta);
final EditText texto =(EditText)addView.findViewById(R.id.et_layout_tipo_1_texto);

etiqueta.setText(Nombre);
Button buscar = (Button)addView.findViewById(R.id.btn_layout_tipo_1_consultar_buscar);
buscar.setText(act.getResources().getString(R.string.cabecera_2_consultar));
buscar.setCompoundDrawables(act.getResources().getDrawable(R.drawable.ic_action_search),null,null,null);
buscar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Functions.AlertDialogShow(act,ctx,ParametroRespuesta);
}
});

scv_container.addView(addView);
}

Sarath Nambiar said...

Thanks dude.. Helped me alot :)

Unknown said...

How does this line work:

((LinearLayout)addView.getParent()).removeView(addView);

If I add more than one view, how is it determined which exact view is to be removed?

http://stackoverflow.com/questions/33954695/how-does-onclicklistener-keep-track-of-the-view-to-be-removed/33954976?noredirect=1#comment55668742_33954976

Andr.oid Eric said...

hello Unknown,

Sorry for my english is too bad to explain, so I post in another example: Add and Remove view dynamically, keep track of child views.

Emanuele Tinari said...

Hello and sorry for my bad english. I'm try to put a AutocompleteTextView, an EditText and a button Add starting from your example in this and last post.
Without fortune. How can i achieve that, and retrieve or cancel data too? a link to a tutorial or where i can find more about it is ok.
thanks in advance

Unknown said...

How to added spinner dynamically. with different data in each spinner. when load it from Json data. each spinner should load with different data. how to achieve it.

divya patel said...

how to grand total for all total??