When I roll my listview I miss checkboxes marked

Asked

Viewed 303 times

1

This is a code from my Adapter, in it I have a textview and 4 chekboxes. The problem is that I believe I have to save the status of my checkboxes, not to lose the data from it, because when I roll my list view my checkboxes uncheck alone.

public class ListaFuncionarioAdapter extends BaseAdapter {
/*
   private Activity activity;
    private List<MeuItem> itens;

    public ListaFuncionarioAdapter(Activity activity, List<MeuItem> itens){
        this.activity = activity;
        this.itens = itens;
    }
*/
    private List<MeuItem> itens;

    FirebaseDatabase firebaseDatabase;
    DatabaseReference databaseReference;

    CheckBox chkSalManha, chkDoceManha, chkSalTarde, chkDoceTarde;
    private Context context;

    private List<QtdePaes> listQtdePaes = new ArrayList<QtdePaes>();
    private ArrayAdapter<QtdePaes> arrayAdapterQtdePaes;
    QtdePaes qtdePaesSelecionado;
    private List<Funcionario> listFuncionario;

    final QtdePaes qtdePaes = new QtdePaes();

    int salmanha = 0;
    int saltarde = 0;
    int docemanha = 0;
    int docetarde = 0;

    public ListaFuncionarioAdapter(Context context, List<Funcionario> listFuncionario) {
        this.context = context;
        this.listFuncionario = listFuncionario;
    }



    private void inicializarFirebase() {
        FirebaseApp.initializeApp(context);
        firebaseDatabase = FirebaseDatabase.getInstance();
       // firebaseDatabase.setPersistenceEnabled(true);
        databaseReference = firebaseDatabase.getReference();

        //DatabaseReference novaReference = firebaseDatabase.getReference();
       // novaReference = databaseReference.child("minh");

    }

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

    @Override
    public Object getItem(int position) {
        return listFuncionario.get(position);
    }

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




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

        View v= View.inflate(context, R.layout.item_funcionario, null);

        chkSalManha = (CheckBox)v.findViewById(R.id.chkSalManha);
        chkDoceManha = (CheckBox)v.findViewById(R.id.chkDoceManha);
        chkSalTarde = (CheckBox)v.findViewById(R.id.chkSalTarde);
        chkDoceTarde = (CheckBox)v.findViewById(R.id.chkDoceTarde);
        TextView txtNome = (TextView)v.findViewById(R.id.txtNome);

        inicializarFirebase();
        txtNome.setText(String.valueOf(listFuncionario.get(position).getNome()));

        //MeuItem item = itens.get(position);

        //chkSalManha.setTag(item);
        //chkSalManha.setChecked(item.foiMarcado());
        v.setTag(listFuncionario.get(position).getUid());



        chkSalManha.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if(isChecked){
                    salmanha += 1;
                    String estado = (String) chkSalManha.getTag();

                   // qtdePaes.setUid(UUID.randomUUID().toString());
                    qtdePaes.setQtdeSalManha(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    //databaseReference.child("QtdePaes").child(qtdePaes.getUid()).setValue(qtdePaes);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
                if(!isChecked)
                {

                    salmanha -= 1;
                    //qtdePaes.setUid(qtdePaesSelecionado.getUid());
                    qtdePaes.setQtdeSalManha(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
            }
        });


        chkSalTarde.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if(isChecked){
                    saltarde += 1;

                    //qtdePaes.setUid(UUID.randomUUID().toString());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    //databaseReference.child("QtdePaes").child(qtdePaes.getUid()).setValue(qtdePaes);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);

                }
                if(!isChecked)
                {

                    saltarde -= 1;
                    //qtdePaes.setUid(qtdePaesSelecionado.getUid());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
            }
        });

        chkDoceManha.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if(isChecked){

                    docemanha += 1;

                    //qtdePaes.setUid(UUID.randomUUID().toString());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    //databaseReference.child("QtdePaes").child(qtdePaes.getUid()).setValue(qtdePaes);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);

                }
                if(!isChecked)
                {

                    docemanha -= 1;
                    //qtdePaes.setUid(qtdePaesSelecionado.getUid());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
            }
        });

        chkDoceTarde.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if(isChecked){
                    docetarde += 1;

                   // qtdePaes.setUid(UUID.randomUUID().toString());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    //databaseReference.child("QtdePaes").child(qtdePaes.getUid()).setValue(qtdePaes);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
                if(!isChecked)
                {

                    docetarde -= 1;
                    //qtdePaes.setUid(qtdePaesSelecionado.getUid());
                    qtdePaes.setQtdeSalTarde(salmanha);
                    qtdePaes.setQtdeDoceManha(docemanha);
                    qtdePaes.setQtdeSalTarde(saltarde);
                    qtdePaes.setQtdeDoceTarde(docetarde);
                    databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);


                }
            }
        });



        return v;

    }


}
  • Why that code pile qtdePaes.setALGMACOISA repeated in both ifs and Es? You can move these blocks to after the if-lse and leave inside them only what really is different between them.

  • I modified my project, it was very messy, @Márciooliveira. I followed your recommendations. it was less code, and working.

3 answers

0

The problem the last condition does not have a else, then it ends up "intertwining" the items.

Instead of putting:

if(isChecked){
// conteúdo
}
if(!isChecked){
// conteúdo
}

Place:

if(isChecked){
// conteúdo
}else{
// conteúdo
}

This will ensure that the CheckBoxare not unchecked if marked.

  • Thank you, friend, but definitely the biggest problem is the question of me losing data from listview

  • @Lucianopedrosa if you do this way, will no longer be unchecked.

  • I see no difference, in terms of the final result, between the two codes.

  • However the traditional way is to do with if/else.

  • @ramaral at least with me, whenever I left an if "loose" on a custom Adapter, always lost content because of view recycling. This is my guess regarding checkbox loss, because the last condition does not end with an Else. It looks like the stupidest thing in the world.

  • @ramaral will not fill anything in the code that makes lose the result beyond that. You managed to fill?

  • Yes, I understand what you’re getting at. However else is the same as testing test denial. Also note that these if are in the onCheckedChanged() and not in the getView() Adapter.

  • @I understood what I meant. The right thing then would be to create the conditions within the getView but without being inside the setOnCheckedChangeListener to solve the problem. Let’s wait for a feedback.

  • In part, in the setOnCheckedChangeListener conditions must be met if there is anything to change if the Checkbox is selected/deselected. The checkbox status in the list object should also be stored there. In getView() check which state is stored and "set" the Checkbox accordingly.

  • @ramaral, I followed your suggestion, I modified the project and now I’m using the recyclerview layout, now I don’t miss my checkbox information anymore. My code was very messy. I fixed a lot of things, now I’m using more good programming practices.

Show 5 more comments

0


Each time Listview needs to render an item/line calls the method getView() of Adapter.

In the implementation of this method the inflate of a new layout and its views are assigned their respective values.

This process is repeated as long as there are items in the list or the Listview time is filled in.

When it’s done scroll, new layouts are "inflated" to the lower positions and those of the upper positions are discarded.

The process is identical when the scroll is done in the opposite direction.

If in the meantime you have marked any of the checkboxes, this check mark will be lost when the respective layout/item/line is discarded as a result of scroll.

Thus, the solution is to keep the state of the checbox’s on the object that is used to populate the Listview and assign it to the Checkbox in the same way that values are assigned to each other views. Behold here an example.

Note: To make the process of creating new layouts more efficient consider using the standard View Holder or a Recyclerview.

  • this behavior you described "When scrolling is done, new layouts are "inflated" to the lower positions and those from the upper positions are discarded." Don’t you mean Recyclerview? As I recall, Listview carries them all. Sorry if I’m wrong.

  • @Tiagoalmeida I think you’re wrong. Both Listview and Recyclerview only load (it’s called the Adapter method getView()/onBindViewHolder() for) the items visible at each moment.

0

Assuming that the amount of items in your Listview will not vary in size, then to simplify, you can create a static 2-dimensional Boolean array in your Adapter.

Ex:

private static boolean [][] checkBoxStates; // a primeira dimensão é a quantidade de itens da sua lista, a segunda dimensão, a quantidade de checkboxes por item

Initialize array in Adapter constructor:

public ListaFuncionarioAdapter(Context context, List<Funcionario> listFuncionario) {
    this.context = context;
    this.listFuncionario = listFuncionario;
    checkBoxStates = new  boolean [listFuncionario.size()][];
    // supondo que o status inicial de todas as check boxes é desmarcado
    for(int i = 0; i < listFuncionario.size(); i++)
        checkBoxStates[i] = new boolean[]{false, false, false, false};
    }

}

Storing/recovering the status of checks:

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

  ...
  // após associar os checkboxes com o findviewById
  chkSalManha.setChecked(checkBoxStates[position][0]);
  chkDoceManha.setChecked(checkBoxStates[position][1]);
  chkSalTarde.setChecked(checkBoxStates[position][2]);
  chkDoceTarde.setChecked(checkBoxStates[position][3]);

  ...
  // Guardando o estado nos listeners:
  chkSalManha.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                checkBoxStates[position][0] = isChecked;
                ...

            }


  chkDoceManha.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                checkBoxStates[position][1] = isChecked;
                ...

            }

  chkSalTarde.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                checkBoxStates[position][2] = isChecked;
                ...

            }

  chkDoceTarde.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                checkBoxStates[position][3] = isChecked;
                ...

            }
  ...

 }

And as already suggested, you can change your listeners' if-LSE code that way:

 chkSalManha.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            checkBoxStates[position][1] = isChecked;

            if(isChecked)
                salmanha++;
            else
                salmanha--;
            }

            qtdePaes.setQtdeSalManha(salmanha);
            qtdePaes.setQtdeDoceManha(docemanha);
            qtdePaes.setQtdeSalTarde(saltarde);
            qtdePaes.setQtdeDoceTarde(docetarde);
            databaseReference.child("QtdePaes").child("6fd2aede-e00f-48d8-b6cb-f1498e23e8e8").setValue(qtdePaes);
        }
    });

Browser other questions tagged

You are not signed in. Login or sign up in order to post.