Friday, November 27, 2015

Add and Remove view dynamically, keep track of child views

I have a old example of "Add and Remove view dynamically". Somebody ask how the Remove button keep track of the views. So I modify the example to explain in more details.


In this example, when user click on the Add button, it will create a child View, addView. The addView have a Button, buttonRemove. The buttonRemove have its own OnClickListener object. The OnClickListener object refer to the specified addView when it is created.

That means the OnClickListener object of the buttonRemove in the first child view("abc") not the same object in the second child view("abcdef"), not the same object in the third child view("abcdefghi")...All have its own individual OnClickListener object. And each OnClickListener object refer to a specified addView object. Such that it can keep track of the child Views, addView.


MainActivity.java
package com.blogspot.android_er.androiddynamicview;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    EditText textIn;
    Button buttonAdd;
    LinearLayout container;
    TextView reList, info;

    @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);
        reList = (TextView)findViewById(R.id.relist);
        info = (TextView)findViewById(R.id.info);
        info.setMovementMethod(new ScrollingMovementMethod());

        buttonAdd.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                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);

                final View.OnClickListener thisListener = new View.OnClickListener(){
                    @Override
                    public void onClick(View v) {
                        info.append("thisListener called:\t" + this + "\n");
                        info.append("Remove addView: " + addView + "\n\n");
                        ((LinearLayout)addView.getParent()).removeView(addView);

                        listAllAddView();
                    }
                };

                buttonRemove.setOnClickListener(thisListener);
                container.addView(addView);

                info.append(
                        "thisListener:\t" + thisListener + "\n"
                                + "addView:\t" + addView + "\n\n"
                );

                listAllAddView();
            }
        });
    }

    private void listAllAddView(){
        reList.setText("");

        int childCount = container.getChildCount();
        for(int i=0; i<childCount; i++){
            View thisChild = container.getChildAt(i);
            reList.append(thisChild + "\n");
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="horizontal"
    android:padding="16dp"
    tools:context="com.blogspot.android_er.androiddynamicview.MainActivity">


    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <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>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:autoLink="web"
            android:text="http://android-er.blogspot.com/"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/relist"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:textStyle="bold"
            android:background="#E0E0E0"/>
        <TextView
            android:id="@+id/info"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:textStyle="italic"
            android:background="#D0D0D0"
            android:gravity="bottom"/>

    </LinearLayout>
</LinearLayout>


layout/row.xml, the layout of the child views.
<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 (Android Studio Format) .

It's another approach to share a common OnClickListener between all buttonRemove.

more:
Add and Remove view dynamically, with EditText/AutoCompleteTextView inside

6 comments:

siddh said...

Hey i am just taking reference your code but how i will compare the text of your child view because if its will be same no problem but if its different then i need to replace the text with top parent to nearest child.!! Is it possible i am using AutocompleteTextview and Assign the same Text to the new View ??

Erik said...

hello siddh,

How you compare strings?

In Java, to compare strings, using StringA.equal(StringB), NOT (StringA==StringB).

siddh said...

Hello ,

Yes exactly i am doing same but like in your row.xml i have taken a Autocompletetextview which is inflating There is no issue regarding the add view but when i remove and specific view from Number 1 to 10 suppose i remove view number 5 so the text in 4 and 6 should be same so i need to save the selected content to some list but in view how can i do that ?? i stuck only when i remove a particular specially not from bottom ??

Erik said...

hello siddh,

Sorry, I don't understand your problem.

I tried to change the TextView to AutoCompleteTextView, and found no any problem. Please read Add and Remove view dynamically, with EditText/AutoCompleteTextView inside.

Vishal Halani said...

how to get each edit text value which will we add can you put code with example like one more button is submit then when click on it i get all text from all edittext and set in one textview.

Unknown said...

hi eric,

i am doing a task in which i will show spinner dynamically with add button event.... now on each click event of spinner of dynamic spinner i have some value related to selected item of spinners.... but the issue is when i have multiple spinners and selects item from lets say 2nd spinner item the related value of 2nd spinner should be changed but it is changing the last displayed textview value which is related to last spinner.......

like i have
1) spinner with textview(dynamic)
2)on each event of add button spinner and textview will displays
3)now lets say i will click button for 4 times which displays(4 spinners and textviews)
4)the process should be select an item of 1st spinner the related data should be display on its textview(related data on textview will come from db)
5)the process should continue many times
6)Now the issue is when i select 2nd spinner item or 3rd spinner item its related data must display on textview 2nd and textview 3rd.... but when i selected 2nd or 3rd spinner item the related data is displaying on 4th spinners texview


how to solve this????