Динамически добавлять элементы в список, используя пользовательский адаптер для Android-приложения
Итак, прямо сейчас у меня есть пользовательский класс адаптера, который принимает массив Locations и добавляет их в ListView. Все это прекрасно и денди, но я хотел бы добавить Locations в этот список после этой инициализации. Например, кто-то может "добавить местоположение", и он добавит его в этот ListView. Вот моя основная деятельность:
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);
}
}
Это работает. Теперь я хочу сделать что-то вроде adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5"));
ПОСЛЕ заполнения массива.
Вот мой класс LocationAdapter:
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;
}
}
Любые идеи о том, как я могу это реализовать? Спасибо.
Ответы
Ответ 1
- В вашем адаптере измените данные Locations [] из массива на
ArrayList и переопределить соответствующий конструктор
- В вашем
деятельности, сделайте переменные данные полем (тип ArrayList
- Когда вы добавляете местоположение, вы можете использовать data.add(location)
- Затем вы можете вызвать notifyDatasetChanged() на вашем адаптере
Пример кода: http://androidadapternotifiydatasetchanged.blogspot.in/
Ответ 2
Сохраните свои данные в ArrayList<Location>
, а не только Location[]
, а затем создайте открытый класс в своем адаптере списка:
ArrayList<Location> data = new ArrayList<Location>();
@Override
public void add(Location location) {
data.add(location);
notifyDataSetChanged();
}
Затем, когда вы хотите добавить элемент в список, просто вызовите location_data.add(new_location)
.
Изменить: Похоже, что у вас есть выбор из нескольких наиболее точных ответов.
Ответ 3
Похоже, вам нужно переопределить метод add в классе LocationAdapter, чтобы добавить объект во внутренний список
@Override
public void add(Location location)
{
super.add(location);
data.add(location);
}
Эта реализация требует, чтобы вы изменяли данные в ArrayList, а не только на массив, иначе вам пришлось бы закодировать массив, размер которого изменился бы самостоятельно.
ArrayList<Location> data = null; // Alternatively use new ArrayList<Location>();
Если вы этого не сделаете, внутренние данные останутся неизменными, и вызов для добавления не изменит список. Это плохо, потому что вы используете переменную данных для получения значений для представлений.
Ответ 4
В вашей основной деятельности я бы рекомендовал использовать ArrayList < Местоположение > , а не Местоположение [], чтобы упростить добавление новых элементов местоположения. Затем, вместо того, чтобы использовать LocationAdapter, ArrayAdapter <Location> , расширьте ListAdapter <Location> , чтобы вы могли передать свой ArrayList < Расположение > к нему.
Тем не менее, все, что вам нужно сделать в методе addLocation (Location l) в вашем MainActivity, - это добавить элемент либо в Location [], либо в ArrayList < Местоположение > структура данных, которую вы передали вашему адаптеру, а затем вызывайте:
adapter.notifyDataSetChanged();
Обратите внимание, что вам нужно будет сделать ваш адаптер переменной-членом в вашем MainActivity, чтобы разрешить доступ за пределами вашего onCreate().