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.
- In your adapter change the
Locations data[]from array toArrayList<Location>and override the appropriate constructor - In your activity, make your variable
dataa field (typeArrayList<Location>) - When you add a location you can use
data.add(location) - Then you can call
notifyDatasetChanged()on your adapter
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.
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.
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().
来源:https://stackoverflow.com/questions/23939800/dynamically-add-items-to-list-view-using-custom-adapter-for-android-app