Breno Macena Breno Macena - 3 months ago 22
Android Question

Android: ArrayAdapter is changing the object attribute

I'm using a custom ListView in my app. The problem is, the object "Pedido" can have the attribute "timestampAtendimento" as a null attribute, and in this case the TextView on my item layout and the item background color should not be changed. However, even when the attribute is null, the class "ListaPedidosRowAdapter" changes the value of the attribute, making it not null (the value is being set with the value of another object on the list).

I debugged the program several times and find out that the object list is correct, the problem happens inside the "ListaPedidosRowAdapter" class. But I have no idea why it's happening.

Could someone help me?

That is my "ListaPedidosRowAdapter" class:

public class ListaPedidosRowAdapter extends ArrayAdapter<Pedido> {

private List<Pedido> pedidos;
private Context context;

public ListaPedidosRowAdapter(List<Pedido> pedidos, Context context) {
super(context, item_lista_pedidos);

this.pedidos = pedidos;
this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder;

if(convertView == null){
convertView = LayoutInflater.from(context).inflate(item_lista_pedidos, null, true);
holder = new ViewHolder();
holder.itemNomePratoTextView = (TextView) convertView.findViewById(R.id.itemNomePratoTextView);
holder.itemQtdPedidoTextView = (TextView) convertView.findViewById(R.id.itemQtdPedidosTextView);
holder.itemGarcomNomeTextView = (TextView) convertView.findViewById(R.id.itemGarcomNomeTextView);
holder.itemTimestampPedidoTextView = (TextView) convertView.findViewById(R.id.itemTimestampPedidoTextView);
holder.itemTimestampAtendimentoTextView = (TextView) convertView.findViewById(R.id.itemTimestampAtendimentoTextView);

convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}

Pedido pedido = pedidos.get(position);

holder.itemNomePratoTextView.setText(pedido.nomeServico);
holder.itemGarcomNomeTextView.setText(pedido.usuario);
holder.itemTimestampPedidoTextView.setText(ValidateDate.getDateTimeForView(pedido.timestampPedido));
holder.itemQtdPedidoTextView.setText(Integer.toString(pedido.quantidade));
// if the attribute is null do not change the text view
if(pedido.timestampAtendimento != null) {
holder.itemTimestampAtendimentoTextView.setText( ValidateDate.getDateTimeForView( pedido.timestampAtendimento ) );
convertView.setBackgroundResource(R.drawable.item_list_disabled);
}

return convertView;
}

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

static class ViewHolder{
public TextView itemNomePratoTextView;
public TextView itemQtdPedidoTextView;
public TextView itemGarcomNomeTextView;
public TextView itemTimestampPedidoTextView;
public TextView itemTimestampAtendimentoTextView;
}
}

Answer

Here's the trick:

if(pedido.timestampAtendimento != null) {
    holder.itemTimestampAtendimentoTextView.setText( ValidateDate.getDateTimeForView( pedido.timestampAtendimento ) );
    convertView.setBackgroundResource(R.drawable.item_list_disabled);
} else {
    holder.itemTimestampAtendimentoTextView.setText("");
    convertView.setBackgroundDrawable(null);
}

You have to remember that row views are reused. For every if condition that binds your views to your data, you'll need an else one to clean them up if such condition doesn't apply.

Comments