Dynamically add items to list view using custom adapter for Android app
Solution 1
- In your adapter change the
Locations data[]
from array toArrayList<Location>
and override the appropriate constructor - In your activity, make your variable
data
a field (typeArrayList<Location>
) - When you add a location you can use
data.add(location)
- Then you can call
notifyDatasetChanged()
on your adapter
Solution 2
Store your data in an ArrayList<Location>
instead of just Location[]
, and then make a public class in your list adapter:
ArrayList<Location> data = new ArrayList<Location>();
@Override
public void add(Location location) {
data.add(location);
notifyDataSetChanged();
}
Then, when you want to add an item to the list, just call location_data.add(new_location)
.
Edit: It looks like you have your pick from several mostly identical answers.
Solution 3
Looks like you need to override the add method in your LocationAdapter class to add the object to the internal list
@Override
public void add(Location location)
{
super.add(location);
data.add(location);
}
This implementation requires that you change data to an ArrayList instead of just an array, otherwise you would have to code the array re-sizing yourself.
ArrayList<Location> data = null; // Alternatively use new ArrayList<Location>();
If you don't do this, the internal data will remain unchanged and a call to add will do not change the list. This is bad because you use the data variable to get the values for the views.
Solution 4
In your main activity, I'd recommend using an ArrayList< Location > rather than Location[] to make it easier to add new Location elements. Then, rather than having LocationAdapter extend ArrayAdapter< Location >, have it extend ListAdapter< Location > so you can pass your ArrayList< Location > to it.
That said, all you need to do in your addLocation(Location l) method in your MainActivity, is add an element to either the Location[] or ArrayList< Location > data structure you passed to your adapter, and then call:
adapter.notifyDataSetChanged();
Note that you'll need to make your adapter a member variable in your MainActivity to allow access outside of your onCreate().
user1282637
Updated on July 28, 2022Comments
-
user1282637 almost 2 years
So, right now I have a custom adapter class that takes in an array of Locations and adds them to a ListView. This is all fine and dandy, but I would like to add Locations to this listview after this initialization. For example, someone can "add a Location" and it will add it to this ListView. Here is my Main Activity:
package com.example.listviewtest; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ListView; public class MainActivity extends Activity { private ListView listView1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Location location_data[] = new Location[] { new Location(R.drawable.ic_launcher, "Location 1", "Fruit!", "2 miles", "8-4 mon-fri\nclosed sun"), new Location(R.drawable.ic_launcher, "Location 2", "Veggies!", "2 miles", "8-5"), new Location(R.drawable.ic_launcher, "Location 3", "Plants!", "2 miles", "8-5"), new Location(R.drawable.ic_launcher, "Location 4", "Flowers!", "2 miles", "8-5"), new Location(R.drawable.ic_launcher, "Location 5", "Baked Goods!", "2 miles", "8-5") }; LocationAdapter adapter = new LocationAdapter(this, R.layout.listview_item_row, location_data); //adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5")); listView1 = (ListView)findViewById(R.id.listView1); View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null); listView1.addHeaderView(header); listView1.setAdapter(adapter); } }
This works. I want to now do something like
adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5"));
AFTER filling it with the array.Here is my LocationAdapter class:
package com.example.listviewtest; import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; public class LocationAdapter extends ArrayAdapter<Location>{ Context context; int layoutResourceId; Location data[] = null; public LocationAdapter(Context context, int layoutResourceId, Location[] data) { super(context, layoutResourceId, data); this.layoutResourceId = layoutResourceId; this.context = context; this.data = data; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; LocationHolder holder = null; if(row == null) { LayoutInflater inflater = ((Activity)context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); holder = new LocationHolder(); holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon); holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle); holder.details = (TextView)row.findViewById(R.id.details); holder.distance = (TextView)row.findViewById(R.id.distance); holder.hours = (TextView)row.findViewById(R.id.hours); row.setTag(holder); } else { holder = (LocationHolder)row.getTag(); } Location location = data[position]; holder.txtTitle.setText(location.title); holder.imgIcon.setImageResource(location.icon); holder.details.setText(location.details); holder.distance.setText(location.distance); holder.hours.setText(location.hours); return row; } static class LocationHolder { ImageView imgIcon; TextView txtTitle; TextView details; TextView distance; TextView hours; } }
Any ideas on how I can implement this? Thanks.
-
sotrh almost 10 yearsYou won't have to use the adapter.notifyDataSetChanged() because you are adding values in onCreate (aka. the view isn't showing yet). If you do it elsewhere you will.
-
user1282637 almost 10 yearsThank you, this is what I had to do
-
zionpi about 8 yearsif data element inside Location data array facility with media info which comes from internet,call
notifyDatasetChanged()
every time will make the app ANR.