title: Android - Dynamically Updating a custom ListView after items in an ArrayList are added
body: <p>I have an activity that displays an initially populated custom ListView taken from an ArrayList, the user can then add to this list which I have no problem storing. I'm having problems displaying the added items. So far, the codes I see online use ArrayAdapter and they're only using the simple listView and not a custom one.</p>
  
  <p>Here are the related files: </p>
  
  <p>list_row_layout.xml</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent" &gt;
  
    &lt;TextView
      android:id="@+id/variant"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentTop="true"
      android:text="variant" /&gt;
  
    &lt;TextView
      android:id="@+id/quantity"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentRight="true"
      android:layout_alignParentTop="true"
      android:text="quantity" /&gt;
  
    &lt;TextView
      android:id="@+id/unit"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentTop="true"
      android:layout_marginRight="221dp"
      android:layout_toLeftOf="@+id/quantity"
      android:text="unit" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Here is the part in my activity_order_form.xml that has the listView element.</p>
  
  <pre><code>&lt;RelativeLayout
      android:id="@+id/relativeLayout3"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentLeft="true"
      android:layout_below="@+id/relativeLayout2"
      android:orientation="vertical" &gt;
  
      &lt;TextView
          android:id="@+id/textViewVariantB"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_marginLeft="94dp"
          android:text="Variant"
          android:textAppearance="?android:attr/textAppearanceLarge" /&gt;
  
      &lt;TextView
          android:id="@+id/textViewUnit"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentRight="true"
          android:layout_alignParentTop="true"
          android:layout_marginRight="123dp"
          android:text="Unit"
          android:textAppearance="?android:attr/textAppearanceLarge" /&gt;
  
      &lt;ListView
          android:id="@+id/listViewProductOrder"
          android:layout_width="match_parent"
          android:layout_height="350dp"
          android:layout_alignParentBottom="true"
          android:layout_alignParentLeft="true"
          android:layout_alignParentRight="true"
          android:layout_below="@+id/textViewVariantB" &gt;
  
      &lt;/ListView&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Here is the class where the ArrayList are stored.</p>
  
  <pre><code>public class CurrentOrderClass {
  
    private String productName;
  
    //ArrayLists
    private ArrayList&lt;String&gt; variantArray = new ArrayList&lt;String&gt;();
    private ArrayList&lt;String&gt; unitArray = new ArrayList&lt;String&gt;();
    private ArrayList&lt;Integer&gt; quantityArray = new ArrayList&lt;Integer&gt;();
  
  
    //TODO ArrayList functions
    public ArrayList&lt;String&gt; getUnitArray() {
      return unitArray;
    }
  
    public void setUnitArray(ArrayList&lt;String&gt; unitArray) {
      this.unitArray = unitArray;
    }
  
    public void addToUnitArray(String unit){
      this.unitArray.add(unit);
    }
  
  
  
    public ArrayList&lt;Integer&gt; getQuantityArray() {
      return quantityArray;
    }
  
    public void setQuantityArray(ArrayList&lt;Integer&gt; quantityArray) {
      this.quantityArray = quantityArray;
    }
  
    public void addToQuantityArray(int quantity){
      this.quantityArray.add(quantity);
    }
  
  
  
    public ArrayList&lt;String&gt; getVariantArray() {
      return variantArray;
    }
  
    public void setVariantArray(ArrayList&lt;String&gt; variantArray) {
      this.variantArray = variantArray;
    }
  
    public void addToVariantArray(String variantArray){
      this.variantArray.add(variantArray);
    }
  }
  </code></pre>
  
  <p>Here is the CustomListAdapter.java file</p>
  
  <pre><code>public class CustomListAdapter extends BaseAdapter {
  
    private ArrayList&lt;CurrentOrderClass&gt; listData;
  
    private LayoutInflater layoutInflater;
  
    public CustomListAdapter(Context context, ArrayList&lt;CurrentOrderClass&gt; listData) {
      this.listData = listData;
      layoutInflater = LayoutInflater.from(context);
    }
  
    @Override
    public int getCount() {
      return listData.size();
    }
  
    @Override
    public Object getItem(int position) {
      return listData.get(position);
    }
  
    @Override
    public long getItemId(int position) {
      return position;
    }
  
    public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder holder;
      if (convertView == null) {
          convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
          holder = new ViewHolder();
          holder.variantView = (TextView) convertView.findViewById(R.id.variant);
          holder.unitView = (TextView) convertView.findViewById(R.id.unit);
          holder.quantityView = (TextView) convertView.findViewById(R.id.quantity);
          convertView.setTag(holder);
      } else {
          holder = (ViewHolder) convertView.getTag();
      }
  
      holder.variantView.setText(listData.get(position).getVariantArray().get(position).toString());
      holder.unitView.setText(listData.get(position).getUnitArray().get(position).toString());
      holder.quantityView.setText(String.valueOf(listData.get(position).getQuantityRow()));
  
      return convertView;
  }
  
    static class ViewHolder {
      TextView variantView;
      TextView unitView;
      TextView quantityView;
    }
  
  
  }
  </code></pre>
  
  <p>This is part of my OrderForm.java activity, this shows the onCreate and the method that populates the listView, as well as the part where user input is taken.</p>
  
  <pre><code>public class OrderForm extends Activity {
  
    public TextView tv;
    private int variantPosition; 
    CustomListAdapter customListAdapter;
    CurrentOrderClass currentOrder = new CurrentOrderClass();
  
    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_order_form);
            tv = (TextView)findViewById(R.id.textViewProduct);
  
            //set variants here
            popolateItem();
  
            //set current order listview here
            ArrayList image_details = getListData();
            final ListView lv1 = (ListView) findViewById(R.id.listViewProductOrder);
  
            customListAdapter = new CustomListAdapter(this, image_details);
            lv1.setAdapter(customListAdapter);
  
    }
  
    private ArrayList getListData() {
  
            ArrayList results = new ArrayList();
  
            for(int i = 0; i &lt; 10; i++){
          currentOrder.getQuantityArray().add(i);
          currentOrder.getUnitArray().add("Sample text here." + i);
          currentOrder.getVariantArray().add("Another sample text here" + i);
          results.add(currentOrder);
            }
            return results;
  
    }
  
        //....snip snip excess code.....
        //This is the part wherein I add new items to the ArrayList in the class
        //After this, I'm not sure how to proceed
  
  
    currentOrder.setProductName(product.getName());
    currentOrder.addToQuantityArray(newQuantity);
    currentOrder.addToUnitArray(product.getUnit()[position]);
    currentOrder.addToVariantArray(product.getVariant()[variantPosition]);
  
    Log.d("Angelo", currentOrder.getProductName() + " " 
              + currentOrder.getQuantityArray() + " " 
              + currentOrder.getUnitArray() + " "
              + currentOrder.getVariantArray());
  
  
  }
  </code></pre>
  
  <p>I also tried to place <code>customListAdapter.notifyDataSetChanged();</code> after the Log entry but nothing happened. Any ideas anyone? Thanks. </p>
  
  <p><strong>EDIT AFTER ANSWERS AND MODIFICATIONS.</strong> </p>
  
  <p>Just follow FD's answer below and add the function he specified there and the 2 function calls after that. Now, you want to modify your <code>getListData()</code> function like this:</p>
  
  <pre><code>private ArrayList getListData() {
  
      ArrayList results = new ArrayList();
  
      int loopUntil;
  
      /* Two scenarios
       * First ---&gt; the user started the activity for the first time, which means that the pre-populated list is what we want
       *            if this is the case, look at the else part of the boolean statement, it only loops until 10 
       *            and in addition, populates those elements
       * Second ---&gt; the user has set something already and we want to populate until that element.
       * 
       */
  
  
      if(currentOrder.getQuantityArray().size() &gt; 10){
          loopUntil = currentOrder.getQuantityArray().size();
  
          for(int i = 0; i &lt; loopUntil; i++){
              currentOrder.getQuantityArray();
              currentOrder.getUnitArray();
              currentOrder.getVariantArray();
              results.add(currentOrder);
          }
  
      }
      else{
          loopUntil = 10;
  
          for(int i = 0; i &lt; loopUntil; i++){
              currentOrder.getQuantityArray().add(i);
              currentOrder.getUnitArray().add("Sample text here." + i);
              currentOrder.getVariantArray().add("Another sample text here" + i);
              results.add(currentOrder);
          }
      }
  
      return results;
  
  }
  </code></pre>
  
  <p>The first condition executes when there is an item beyond the pre-populated one, since the else statement loops only until the pre-populated item (item number 9, index 0). This loop ensures that everything you add to the ArrayList gets added to the ListView. </p>
  
  <p>The second condition executes when the activity is opened for the first time and there's supposed to be nothing in that list yet except the ones that you populated yourself.</p>