quando me deparei com uma situação chata: Ao marcar alguns checkboxs, e usar o scroll da
app, percebi que alguns itens que não tinha marcado, misteriosamente apareciam marcados, e os
itens que tinha marcado antes dos scrooling, já não esatavam mais marcados.
Pois bem, após algumas pesquisas vi que esse problema estava acontecendo com varias pessoas, porém
não achei nenhuma solução funcionando, e resolvi disponibilizar por aqui.
Primeiramente, os check box estavam mudando de estado por causa do ListView Recycle no meu Adapter,
que resolvi armazenando o estado em uma coleção no onClick... e no momento antes do retorno do metodo getChildView(...)
eu veficido se um determinado identificador existe.
expandable.xml
list_item_group.xml
list_item_child.xml
ChildEntity.java
package com.blogspot.receitastecnologicas; import java.math.BigDecimal; import java.text.ParseException; public class ChildEntity { private Integer id; private String descricao; private BigDecimal valor; public ChildEntity() { // TODO Auto-generated constructor stub } public ChildEntity(int id, String descr, BigDecimal valor) { this.id = id; this.descricao = descr; this.valor = valor; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } public BigDecimal getValor() { return valor; } public void setValor(BigDecimal valor) { this.valor = valor; } public String getValorFormatado() throws ParseException { // TODO Auto-generated method stub return this.getValor().toString(); } }
GrupoEntity.java
package com.blogspot.receitastecnologicas; import java.util.List; public class GrupoEntity { private Integer id; private String descricao; private String tipo; private ListlistChild; public GrupoEntity() { } public GrupoEntity(Integer id, String descricao, String tipo) { this.id = id; this.descricao = descricao; this.tipo = tipo; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } public String getTipo() { return tipo; } public void setTipo(String tipo) { this.tipo = tipo; } public List getListChild() { return listChild; } public void setListChild(List listChild) { this.listChild = listChild; } @Override public String toString() { return this.getId() + " - " + this.getDescricao(); } }
MainActivity.java
package com.blogspot.receitastecnologicas; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.widget.ExpandableListView; import com.blogspot.receitastecnologicas.R; public class MainActivity extends Activity { ExpandableListView explistView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.expandable); explistView = (ExpandableListView) findViewById(R.id.list_expandable); Listlistgrupo = new ArrayList (); GrupoEntity grupo = new GrupoEntity(1, "Street Fighter", "D"); List child = new ArrayList (); child.add(new ChildEntity(1, "Ryu", new BigDecimal(10))); child.add(new ChildEntity(2, "Blanka", new BigDecimal(20))); child.add(new ChildEntity(3, "Vega", new BigDecimal(30))); grupo.setListChild(child); listgrupo.add(grupo); GrupoEntity grupo1 = new GrupoEntity(2, "Mortal Kombat", "D"); List child1 = new ArrayList (); child1.add(new ChildEntity(4, "Sub Zero", new BigDecimal(10))); child1.add(new ChildEntity(5, "Scorpion", new BigDecimal(20))); child1.add(new ChildEntity(6, "Rayden", new BigDecimal(30))); grupo1.setListChild(child1); listgrupo.add(grupo1); GrupoEntity grupo2 = new GrupoEntity(3, "Oh my Dog!", "D"); List child2 = new ArrayList (); child2.add(new ChildEntity(7, "Allejo", new BigDecimal(10))); child2.add(new ChildEntity(8, "Chuck Norris", new BigDecimal(20))); child2.add(new ChildEntity(9, "Jeremias", new BigDecimal(30))); grupo2.setListChild(child2); listgrupo.add(grupo2); // sets the adapter that provides data to the list. explistView.setAdapter(new ExpandableAdapter(MainActivity.this, listgrupo)); } }
ExpandableAdapter.java
package com.blogspot.receitastecnologicas; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.CheckBox; import android.widget.TextView; import com.blogspot.receitastecnologicas.R; public class ExpandableAdapter extends BaseExpandableListAdapter { private Context ctx; private Listlista; private Map childSelected = new HashMap (); public ExpandableAdapter(Context ctx, List lista) { super(); this.ctx = ctx; this.lista = lista; } // interface public Object getChild(int groupPosition, int childPosition) { return lista.get(groupPosition).getListChild().get(childPosition); } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { final ViewChildHolder holder; final ChildEntity child = lista.get(groupPosition).getListChild() .get(childPosition); if (convertView == null) { convertView = LayoutInflater.from(ctx).inflate( R.layout.list_item_child, null);// carregando layout holder = new ViewChildHolder(); holder.id = (TextView) convertView.findViewById(R.id.txtid); holder.txtValor = (TextView) convertView .findViewById(R.id.txtValorTitulo); holder.check = (CheckBox) convertView.findViewById(R.id.chkItem); holder.check.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { CheckBox chk = (CheckBox) v; Log.d("Check", "Selecionado " + holder.check.getText() + " Holder:" + holder); if (chk.isChecked()) { if (!childSelected.containsKey(holder.id.getText())) childSelected.put(holder.id.getText().toString(), true); } else { if (childSelected.containsKey(holder.id.getText())) childSelected.remove(holder.id.getText()); } holder.check.setChecked(chk.isChecked()); } }); convertView.setTag(holder); } else { holder = (ViewChildHolder) convertView.getTag(); } holder.check.setText(child.getDescricao()); holder.txtValor.setText(child.getValor().toString()); holder.id.setText(child.getId().toString()); holder.check.setChecked(childSelected.containsKey(holder.id.getText())); return convertView; } static class ViewChildHolder { TextView id; TextView txtValor; CheckBox check; } public int getChildrenCount(int groupPosition) { return lista.get(groupPosition).getListChild().size(); } public Object getGroup(int groupPosition) { return lista.get(groupPosition); } public int getGroupCount() { return lista.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { ViewGroupHolder holder; GrupoEntity grupo = lista.get(groupPosition); if (convertView == null) { convertView = LayoutInflater.from(ctx).inflate( R.layout.list_item_group, null);// carregando layout holder = new ViewGroupHolder(); holder.txtDescricao = (TextView) convertView .findViewById(R.id.txt_item_group); convertView.setTag(holder); } else { holder = (ViewGroupHolder) convertView.getTag(); } holder.txtDescricao.setText(grupo.getDescricao()); return convertView; } static class ViewGroupHolder { TextView txtDescricao; } public boolean hasStableIds() { return true; } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }
http://developer.android.com/reference/android/widget/ExpandableListView.html