List Adapter Duplicating Positions in ListView

0

I have a class named "AdapterListParts" which extends the BaseAdapter class and in it I inflate a layout that contains a CheckBox and an ImageView.

AdapterList Players class

public class AdapterListJogadores extends BaseAdapter {
    private LayoutInflater inflater;
    private List<Jogador> jogador;

    public AdapterListJogadores(Context context, List<Jogador> jogador){
        this.jogador = jogador;
        inflater = LayoutInflater.from(context);
    }

    public List<Jogador> getJogador(){
        return jogador;
    }

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

    @Override
    public Jogador getItem(int position) {
        return jogador.get(position);
    }

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

    private class ItemSuporte{
        CheckBox txtNomeJogador;
        ImageView imgPosicao;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        Log.e("Position: ", String.valueOf(position)); //Mostra a posição recebida como parametro do getView no log 
        // Resultado do log, logo abaixo

        ItemSuporte item;

        if(convertView == null){
            convertView = inflater.inflate(R.layout.list_jogador, null);

            item = new ItemSuporte();

            item.txtNomeJogador = (CheckBox) convertView.findViewById(R.id.txtNomeJogador);
            item.imgPosicao = (ImageView) convertView.findViewById(R.id.imgPosicao);

            convertView.setTag(item);

            item.txtNomeJogador.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox cb = (CheckBox) v;
                    Jogador jogador = getItem(position);
                    jogador.setMarcado(cb.isChecked());
                }
            });

        } else {
            item = (ItemSuporte) convertView.getTag();
        }

        Jogador jogador = getItem(position);

        item.txtNomeJogador.setText(jogador.getNomeJogador());
        item.txtNomeJogador.setChecked(jogador.isMarcado());

        int posicao = jogador.getPosicao();
        switch (posicao){
            case 0:
                item.imgPosicao.setImageResource(R.mipmap.jogador);
                break;
            case 1:
                item.imgPosicao.setImageResource(R.mipmap.goleiro);
                break;
            default:
                item.imgPosicao.setImageResource(R.mipmap.bola);
                break;
        }

        return convertView;
    }
}

Player Class

public class Jogador {
    int _idJogador;
    String _nomeJogador;
    int _posicao;
    private boolean marcado;

    public Jogador(int idJogador, String nomeJogador, int posicao) {
        this._idJogador = idJogador;
        this._nomeJogador = nomeJogador;
        this._posicao = posicao;
    }

    // getting Id
    public int getIdJogador() {
        return this._idJogador;
    }

    // setting id
    public void setIdJogador(int idJogador) {
        this._idJogador = idJogador;
    }

    // getting nome
    public String getNomeJogador() {
        return this._nomeJogador;
    }

    // setting nome
    public void setNomeJogador(String nomeJogador) {
        this._nomeJogador = nomeJogador;
    }

    // getting posicao
    public int getPosicao() {
        return this._posicao;
    }

    // setting posicao
    public void setPosicao(int posicao) {
        this._posicao = posicao;
    }

    public boolean isMarcado() {
        return marcado;
    }

    public void setMarcado(boolean marcado) {
        this.marcado = marcado;
    }
}

Already in my activity I have a ListView that receives the values of this adapter and puts it on the screen for the user.

 public void onResume(){
        super.onResume();

        final DBAdapterJogador dbJogador = new DBAdapterJogador(this);
        dbJogador.open();

        final List<Jogador> jogador = dbJogador.listar();
        final AdapterListJogadores adapter = new AdapterListJogadores(this, jogador);
        lstJogadores.setAdapter(adapter);
        dbJogador.close();
}

This is the result I have in the log when I run the project with 15 items in my bank.

02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 0
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 1
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 2
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 3
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 4
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 5
02-11 16:20:11.386    3677-3677/favarin.com.br.pernetas E/Position:﹕ 6
02-11 16:20:11.387    3677-3677/favarin.com.br.pernetas E/Position:﹕ 7
02-11 16:20:11.387    3677-3677/favarin.com.br.pernetas E/Position:﹕ 8
02-11 16:20:11.387    3677-3677/favarin.com.br.pernetas E/Position:﹕ 9
02-11 16:20:11.387    3677-3677/favarin.com.br.pernetas E/Position:﹕ 10
02-11 16:20:11.388    3677-3677/favarin.com.br.pernetas E/Position:﹕ 11
02-11 16:20:11.388    3677-3677/favarin.com.br.pernetas E/Position:﹕ 12
02-11 16:20:11.388    3677-3677/favarin.com.br.pernetas E/Position:﹕ 0
02-11 16:20:11.389    3677-3677/favarin.com.br.pernetas E/Position:﹕ 1
02-11 16:20:11.390    3677-3677/favarin.com.br.pernetas E/Position:﹕ 2
02-11 16:20:11.394    3677-3677/favarin.com.br.pernetas E/Position:﹕ 3
02-11 16:20:11.398    3677-3677/favarin.com.br.pernetas E/Position:﹕ 4
02-11 16:20:11.400    3677-3677/favarin.com.br.pernetas E/Position:﹕ 5
02-11 16:20:11.402    3677-3677/favarin.com.br.pernetas E/Position:﹕ 6
02-11 16:20:11.403    3677-3677/favarin.com.br.pernetas E/Position:﹕ 7
02-11 16:20:11.406    3677-3677/favarin.com.br.pernetas E/Position:﹕ 8
02-11 16:20:11.408    3677-3677/favarin.com.br.pernetas E/Position:﹕ 9
02-11 16:20:11.411    3677-3677/favarin.com.br.pernetas E/Position:﹕ 10
02-11 16:20:11.414    3677-3677/favarin.com.br.pernetas E/Position:﹕ 11
02-11 16:20:11.423    3677-3677/favarin.com.br.pernetas E/Position:﹕ 12
02-11 16:20:11.451    3677-3677/favarin.com.br.pernetas E/Position:﹕ 0
02-11 16:20:11.452    3677-3677/favarin.com.br.pernetas E/Position:﹕ 1
02-11 16:20:11.453    3677-3677/favarin.com.br.pernetas E/Position:﹕ 2
02-11 16:20:11.454    3677-3677/favarin.com.br.pernetas E/Position:﹕ 3
02-11 16:20:11.454    3677-3677/favarin.com.br.pernetas E/Position:﹕ 4
02-11 16:20:11.454    3677-3677/favarin.com.br.pernetas E/Position:﹕ 5
02-11 16:20:11.455    3677-3677/favarin.com.br.pernetas E/Position:﹕ 6
02-11 16:20:11.455    3677-3677/favarin.com.br.pernetas E/Position:﹕ 7
02-11 16:20:11.455    3677-3677/favarin.com.br.pernetas E/Position:﹕ 8
02-11 16:20:11.456    3677-3677/favarin.com.br.pernetas E/Position:﹕ 9
02-11 16:20:11.456    3677-3677/favarin.com.br.pernetas E/Position:﹕ 10
02-11 16:20:11.456    3677-3677/favarin.com.br.pernetas E/Position:﹕ 11
02-11 16:20:11.456    3677-3677/favarin.com.br.pernetas E/Position:﹕ 12
02-11 16:20:11.696    3677-3677/favarin.com.br.pernetas E/Position:﹕ 0
02-11 16:20:11.696    3677-3677/favarin.com.br.pernetas E/Position:﹕ 1
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 2
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 3
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 4
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 5
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 6
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 7
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 8
02-11 16:20:11.697    3677-3677/favarin.com.br.pernetas E/Position:﹕ 9
02-11 16:20:11.698    3677-3677/favarin.com.br.pernetas E/Position:﹕ 10
02-11 16:20:11.698    3677-3677/favarin.com.br.pernetas E/Position:﹕ 11
02-11 16:20:11.698    3677-3677/favarin.com.br.pernetas E/Position:﹕ 12

With this I'm having a problem that when I select a CheckBox with position 15 (for example) it automatically selects the item from position 3 and takes all values from that position.

    
asked by anonymous 11.02.2016 / 22:27

1 answer

2

You are assigning OnClickListener() only when convertView is null. When the view is reused for another item the position , which was passed to the listener, retains its initial value, the value it had when the listener was created (note that it is declared final int position ).

Pass the assignment of OnClickListener() out of block if(convertView == null)

if(convertView == null){
    ....
    ....
} else {
    item = (ItemSuporte) convertView.getTag();
}

item.txtNomeJogador.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        CheckBox cb = (CheckBox) v;
        Jogador jogador = getItem(position);
        jogador.setMarcado(cb.isChecked());
    }
});

So, when the execution passes through else , the previously applied listener is replaced by a new one with the correct value of position .

    
11.02.2016 / 23:32