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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23939800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:14:50  来源:igfitidea点击:

Dynamically add items to list view using custom adapter for Android app

javaandroidandroid-layoutlistviewandroid-listview

提问by user1282637

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:

所以,现在我有一个自定义适配器类,它接收一个位置数组并将它们添加到一个 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);
}
}

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.

这有效。我现在想在adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5"));用数组填充它之后做一些事情。

Here is my LocationAdapter class:

这是我的 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;
}
}

Any ideas on how I can implement this? Thanks.

关于如何实现这一点的任何想法?谢谢。

采纳答案by LordRaydenMK

  1. In your adapter change the Locations data[]from array to ArrayList<Location>and override the appropriate constructor
  2. In your activity, make your variable dataa field (type ArrayList<Location>)
  3. When you add a location you can use data.add(location)
  4. Then you can call notifyDatasetChanged()on your adapter
  1. 在您的适配器中,将Locations data[]from 数组更改为 ArrayList<Location>并覆盖相应的构造函数
  2. 在您的活动中,让您的变量data成为一个字段(类型ArrayList<Location>
  3. 添加位置时,您可以使用 data.add(location)
  4. 然后你可以调用notifyDatasetChanged()你的适配器

Example code.

示例代码

回答by bstar55

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.

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

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:

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

adapter.notifyDataSetChanged();

Note that you'll need to make your adapter a member variable in your MainActivity to allow access outside of your onCreate().

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

回答by Engineero

Store your data in an ArrayList<Location>instead of just Location[], and then make a public class in your list adapter:

将您的数据存储在一个ArrayList<Location>而不是 just 中Location[],然后在您的列表适配器中创建一个公共类:

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).

然后,当您想向列表中添加项目时,只需调用location_data.add(new_location).

Edit:It looks like you have your pick from several mostly identical answers.

编辑:看起来您可以从几个几乎相同的答案中进行选择。

回答by sotrh

Looks like you need to override the add method in your LocationAdapter class to add the object to the internal list

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

@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 而不仅仅是数组,否则您必须自己编写代码重新调整数组大小。

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.

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