简体   繁体   English

列表内的按钮侦听器产生意外结果

[英]Button listener inside a list producing unexpected results

public class CustomerProductAdapter extends BaseAdapter {
Context ccon;
ImageView cprdctimg;

LayoutInflater cprdctinflater;
View cprdctview;
TextView cprdctname,cprdctdesc,cprdctprice,cprdctquant,cpquantity;
ArrayList<Product> cproduct;
Product currentproduct;
Button cpincq,cpdecq;
@Override
public int getCount() {
    return cproduct.size();
}

@Override
public Object getItem(int i) {
    return cproduct.get(i).getPname();
}

public CustomerProductAdapter(Context con,ArrayList<Product> product) {
    this.cproduct=product;
    this.ccon = con;
    cprdctinflater=LayoutInflater.from(con);
}

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

@Override
public View getView(int i, View view, final ViewGroup viewGroup) {
    cprdctview=cprdctinflater.inflate(R.layout.cplist,null);
    cpincq=cprdctview.findViewById(R.id.cpincq);
    cpquantity=cprdctview.findViewById(R.id.cpquantity);
    cpdecq=cprdctview.findViewById(R.id.cpdecq);
    cprdctname=cprdctview.findViewById(R.id.cpname);
    cprdctdesc=cprdctview.findViewById(R.id.cpdesc);
    cprdctimg=cprdctview.findViewById(R.id.cppic);
    cprdctprice=cprdctview.findViewById(R.id.cpprice);
    cprdctquant=cprdctview.findViewById(R.id.cpquant);

    currentproduct=cproduct.get(i);
    cprdctimg.setImageResource(cproduct.get(i).getPimage());
    cprdctname.append(cproduct.get(i).getPname().toString());
    cprdctdesc.append(cproduct.get(i).getPdesc().toString());
    cprdctprice.append(cproduct.get(i).getPprice().toString());
    cprdctquant.append(cproduct.get(i).getPquant());

    cpincq.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            currentproduct.inccustomerquantity();
            if(currentproduct.getcustomerquantity()>Integer.parseInt(currentproduct.getPquant()))
            {
                Toast.makeText(viewGroup.getContext(), "You cannot order more than stock", Toast.LENGTH_SHORT).show();
                currentproduct.deccustomerquantity();
            }
            else {
                cpquantity.setText("" + currentproduct.getcustomerquantity());
            }
        }
    });
    cpdecq.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(currentproduct.deccustomerquantity()) {
                cpquantity.setText("" + currentproduct.getcustomerquantity());
            }
        }
    });

    return cprdctview;
}
}

Here, if I increase the quantity of one product in the list, the corresponding TextView isn't changing.Instead some other TextView in a different list item is changed. 在这里,如果我增加列表中一种产品的数量,则相应的TextView不会更改,而是更改其他列表项中的其他TextView。 As you can see in the image,the quantity of grapes changes when I click "+" symbol in banana item. 从图像中可以看到,当我单击香蕉项目中的“ +”符号时,葡萄的数量就会改变。 Please help me to fix this error so that the change is made only to the appropriate textview. 请帮助我解决此错误,以便仅对相应的textview进行更改。

图片

When you click a button, you need to change the model in the list, not the UI. 单击按钮时,需要更改列表中的模型,而不是UI。 After that, update the desired position of the adapter. 之后,更新适配器的所需位置。 I suggest you look at the ViewHolder template. 我建议您看一下ViewHolder模板。

GetView() is called everytime when creates a row. 创建行时每次都会调用GetView()。 Therefore your global/instance variables ( currentproduct, cprdctname, cprdctdesc... ), are always refer to the last created row (when scroll up, the bottom one; when scroll down, the top one). 因此,您的全局/实例变量( currentproduct,cprdctname,cprdctdesc ... )始终引用最后创建的行(向上滚动时,底部滚动;向下滚动时,顶部滚动)。 You may save item row position as Tag to the buttons and update the corresponding item in data list. 您可以将项目行位置保存为按钮的标签 ,并更新数据列表中的相应项目。 Then call adapter to redraw all the rows by notifyDataSetChanged(). 然后调用适配器以通过notifyDataSetChanged()重绘所有行。

Try this: 尝试这个:

@Override
public View getView(int i, View view, final ViewGroup viewGroup) {
cprdctview=cprdctinflater.inflate(R.layout.cplist,null);
cpincq=cprdctview.findViewById(R.id.cpincq);
cpquantity=cprdctview.findViewById(R.id.cpquantity);
cpdecq=cprdctview.findViewById(R.id.cpdecq);
cprdctname=cprdctview.findViewById(R.id.cpname);
cprdctdesc=cprdctview.findViewById(R.id.cpdesc);
cprdctimg=cprdctview.findViewById(R.id.cppic);
cprdctprice=cprdctview.findViewById(R.id.cpprice);
cprdctquant=cprdctview.findViewById(R.id.cpquant);

currentproduct=cproduct.get(i);
cprdctimg.setImageResource(cproduct.get(i).getPimage());
cprdctname.append(cproduct.get(i).getPname().toString());
cprdctdesc.append(cproduct.get(i).getPdesc().toString());
cprdctprice.append(cproduct.get(i).getPprice().toString());
cprdctquant.append(cproduct.get(i).getPquant());

cpincq.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        currentproduct = cproduct.get((int)view.getTag()); // Get item for the clicked position
        currentproduct.inccustomerquantity();
        if(currentproduct.getcustomerquantity()>Integer.parseInt(currentproduct.getPquant()))
        {
            Toast.makeText(viewGroup.getContext(), "You cannot order more than stock", Toast.LENGTH_SHORT).show();
            currentproduct.deccustomerquantity();
        }
        else {
            //cpquantity.setText("" + currentproduct.getcustomerquantity());
            notifyDataSetChanged();
        }
    }
});
cpdecq.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        currentproduct = cproduct.get((int)view.getTag()); // Get item for the clicked position
        if(currentproduct.deccustomerquantity()) {
            //cpquantity.setText("" + currentproduct.getcustomerquantity());
            notifyDataSetChanged();
        }
    }
});

// Save the current position as Tag to the buttons
cpincq.setTag(i);
cpdecq.setTag(i);

return cprdctview;
}

Hope that helps! 希望有帮助!

As per android official documentation , do not use position as it gets reused . 根据android官方文档,不要使用位置,因为它会被重用。 Using getAdapterPosition() is recommended. 建议使用getAdapterPosition()。 So in your code instead of listOfItems.get(i) use listOfItems(getAdapterPosition()) 因此,在您的代码中,而不是listOfItems.get(i),请使用listOfItems(getAdapterPosition())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM