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
Haha Isso salvou meu projeto
ResponderExcluirMeu Muito Obrigaddo a você moça!!
Olá eu to com um problema ...tenho um projeto onde o usuário seleciona o quantidade de produto 1,2,3 4...etc e o tipo se Cx, Pct, Un...a quantidade e o tipo do produto estão em dois spinners, um para quantidade e outro para o tipo. o nome do produto esta em um textview, e assim é cada linha do meu expadable listView. Porém quando dou scroll na tela ou quando abro um pai da lista a seleção que o usuário fez e desfeita e os spinners voltam ao valor original. eu queria manter o valor selecionado pelo usuário quando der scroll na tela ou quando eu expandir outro item. a ideia é pegar esses valores selecionados pedo usuário e mandar para um arquivo e exporta-lo por e-mail.. Estou tentando ha algumas semanas e nada já pesquisei muito e não achei nada sobre o problema..você poderia me ajudar?
ResponderExcluirOlá eu to com um problema ...tenho um projeto onde o usuário seleciona o quantidade de produto 1,2,3 4...etc e o tipo se Cx, Pct, Un...a quantidade e o tipo do produto estão em dois spinners, um para quantidade e outro para o tipo. o nome do produto esta em um textview, e assim é cada linha do meu expadable listView. Porém quando dou scroll na tela ou quando abro um pai da lista a seleção que o usuário fez e desfeita e os spinners voltam ao valor original. eu queria manter o valor selecionado pelo usuário quando der scroll na tela ou quando eu expandir outro item. a ideia é pegar esses valores selecionados pedo usuário e mandar para um arquivo e exporta-lo por e-mail.. Estou tentando ha algumas semanas e nada já pesquisei muito e não achei nada sobre o problema..você poderia me ajudar?
ResponderExcluirFaz muito tempo que não progamo em android, mas, o problema descrito nesse post se davam por causa da mudança de estado do checkobx 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(...)
ResponderExcluireu veficido se um determinado identificador existe.
Olá!
ExcluirTive esse mesmo problema de CheckBox aparecendo marcado de desmarcado ao usar o Scroll.
Nesta minha implementação utilizei o "onCheckedChanged" para verificar quando o checkbox é alterado pelo usuário.
No getGroupView seu sempre setava o listener do evento onCheckedChanged.
Resolvi o problema setando onCheckedChanged como "null" no inicio do getGroupView e setando seu evento só no final, antes de fazer o return do convertView.
Dessa forma resolveu aquele problema sem precisar de arrays externas.
Teria como postar essa parte do seu código por gentileza? sou muito iniciante em Android e soluções simples são sempre bem-vindas. Abraço ;D
Excluir