如何访问ListView中的特定行并对该行的内容进行操作?

时间:2017-10-28 20:27:59

标签: android android-layout listview onclicklistener custom-adapter

我有一个列表视图,使用自定义适配器和行布局填充了一组对象。该行显示对象的名称,价格,包含用于更改数量的按钮,并根据所选数量显示总数。

Example of list populated with 3 items

问题在于:我想告诉列表视图,例如,当用户点击第二行中的数量按钮时,我想访问同一行中的价格和数量值,& ;将结果显示在该特定行末尾的总单元格中。我无法弄清楚如何做到这一点。我很困惑,因为按钮元素在XML布局中有一个ID,所以如何区分第二行中的按钮和第一行或最后一行中的按钮,因为它们全部都是重复?

我知道将执行我需要的数学运算的OnClickListener方法的语法,我只是不知道程序应该在哪里实现它。我已尝试使用适配器,但只有列表中最后一行的按钮才能正常运行,而不是所有按钮。我现在一直在搜索和谷歌搜索,我已经看到了不同的方法,但我正在努力实施它们。

我得到的最好的方法是关于一个名为ListView.getChildAt(index)的方法,该方法应该根据索引返回列表中的特定行,但是如何根据单击的按钮获取行的索引? This is the stackoverflow post where I read on the .getChildAt(index) method

我将在下面为我的项目提供代码:

ShopActivity.java的代码:

public class ShopActivity extends AppCompatActivity {

ListView listView;
ItemListAdapter adapter;
ArrayList<ShoppingItem> shoppingItems = new ArrayList<ShoppingItem>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.shop_activity);

    shoppingItems.add(new ShoppingItem("Drink", "Water Bottle 1.5 ltr", 11));
    shoppingItems.add(new ShoppingItem("Drink", "Pepsi 2 ltr", 10));
    shoppingItems.add(new ShoppingItem("Drink", "Orange Juice 1.5 ltr", 7));

    listView = (ListView) findViewById(R.id.itemListView);
    adapter = new ItemListAdapter(this, R.layout.item_layout, shoppingItems);
    listView.setAdapter(adapter);
}

适配器代码:

public class ItemListAdapter extends ArrayAdapter<ShoppingItem> {

private ArrayList<ShoppingItem> items;
private int layoutResourceId;
private Context context;
ItemHolder holder = new ItemHolder();

public ItemListAdapter(Context context, int layoutResourceId, ArrayList<ShoppingItem> items) {
    super(context, layoutResourceId, items);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.items = items;
}

public static class ItemHolder {
    public ShoppingItem shoppingItem;
    public TextView itemName;
    public TextView itemPrice;
    public TextView itemQuantity;
    public TextView totalPriceNumber;
    public ImageButton plusButton;
    public ImageButton minusButton;
}

@Override
public int getCount() {
    return items.size();
}

@Override
public ShoppingItem getItem(int position) {
    return items.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    View rowView = convertView;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(layoutResourceId, parent, false);

        TextView itemName = (TextView) rowView.findViewById(R.id.itemName);
        TextView itemPrice = (TextView) rowView.findViewById(R.id.itemPrice);
        TextView itemQuantity = (TextView) rowView.findViewById(R.id.itemQuantity);
        TextView totalPriceNumber = (TextView) rowView.findViewById(R.id.totalPrice);
        ImageButton plusButton = (ImageButton) rowView.findViewById(R.id.plusButton);
        ImageButton minusButton = (ImageButton) rowView.findViewById(R.id.minusButton);
        holder.itemName = itemName;
        holder.itemPrice = itemPrice;
        holder.itemQuantity = itemQuantity;
        holder.totalPriceNumber = totalPriceNumber;
        holder.plusButton = plusButton;
        holder.minusButton = minusButton;

        rowView.setTag(holder);

    } else
        holder = (ItemHolder) rowView.getTag();

    holder.shoppingItem = items.get(position);

    holder.itemName.setText(holder.shoppingItem.getItemName());
    holder.itemPrice.setText(Double.toString(holder.shoppingItem.getItemPrice()));
    holder.itemQuantity.setText(Integer.toString(holder.shoppingItem.getQuantity()));
    holder.totalPriceNumber.setText(Double.toString(holder.shoppingItem.getItemPrice() * holder.shoppingItem.getQuantity()));

    final int rowPosition = position;
    holder.plusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.shoppingItem = items.get(rowPosition);
            int newQuantity = holder.shoppingItem.getQuantity();
            newQuantity++;
            holder.shoppingItem.setQuantity(newQuantity);

            holder.itemQuantity.setText(Integer.toString(newQuantity));
            holder.totalPriceNumber.setText(Double.toString(holder.shoppingItem.getItemPrice() * holder.shoppingItem.getQuantity()));
            notifyDataSetChanged();
        }
    });

    return rowView;
}

行XML代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TableRow>

        <CheckBox
            android:layout_width="25dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center" />

        <ImageView
            android:id="@+id/imageBar"
            android:layout_width="50dp"
            android:layout_height="75dp"
            android:layout_gravity="center"
            android:src="@drawable/drink" />

        <TextView
            android:id="@+id/itemName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="3"
            android:width="0dp" />

        <TextView
            android:id="@+id/itemPrice"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:width="0dp"
            android:gravity="center" />

        <ImageButton
            android:id="@+id/minusButton"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="0.3" />

        <TextView
            android:id="@+id/itemQuantity"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="0.4"
            android:width="0dp"
            android:gravity="center" />

        <ImageButton
            android:id="@+id/plusButton"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="0.3" />

        <TextView
            android:id="@+id/totalPrice"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:width="0dp"
            android:gravity="center" />
    </TableRow>
</TableLayout>

ShoppingItem对象的代码:

public class ShoppingItem {
private String itemType;
private String itemName;
private double itemPrice;
private int quantity = 1;

public ShoppingItem(String itemType, String itemName, double itemPrice, int quantity) {
    this.itemType = itemType;
    this.itemName = itemName;
    this.itemPrice = itemPrice;
    this.quantity = quantity;
}

public String getItemType() {
    return this.itemType;
}

public void setItemType(String itemType) {
    this.itemType = itemType;
}

public String getItemName() {
    return this.itemName;
}

public void setItemName(String itemName) {
    this.itemName = itemName;
}

public double getItemPrice() {
    return this.itemPrice;
}

public void setItemPrice(double itemPrice) {
    this.itemPrice = itemPrice;
}

public int getQuantity() {
    return this.quantity;
}

public void setQuantity(int quantity) {
    this.quantity = quantity;
}

我是Android开发领域的新手。

1 个答案:

答案 0 :(得分:1)

您的每一行代表一个数据集。例如,您有一个项目的数据类。

data class Item(name: String, price: Double)

为数量quantity: Int

添加字段

在加号按钮的onClick中,增加项目的quantity变量。例如:

// data set is something like this...
val dataSet = mutableListOf<Item>()

// creating the view for row i...
plusButton.onClick {
    dataSet[i].quantity++
    notifyItemChanged(i) // dont think this exists for ListView, but you can also just use notifyDataSetChanged, which will invalidate all rows
}

增加数量后,触发更改行的notifyItemChanged方法,这将触发行的UI更新,然后代表当前数据集。

您应该在onClick方法中添加getView侦听器,而不是i使用position来访问数据集中的项目。

编辑:

getView()方法中尝试以下方法:

final int rowPosition = position;
plusButton.setOnClickListener(new View.OnClickListener(View v) {
    items.get(rowPosition).quantity++;
    notifyDataSetChanged();
});