Java 使用Android应用程序的自定义适配器将项目动态添加到列表视图

Java 使用Android应用程序的自定义适配器将项目动态添加到列表视图,java,android,android-layout,listview,android-listview,Java,Android,Android Layout,Listview,Android Listview,所以,现在我有一个自定义适配器类,它接受一个位置数组并将它们添加到ListView中。这一切都很好,但我想在初始化之后将位置添加到此listview。例如,有人可以“添加位置”,它会将其添加到此ListView。以下是我的主要活动: package com.example.listviewtest; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.wi

所以,现在我有一个自定义适配器类,它接受一个位置数组并将它们添加到ListView中。这一切都很好,但我想在初始化之后将位置添加到此listview。例如,有人可以“添加位置”,它会将其添加到此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的事情(新位置(R.drawable.ic_launcher,“位置6”,“蔬菜!”,“2英里”,“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;
}
}
package com.example.listviewtest;
导入android.app.Activity;
导入android.content.Context;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.ImageView;
导入android.widget.TextView;
公共类LocationAdapter扩展了ArrayAdapter{
语境;
国际布局资源;
位置数据[]=null;
public LocationAdapter(上下文上下文,int-layoutResourceId,位置[]数据){
超级(上下文、布局资源ID、数据);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
这个数据=数据;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行=转换视图;
LocationHolder=null;
if(行==null)
{
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(layoutResourceId,父级,false);
保持架=新位置保持架();
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=(LocationHolder)行。getTag();
}
位置=数据[位置];
holder.txtTitle.setText(location.title);
holder.imgIcon.setImageResource(location.icon);
holder.details.setText(location.details);
保持架距离设置文本(位置距离);
holder.hours.setText(location.hours);
返回行;
}
静态类位置保持器
{
ImageView imgIcon;
TextView-txtTitle;
文本视图详细信息;
文本视图距离;
文本浏览时间;
}
}

关于如何实现这一点,有什么想法吗?谢谢。

在您的主要活动中,我建议您使用ArrayList而不是Location[],以便更轻松地添加新的Location元素。然后,与其让LocationAdapter扩展ArrayAdapter,不如让它扩展ListAdapter,这样您就可以将ArrayList传递给它

也就是说,在MainActivity中的addLocation(Location l)方法中,只需向传递给适配器的Location[]或ArrayList数据结构添加一个元素,然后调用:

adapter.notifyDataSetChanged();
请注意,您需要将适配器设置为MainActivity中的成员变量,以允许在onCreate()之外进行访问

  • 在适配器中,将
    位置数据[]
    从阵列更改为
    ArrayList
    并重写相应的构造函数
  • 在活动中,将变量
    数据
    设为字段(键入
    ArrayList
  • 添加位置时,可以使用
    数据。添加(位置)
  • 然后可以在适配器上调用
    notifyDatasetChanged()

  • .

    将数据存储在
    阵列列表中,而不仅仅是
    位置[]
    ,然后在列表适配器中创建一个公共类:

    ArrayList<Location> data = new ArrayList<Location>();
    
    @Override
    public void add(Location location) {
        data.add(location);
        notifyDataSetChanged();
    }
    
    ArrayList data=new ArrayList();
    @凌驾
    公共作废添加(位置){
    数据。添加(位置);
    notifyDataSetChanged();
    }
    
    然后,当您想向列表中添加项目时,只需调用
    location\u data.add(new\u location)


    编辑:看起来您从几个基本相同的答案中进行了选择。

    看起来您需要覆盖LocationAdapter类中的add方法,以将对象添加到内部列表中

    @Override
    public void add(Location location)
    {
        super.add(location);
        data.add(location);
    }
    
    此实现要求您将数据更改为ArrayList,而不仅仅是数组,否则您必须自己对数组进行编码以重新调整大小

    ArrayList<Location> data = null; // Alternatively use new ArrayList<Location>();
    
    ArrayList data=null;//或者使用新的ArrayList();
    

    如果不这样做,内部数据将保持不变,并且调用add不会更改列表。这是不好的,因为您使用数据变量来获取视图的值。

    您不必使用adapter.notifyDataSetChanged(),因为您正在onCreate中添加值(即视图尚未显示)。如果你在其他地方这样做,你会的。谢谢,这是我必须做的。如果位置数据阵列设施中的数据元素包含来自互联网的媒体信息,每次调用
    notifyDatasetChanged()
    都会使应用程序成为ANR。