最后位置null ListView自定义适配器

时间:2016-02-24 13:10:28

标签: android listview custom-adapter

在我的适配器类中,我遇到了getView方法()的问题。当我打印我想要列出的元素的位置时,总是错过最后一个但重复第一个。例如,我有一个包含7个元素的RowItem(自定义)类的数组。我得到的职位是:

@Override
public View getView(int position, View convertView, final ViewGroup parent) {
    System.out.println("Position : "+position);
    return null
}

Position : 0
Position : 1
Position : 2
Position : 3
Position : 4
Position : 5
.....

但是,如果方法getCount打印收据

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    System.out.println("Count "+getCount());
    return null;
}

Count : 7
Count : 7
Count : 7
Count : 7
Count : 7
Count : 7

这导致我的最后一个元素总是像第一个元素。在我的列表中,我有一个按钮,当您单击时,修改按钮所属的单元格中的值。但是这个错误,它只在视觉上修改了第一个元素和最后一个元素。我的班级:

@SuppressLint("InflateParams")
public class CustomListViewAdapter extends ArrayAdapter<RowItem> {

Context context;
private ArrayList<RowItem> items;

public CustomListViewAdapter(Context context, int resourceId,
    List<RowItem> items) {
    super(context, resourceId, items);
    this.context = context;
    this.items = new ArrayList<RowItem>();
    this.items.addAll(items);
}

/*private view holder class*/
static class ViewHolder {
    TextView txtNombre;
    TextView txtTicket;
    TextView txtAsiento;
    TextView txtOrden;
    TextView txtNumero;
    TextView txtMensaje;
    TextView txtAdicionales;
    TextView txtOtros;
    TextView txtCategoria;
    Button btn; 
 }


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

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

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

我从我的活动中打电话给这个班级

CustomListViewAdapter adapter;
public List<RowItem> rowItems = new ArrayList<RowItem>();
rowItems = nueva.getInscripcionsByRut(ValidacionMultiple.this, rut_inscripcion);
adapter = new CustomListViewAdapter(ValidacionMultiple.this,R.layout.lista_validacion_multiple, rowItems );
listView.setAdapter(adapter);

方法getInscripcionsByRut

public List<RowItem> getInscripcionsByRut(Context context, String rut){
    inscripcionValida = new Inscripcions();
    List<RowItem> rowItems = new ArrayList<RowItem>();
    RowItem item;
    bdTickets = new TicketsBaseDatos(context, Config.NAME_DATABASE, null, 1);
    SQLiteDatabase db = bdTickets.getWritableDatabase();
    SessionManager manager = new SessionManager();
    String codigoEvento = manager.getValue(context, "codigoEvento");
    String[] args = new String[] {rut,codigoEvento};
    String codigo_checkin = manager.getValue(context, "checkin");
    Cursor c = db.rawQuery("SELECT * FROM Inscripcion WHERE rut=? AND codigo_evento=?",args);
    for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
         item = new RowItem();
         inscripcionValida.setId(c.getInt(0));
         inscripcionValida.setHash(c.getString(1));
         inscripcionValida.setCodigo_evento(c.getString(2));
         inscripcionValida.setTicket(c.getString(3));
         inscripcionValida.setNombre(c.getString(4));
         inscripcionValida.setInscripcion_id(c.getString(5));
         inscripcionValida.setValidado(c.getInt(6));
         inscripcionValida.setSincronizado(c.getInt(7));
         inscripcionValida.setNumero(c.getString(8));
         inscripcionValida.setAsiento(c.getString(9));
         inscripcionValida.setAdicionales(c.getString(10));
         inscripcionValida.setOtros(c.getString(11));
         inscripcionValida.setCategoria(c.getString(12));
         inscripcionValida.setRut(c.getString(14));
         inscripcionValida.setTalla(c.getString(15));
         inscripcionValida.setNombreResponsable(c.getString(17));
         inscripcionValida.setFechaValidacion(c.getString(16));
         item.setAsiento(inscripcionValida.getAsiento());
         item.setNumero(inscripcionValida.getNumero());
         item.setHash(inscripcionValida.getHash());
         item.setNombre(inscripcionValida.getNombre());
         item.setTicket(inscripcionValida.getTicket());
         item.setOtros(inscripcionValida.getOtros());
         item.setAdicionales(inscripcionValida.getAdicionales());
         if(manager.getValue(context,"checkin") != null){
             item.setValidado(checkinValidado(context,inscripcionValida.getInscripcion_id(),codigo_checkin));
         }else{
             item.setValidado(inscripcionValida.getValidado());
         }
         item.setId_inscripcion(Integer.parseInt(inscripcionValida.getInscripcion_id()));
         rowItems.add(item); 
    }
    c.close();
    db.close();
    return rowItems;
}

它还将数据从我的数据库发送到我的列表以显示在列表视图中。

我的getView方法如下:

 @Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    System.out.println(getCount());
    ViewHolder holder;
    RowItem rowItem = getItem(position);
    if (convertView == null) {
        LayoutInflater mInflater = LayoutInflater.from(getContext());
        convertView = mInflater.inflate(R.layout.lista_validacion_multiple,null);
        holder = new ViewHolder();
        holder.txtNombre = (TextView)convertView.findViewById(R.id.txtNombre);
        holder.btn = (Button)convertView.findViewById(R.id.button1);
        holder.txtMensaje = (TextView)convertView.findViewById(R.id.txtMensaje);
        convertView.setTag(holder); 
    } else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.txtNombre.setText(Html.fromHtml("Nombre: <b>"+rowItem.getNombre()+"</b>"));
    if(rowItem.getValidado()==1){
        holder.btn.setBackgroundResource(R.drawable.icon_big_alert);
        holder.btn.setText("");
        holder.txtMensaje.setText("E-ticket ya validado");
    }else{
        holder.btn.setTag(position);
        holder.btn.setOnClickListener(new View.OnClickListener() {
           //More code...
        });
    }
    convertView.setTag(holder);
    return convertView;
}

这里发生的是,如果我点击第一个项目或最后一个项目的按钮,您将获得相同的数据并且不对应。

1 个答案:

答案 0 :(得分:1)

只需在if条件中添加holder.btn.setOnClickListener(null);即可。

if(rowItem.getValidado()==1){  
     holder.btn.setOnClickListener(null);
}else{
     holder.btn.setOnClickListener(new View.OnClickListener() {
          int position=(Integer)v.getTag();
          RowItem item_click = getItem(position);
          Button b = (Button)v.findViewById(R.id.button1);
          b.setTag(position);
          //More elements.
     });
}

您看到的不一致行为是因为listview中的视图回收。您对列表项的视图将被回收并重复使用。假设您列表中有100个项目,因此将不会创建100个不同的视图。它只会创建大约等于列表中可见项目数的唯一视图。因此,如果某个项目从列表中消失,则其视图不会被销毁,而是会将其提供给其他项目。

public View getView(int position, View convertView, ViewGroup parent);

这里convertView是被回收的视图

现在,在您的代码中,您将onClickListener分配给一个视图。对于第7个项目,早期将被回收,已经设置了onClickListener。所以只需删除那个你不希望听众出现的行上的onClickListener