Strange behavior of Basedapter on android

Asked

Viewed 66 times

1

I have a ListView with CheckBox, that one ListView is organized with two List in Adapter, one that would be all items, and the other only with the selected.

I created a CheckBox to add the mark/deselect all functionality, so when I click on mark, I add in the list of selected all items, otherwise create a new instance of the list, until then everything ok.

However, if I click on one CheckBox within the ListView also have it added/removed from the list of selected, and call notifySetDataChanged() to update the screen, the strange thing is that it is also being removed from the main list, which causes the screen to be redesigned without the item, and not just uncheck it.

At no point in the code do I make any changes to the main list, only to the list of selected ones, and even then, when I add/remove from the list of selected ones is being removed from the main list, does anyone know what may be occurring?

The code of the Adapter is this:

public class ListViewNaoEnviadosAdapter extends BaseAdapter {

    private List<NaoEnviado> naoEnviados;
    private List<NaoEnviado> selecionados;
    private CheckBox chkEnviarSmsNaoEnviados, chkNaoEnviadosMarcarTodos;
    private TextView tvTotalNaoEnviados;
    private LayoutInflater layoutInflater;
    private final Context ctx;

    public ListViewNaoEnviadosAdapter(Context ctx, List<NaoEnviado> naoEnviados) {
        this.layoutInflater = LayoutInflater.from(ctx);
        this.ctx = ctx;
        this.naoEnviados = naoEnviados;
        this.selecionados = naoEnviados;

        chkNaoEnviadosMarcarTodos = (CheckBox) ((MainActivity) ctx)
                .findViewById(R.id.chkNaoEnviadosMarcarTodos);
        chkNaoEnviadosMarcarTodos.setChecked(true);

        tvTotalNaoEnviados = (TextView) ((MainActivity) ctx)
                .findViewById(R.id.tvTotalNaoEnviados);
        tvTotalNaoEnviados.setText(String.valueOf(selecionados.size()));
    }

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

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

    @Override
    public long getItemId(int position) {
        return naoEnviados.get(position).getId();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        NaoEnviadosHelper naoEnviadosHelper = new NaoEnviadosHelper();
        final NaoEnviado naoEnviado = naoEnviados.get(position);
        final Telefone tel = new Telefone(ctx);

        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.listview_sms_nao_enviados, null);
            naoEnviadosHelper.nome = (TextView) convertView.findViewById(R.id.tvSmsNaoEnviadosNome);
            naoEnviadosHelper.telefone = (TextView) convertView.findViewById(R.id.tvSmsNaoEnviadosTelefone);
            naoEnviadosHelper.descFalha = (TextView) convertView.findViewById(R.id.tvSmsNaoEnviadosDescFalha);
            naoEnviadosHelper.enviarSms = (CheckBox) convertView.findViewById(R.id.chkEnviarSmsNaoEnviados);
            convertView.setTag(naoEnviadosHelper);
        } else {
            naoEnviadosHelper = (NaoEnviadosHelper) convertView.getTag();
        }
        naoEnviadosHelper.nome.setText(naoEnviado.getNome().trim());
        naoEnviadosHelper.telefone.setText(tel.formataTelefone(naoEnviado.getTelefone()));
        naoEnviadosHelper.descFalha.setText(naoEnviado.getTipoFalha());
        naoEnviadosHelper.enviarSms.setChecked(selecionados.contains(naoEnviado));

        //Checkbox marcar/desmarcar todos na tela...
        chkNaoEnviadosMarcarTodos = (CheckBox) ((MainActivity) ctx)
                .findViewById(R.id.chkNaoEnviadosMarcarTodos);
        chkNaoEnviadosMarcarTodos.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selecionados = new ArrayList<NaoEnviado>();
                if (chkNaoEnviadosMarcarTodos.isChecked()) {
                    selecionados = naoEnviados;
                }
                notifyDataSetChanged();
            }
        });

        //Checkbox marcar/desmarcar para envio
        chkEnviarSmsNaoEnviados = (CheckBox) convertView.findViewById(R.id.chkEnviarSmsNaoEnviados);
        chkEnviarSmsNaoEnviados.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!chkEnviarSmsNaoEnviados.isChecked()) {
                    selecionados.add(naoEnviado);
                } else {
                    //Aqui acontece o problema, quando mando remover desta lista, também
                    // é removido da lista principal (naoEnviados)
                    selecionados.remove(naoEnviado);

                    //Se um elemento foi removido eu desmarco o checkbox marcartodos
                    chkNaoEnviadosMarcarTodos.setChecked(false);
                }
                notifyDataSetChanged();
            }
        });
        tvTotalNaoEnviados.setText(String.valueOf(selecionados.size()));

        return convertView;
    }

    private class NaoEnviadosHelper {
        TextView telefone, nome, descFalha;
        CheckBox enviarSms;
    }
}

1 answer

0


For what it gives me to realize you have not two list but only one.
Having two variables with different names on their own does not guarantee that their value is different.

In this part of the code

public ListViewNaoEnviadosAdapter(Context ctx, List<NaoEnviado> naoEnviados) {
    this.layoutInflater = LayoutInflater.from(ctx);
    this.ctx = ctx;
    this.naoEnviados = naoEnviados;
    this.selecionados = naoEnviados;

    .....
    .....

and in this

chkNaoEnviadosMarcarTodos.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        selecionados = new ArrayList<NaoEnviado>();
        if (chkNaoEnviadosMarcarTodos.isChecked()) {
            selecionados = naoEnviados;
        }
        notifyDataSetChanged();
    }
});

in making selecionados = naoEnviados; you are not copying the content of naoEnviados for selecionados is just making that variable selecionados points to the same content that points naoEnviados.
Any change made to one is reflected in the other.

  • Thanks @ramaral for the help, but I tried to fill the list manually, and still, the problem continues. has any other detail that might be causing the problem?

  • How do I fill this out?

  • I did it with a foreach: for(Naoenviado n : naoEnviados) ..., and within it, I added the list of selected, selected.add(n);

  • 1

    I checked here, and you were right, in the class constructor, I made this reference of the two lists, this was causing the problem, I modified in the constructor, and now it’s ok, thanks @ramaral once again.

Browser other questions tagged

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