更改列表项上的ImageView背景单击

时间:2015-10-19 11:23:16

标签: android listview adapter

我有一个包含行的ListView:2个按钮(减号,加号)和它们之间的ImageView。在减号或加号按钮上单击,我更改ImageView背景。

问题 - 当我点击f.ex第6行上的按钮(我需要滚动查看该行)时,第2行的ImageView也会改变背景。这是我的适配器代码:

public class PickUpProductsAdapter extends ArrayAdapter<PickUpProductsAdapterItem> {

private Context context;
private int resource;
private AddProductAdapterListener listener;
private int totalQuantity;
private int totalPoints;
private boolean paddingForLastItem;
private PickedUpProducts pickedUpProducts = new PickedUpProducts();
private List<PickUpProductsAdapterItem> items;

public static PickUpProductsAdapter create(Context context, List<Place.Product> products, boolean paddingForLastItem){
    PickUpProductsAdapter adapter = new PickUpProductsAdapter(context, R.layout.pick_up_product_item, createItems(products));
    adapter.paddingForLastItem = paddingForLastItem;
    return adapter;
}

private static List<PickUpProductsAdapterItem> createItems(List<Place.Product> products) {
    ArrayList<PickUpProductsAdapterItem> result = new ArrayList<PickUpProductsAdapterItem>();
    for(Place.Product product : products){
        result.add(new PickUpProductsAdapterItem(product));
    }
    return result;
}

public PickUpProductsAdapter(Context context, int resource, List<PickUpProductsAdapterItem> objects) {
    super(context, resource, objects);
    this.context = context;
    this.resource = resource;
    this.items = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    AddProductAdapterItemViewHolder viewHolder;
    PickUpProductsAdapterItem item = items.get(position);

    if(convertView == null){
        viewHolder = new AddProductAdapterItemViewHolder();
        convertView = LayoutInflater.from(context).inflate(resource, parent, false);
        viewHolder.findViewsIn(convertView);
        viewHolder.setupListeners(item);
        convertView.setTag(viewHolder);
    } else{
        viewHolder = (AddProductAdapterItemViewHolder) convertView.getTag();
    }

    viewHolder.updateWith(item);

    if(position == items.size()-1 && paddingForLastItem){
        viewHolder.setBottomPadding();
    } else{
        viewHolder.clearBottomPadding();
    }
    return convertView;
}

public void setListener(AddProductAdapterListener listener) {
    this.listener = listener;
}

class AddProductAdapterItemViewHolder{

    private View root;
    private ImageView image;
    private TextView quantity;
    private TextView points;
    private ImageButton minusButton;
    private ImageButton plusButton;
    private int minusButtonAlpha = 100;

    public void findViewsIn(View convertView) {
        root = convertView;
        image = (ImageView) convertView.findViewById(R.id.product_image);
        quantity = (TextView) convertView.findViewById(R.id.product_quantity);
        points = (TextView) convertView.findViewById(R.id.product_points);
        minusButton = (ImageButton) convertView.findViewById(R.id.product_minus_button);
        minusButton.setImageAlpha(minusButtonAlpha);
        minusButton.setEnabled(false);
        plusButton = (ImageButton) convertView.findViewById(R.id.product_plus_button);
    }

    public void updateWith(PickUpProductsAdapterItem item) {
        int itemQuantity = item.getQuantity();
        final String imageXxhpdiMedium = item.getProduct().getImageXxhpdiMedium();
        if(imageXxhpdiMedium.equals("http://")){ // use placeholder without Picasso to load it only once. When Picasso is used starting animation causes load it multiple times.
            image.setImageResource(R.drawable.product_placeholder_120_white);
        } else {
            Picasso.with(context).
                    load(imageXxhpdiMedium).
                    placeholder(R.drawable.empty_120).
                    error(R.drawable.product_placeholder_120_white).
                    into(image);
        }
        if(itemQuantity > 0){
            quantity.setText(String.format("%d x %s", itemQuantity, item.getProduct().getName()));
            points.setText(String.format("%d %s", item.getProduct().getPoints() * itemQuantity, context.getString(R.string.pkt)));
        } else{
            quantity.setText(item.getProduct().getName());
            points.setText(String.format("%d %s", item.getProduct().getPoints(), context.getString(R.string.pkt)));
        }
    }

    public void setupListeners(final PickUpProductsAdapterItem item) {
        minusButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (totalQuantity > 0 && item.getQuantity() > 0) {
                    totalQuantity--;
                }
                if (totalPoints > 0 && item.getQuantity() > 0) {
                    totalPoints -= item.getProduct().getPoints();
                }
                item.decrementQuantity();
                if (item.getQuantity() >= 0) {
                    image.startAnimation(AnimationUtils.loadAnimation(context, R.anim.product_scale));
                }
                if (item.getQuantity() < 1) {
                    image.setBackgroundResource(R.drawable.no_product_selected);
                    minusButton.setImageAlpha(minusButtonAlpha);
                    minusButton.setEnabled(false);
                }
                notifyDataSetChanged();
                if (listener != null) {
                    listener.productsQuantityChanged(pickedUpProducts.remove(item, totalQuantity, totalPoints));
                }
            }
        });
        plusButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                item.incrementQuantity();
                image.setBackgroundResource(R.drawable.product_selected);
                image.startAnimation(AnimationUtils.loadAnimation(context, R.anim.product_scale));
                totalQuantity++;
                minusButton.setImageAlpha(255);
                minusButton.setEnabled(true);
                totalPoints += item.getProduct().getPoints();
                notifyDataSetChanged();
                if(listener != null){
                    listener.productsQuantityChanged(pickedUpProducts.add(item, totalQuantity, totalPoints));
                }
            }
        });
    }

    public void setBottomPadding() {
        ViewGroup.LayoutParams params = root.getLayoutParams();
        params.height = (int) (root.getResources().getDimension(R.dimen.pick_up_product_item_height) + root.getResources().getDimension(R.dimen.earn_done_height));
        root.setLayoutParams(params);
    }

    public void clearBottomPadding() {
        ViewGroup.LayoutParams params = root.getLayoutParams();
        params.height = (int) (root.getResources().getDimension(R.dimen.pick_up_product_item_height));
        root.setLayoutParams(params);
    }
}

public interface AddProductAdapterListener{
    void productsQuantityChanged(PickedUpProducts pickedUpProducts);
}

}

这一行:

image.setBackgroundResource(R.drawable.product_selected);

以某种方式执行2行而不是我点击的那一行。

我可能在ViewHolder中使用OnClickListener弄乱了一些东西。

任何想法代码可能有什么问题?感谢。

1 个答案:

答案 0 :(得分:0)

你说得对,问题在于

image.setBackgroundResource(R.drawable.product_selected);

您设置了后台资源if (item.getQuantity() < 1) {

现在图像的背景从未被清除或重置。现在,ImageView被回收或重复使用,您只能在

中更改源图像而不是背景
if(imageXxhpdiMedium.equals("http://")){ // use placeholder without Picasso to load it only once. When Picasso is used starting animation causes load it multiple times.
        image.setImageResource(R.drawable.product_placeholder_120_white);
    } else {
        Picasso.with(context).
                load(imageXxhpdiMedium).
                placeholder(R.drawable.empty_120).
                error(R.drawable.product_placeholder_120_white).
                into(image);
    }

因此背景会在循环图像中反映出来。