|
||
|
|
|
|||||||
| Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android |
![]() |
|
|
Herramientas |
|
#1
|
||||
|
||||
|
Problema listview con checkboxes
Saludos compañeros , tengo un problema con un listview con custom adapter y checkboxes , el problema básicamente es que al hacer visibles o checkar los checks que están fuera de de la lista al hacer scroll y re-dibujarlos se comportan como quieren , los seleccionados se de-seleccionan y algunos visibles se hace invisibles...
utlizo unos métodos para hacer los check visibles y para checkarlos todos o no , serian estos: Código:
private void setListChecksVisibles(boolean isVisible) {
int nVisible = isVisible ? View.VISIBLE : View.GONE;
header.setVisibility(nVisible);
footer.setVisibility(nVisible);
for(int i=0; i<lst.getChildCount(); i++){
View ll = lst.getChildAt(i);
CheckBox cb = (CheckBox) ll.findViewById(R.id.checkItems);
cb.setVisibility(nVisible);
}
adp.notifyDataSetChanged();
}
private void checkAll(boolean bCheck) {
for(int i=0; i<lst.getChildCount(); i++){
View ll =lst.getChildAt(i);
CheckBox cb = (CheckBox)ll.findViewById(R.id.checkItems);
cb.setChecked(bCheck);
}
adp.notifyDataSetChanged();
}
mi adapter es este: Código:
public class HistoryAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private Cursor cur;
private ArrayList<Boolean> itemSelection;
public HistoryAdapter(){
db = new DBHelper(getApplicationContext(), DBHelper.TABLE_NAME, null, 1);
this.cur = db.SelectAll();
mInflater = (LayoutInflater)getApplicationContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
itemSelection= new ArrayList<Boolean>();
for(int i=0;i<this.getCount();i++) {
itemSelection.add(i, false);
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return cur.getCount();
}
@Override
public Cursor getItem(int position) {
cur.moveToPosition(position);
return cur;
}
@Override
public long getItemId(int position) {
Cursor c = getItem(position);
long id =(Long)(long)c.getInt(c.getColumnIndex(DBHelper.KEY_ID));
return id;
}
private class ViewHolder {
TextView lng;
TextView lat;
TextView date;
CheckBox ch;
}
@Override
public View getView(final int position, View convertView, ViewGroup arg2) {
ViewHolder holder= null;
holder= new ViewHolder();
if (convertView == null) {
convertView = mInflater.inflate(R.layout.itemhistory, null);
holder.lng = (TextView) convertView.findViewById(R.id.textLongitude);
holder.lat=(TextView) convertView.findViewById(R.id.textLatitude);
holder.date=(TextView) convertView.findViewById(R.id.textDate);
holder.ch=(CheckBox)convertView.findViewById(R.id.checkItems);
holder.ch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
itemSelection.set(position,isChecked);
}
});
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
try
{
Cursor rowItem = getItem(position);
holder.lng.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LONGITUDE))+" ");
holder.lat.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LATITUDE))+" ");
holder.date.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_DATE))+" ");
holder.ch.setChecked(itemSelection.get(position));
}catch(Exception ex){
ex.printStackTrace();
}
return convertView;
}
}
Última edición por rafaxplayer Día 14/09/13 a las 18:49:18. |
|
|
|
#2
|
||||
|
||||
|
Para el setListChecksVisibles debería funcionar, porque no veo en el getView ningún código que modifique la visibilidad de los elementos. Y el reciclado de vista no debería influir, porque estás haciéndolo sobre todos los elementos (aunque realmente sea sobre los elementos visibles todo el tiempo).
Para el checkAll es lógico que no funcione, porque al scrollear y ejecutarse el getView el estado del check depende de itemSelection.get(position), y por tanto se marca según lo que dice ese ArrayList. La solución para el checkAll es poner todos los elementos de itemSelection al estado que pasas por parámetro. Para el otro caso, prueba añadiendo en el getView que la visibilidad dependa de una variable booleana en el HistoryAdapter. Y en el método setListChecksVisibles establece esa variable al valor que pasas por parámetro. |
|
#3
|
||||
|
||||
|
Gracias kriogen , he logrado solucionar lo de mostrar y checkar o no todos los checks , lo conseguido usando unos métodos dentro del adapter(setCheckedall(boolean check) , setVisibleChecks(int vis) ) .
Mi problema es ahora la persistencia cuando hago selección aleatoria de los checks , cuando los oculta el scroll y vuelven cambian de estado como le da la gana ;( he puesto un checkedchangedlistener para editar el array donde guardo el estado para aplicarlo al redibujar pero no funciona, ademas como veras en el listener hay un log.d que me da estado y posicion y por lo que veo la posición no cuadra cuando los items salen de ocultos en el scroll, no se que hago mal en este sentido;( El adapter: Código:
public class HistoryAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private Cursor cur;
private ArrayList<Boolean> itemSelection;
private ArrayList<Integer> itemVisible;
public HistoryAdapter(){
db = new DBHelper(getApplicationContext(), DBHelper.TABLE_NAME, null, 1);
this.cur = db.SelectAll();
mInflater = (LayoutInflater)getApplicationContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
itemSelection=new ArrayList<Boolean>();
for(int i=0 ;i<this.getCount();i++ ) {
itemSelection.add(i, false);
}
itemVisible=new ArrayList<Integer>();
for(int i=0 ;i<this.getCount();i++ ) {
itemVisible.add(i, View.GONE);
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return cur.getCount();
}
@Override
public Cursor getItem(int position) {
cur.moveToPosition(position);
return cur;
}
@Override
public long getItemId(int position) {
Cursor c = getItem(position);
long id =(Long)(long)c.getInt(c.getColumnIndex(DBHelper.KEY_ID));
return id;
}
public void setCheckedall(boolean check) {
for(int i=0 ;i<itemSelection.size();i++ ) {
itemSelection.set(i,check);
}
this.notifyDataSetChanged();
}
public void setVisibleChecks(int vis) {
for(int i=0 ;i<itemVisible.size();i++ ) {
itemVisible.set(i, vis);
}
this.notifyDataSetChanged();
}
private class ViewHolder {
TextView lng;
TextView lat;
TextView date;
CheckBox ch;
}
@Override
public View getView(final int position, View convertView, ViewGroup arg2) {
ViewHolder holder= null;
if (convertView == null) {
holder= new ViewHolder();
convertView = mInflater.inflate(R.layout.itemhistory, null);
holder.lng = (TextView) convertView.findViewById(R.id.textLongitude);
holder.lat=(TextView) convertView.findViewById(R.id.textLatitude);
holder.date=(TextView) convertView.findViewById(R.id.textDate);
holder.ch=(CheckBox)convertView.findViewById(R.id.checkItems);
holder.ch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
itemSelection.set(position,isChecked);
Log.d("Position",String.valueOf(position)+" "+String.valueOf(isChecked));
}
});
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
try
{
Cursor rowItem = getItem(position);
holder.lng.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LONGITUDE))+" ");
holder.lat.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LATITUDE))+" ");
holder.date.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_DATE))+" ");
holder.ch.setChecked(itemSelection.get(position));
holder.ch.setVisibility(itemVisible.get(position));
}catch(Exception ex){
ex.printStackTrace();
}
return convertView;
}
}
|
|
#4
|
||||
|
||||
|
Bueno arreglado , al final el evento checkedchangued no estaba funcionando bien guardando los cambios , lo ha cambiado por clicklistener y declarado despues:
asi ha quedado el adapter: Código:
public class HistoryAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private Cursor cur;
private ArrayList<Boolean> itemSelection;
private ArrayList<Integer> itemVisible;
public HistoryAdapter(){
db = new DBHelper(getApplicationContext(), DBHelper.TABLE_NAME, null, 1);
this.cur = db.SelectAll();
mInflater = (LayoutInflater)getApplicationContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
itemSelection=new ArrayList<Boolean>();
for(int i=0 ;i<this.getCount();i++ ) {
itemSelection.add(i, false);
}
itemVisible=new ArrayList<Integer>();
for(int i=0 ;i<this.getCount();i++ ) {
itemVisible.add(i, View.GONE);
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return cur.getCount();
}
@Override
public Cursor getItem(int position) {
cur.moveToPosition(position);
return cur;
}
@Override
public long getItemId(int position) {
Cursor c = getItem(position);
long id =(Long)(long)c.getInt(c.getColumnIndex(DBHelper.KEY_ID));
return id;
}
public void setCheckedall(boolean check) {
for(int i=0 ;i<itemSelection.size();i++ ) {
itemSelection.set(i,check);
}
this.notifyDataSetChanged();
}
public void setVisibleChecks(int vis) {
for(int i=0 ;i<itemVisible.size();i++ ) {
itemVisible.set(i, vis);
}
this.notifyDataSetChanged();
}
private class ViewHolder {
TextView lng;
TextView lat;
TextView date;
CheckBox ch;
}
@Override
public View getView(final int position, View convertView, ViewGroup arg2) {
ViewHolder holder= null;
if (convertView == null) {
holder= new ViewHolder();
convertView = mInflater.inflate(R.layout.itemhistory, null);
holder.lng = (TextView) convertView.findViewById(R.id.textLongitude);
holder.lat=(TextView) convertView.findViewById(R.id.textLatitude);
holder.date=(TextView) convertView.findViewById(R.id.textDate);
holder.ch=(CheckBox)convertView.findViewById(R.id.checkItems);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
try
{
Cursor rowItem = getItem(position);
holder.lng.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LONGITUDE))+" ");
holder.lat.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_LATITUDE))+" ");
holder.date.setText(rowItem.getString(rowItem.getColumnIndex(DBHelper.KEY_DATE))+" ");
holder.ch.setChecked(itemSelection.get(position));
holder.ch.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
itemSelection.set(position, ((CheckBox) v).isChecked());
}
});
holder.ch.setVisibility(itemVisible.get(position));
//holder.ch.setTag(position);
}catch(Exception ex){
ex.printStackTrace();
}
return convertView;
}
|
![]() |
Estás aquí
|
||||||
|
||||||