Spinner In Custom ListView Randomly Changed When Scrolling

java android listview

224 просмотра

1 ответ

I Just need to fix the value inside Spinner when i select some value and SetEnabled True/False when i checked the CheckBox.

For example when i check the chekcbox, the spinner will be enabled and do the opposite when i uncheck the checkbox.

However it will changing randomly when i just scrolling.

This my code :

CustomListView.java

class CustomListView extends BaseAdapter {
    private ArrayList<ListItem2> listData;
    private LayoutInflater layoutInflater;
    private Context context;

    public CustomListView adapter = this;
    String jmlCmbSiap;
    ArrayList<String> a = new ArrayList<>();
    public CustomListView(Context context, ArrayList<ListItem2> listData) {
        this.listData = listData;
        layoutInflater = LayoutInflater.from(context);
        this.context = context;
    }

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

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

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

    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        newsItem = listData.get(position);

        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.listview_detail_order, null);
            holder = new ViewHolder();
            newsItem.setAdapter(Integer.parseInt(newsItem.getJumlah()));
            holder.txtBarang = (TextView) convertView.findViewById(R.id.txtBarang);
            holder.txtJumlah = (TextView) convertView.findViewById(R.id.txtJumlah);
            holder.txtBox = (TextView) convertView.findViewById(R.id.txtBoxes);
            holder.cmbSiap = (Spinner) convertView.findViewById(R.id.cmbSiap);
            holder.cmbSiap.setAdapter(newsItem.getAdapter());
            holder.thumbImage = (ImageView) convertView.findViewById(R.id.thumbImage);
            holder.chkOk = (CheckBox) convertView.findViewById(R.id.chkOk);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Picasso
                .with(context)
                .load(newsItem.getImg())
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.placeholder)
                .into(holder.thumbImage);


        holder.txtBarang.setText(newsItem.getNamaProduk().toUpperCase());
        holder.txtJumlah.setText(newsItem.getJumlah().toUpperCase());

        holder.cmbSiap.setSelection(Integer.parseInt(newsItem.getJumlah()));
        holder.cmbSiap.setEnabled(newsItem.getcmbSiap());
        holder.txtBox.setEnabled(newsItem.gettxtBox());

        holder.cmbSiap.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                jmlCmbSiap = parent.getItemAtPosition(position).toString();
                newsItem.setJumlah(jmlCmbSiap);
                holder.cmbSiap.setSelection(Integer.parseInt(newsItem.getJumlah()));
                System.out.println("JML : " + newsItem.getJumlah());

            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        holder.chkOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (newsItem.getchkOk() == false) {
                    newsItem.setcmbSiap(true);
                    newsItem.setchkOk(true);
                    newsItem.settxtBox(true);
                    holder.cmbSiap.setEnabled(true);
                    holder.chkOk.setChecked(true);
                    txtBox.setEnabled(true);
                    numberChecked = numberChecked + 1;
                    idChkOk.add(position);
                    System.out.println("Chk : " + idChkOk);
                } else {
                    numberChecked = numberChecked - 1;
                    newsItem.setcmbSiap(false);
                    newsItem.setchkOk(false);
                    holder.cmbSiap.setEnabled(false);
                    holder.chkOk.setChecked(false);
                    if (numberChecked == 0) {
                        newsItem.settxtBox(false);
                        txtBox.setEnabled(false);
                    }
                    idChkOk.remove(position);
                    System.out.println("Chk : " + idChkOk);
                }
            }
        });

        cmdPak.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a.clear();
                for (int i = 0; i < listData.size(); i++)
                {
                    newsItem = listData.get(i);
                    a.add(newsItem.getJumlah().toString());
                }
                System.out.println("Pak : " + a);
            }
        });

        return convertView;
    }

    class ViewHolder {
        TextView txtBarang,txtJumlah,txtBox;
        Spinner cmbSiap;
        ImageView thumbImage;
        CheckBox chkOk;

    }
}

ListItem2.java

class ListItem2 {

    private String shipment;
    private String truck;
    private String transporter;
    private String tanggal;
    private String order;
    private String nilai;
    private String alamat;
    private String status;
    private String jumlah;
    private String namaProduk;
    private String img;
    private String sopir;
    private String jumlahTerima;
    private String alasan;
    private String orderTemp;
    private Boolean chkOk;
    private Boolean cmbSiap;
    private Boolean txtBox;
    private ArrayAdapter<CharSequence> adapter;
    private ArrayList<String> array = new ArrayList<String>();

    public void setAdapter(Integer jml)
    {
        for (int i = 0; i<= jml; i++) {
            array.add(String.valueOf(i));
        }
        adapter = new ArrayAdapter(DetailOrder.this,android.R.layout.simple_spinner_item,array);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    }

    public ArrayAdapter<CharSequence> getAdapter()
    {
        return adapter;
    }

    public void setTanggal(String tanggal) {
        this.tanggal = tanggal;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getAlamat() {
        return alamat;
    }

    public void setAlamat(String alamat) {
        this.alamat = alamat;
    }

    public String getNilai() {
        return nilai;
    }

    public void setNilai(String nilai) {
        this.nilai = nilai;
    }

    public String getKodeProduk() {
        return nilai;
    }

    public void setKodeProduk(String nilai) {
        this.nilai = nilai;
    }

    public String getNamaProduk() {
        return namaProduk;
    }

    public void setNamaProduk(String namaProduk) {
        this.namaProduk = namaProduk;
    }

    public String getJumlah() {
        return jumlah;
    }

    public void setJumlah(String jumlah) {
        this.jumlah = jumlah;
    }

    public Boolean getchkOk() {
        return chkOk;
    }

    public void setchkOk(Boolean chkOk) {
        this.chkOk = chkOk;
    }

    public Boolean getcmbSiap() {
        return cmbSiap;
    }

    public void setcmbSiap(Boolean cmbSiap) {
        this.cmbSiap = cmbSiap;
    }

    public Boolean gettxtBox() {
        return txtBox;
    }

    public void settxtBox(Boolean txtBox) {
        this.txtBox = txtBox;
    }
}

Could you lend me a hand ?

Update :

chkAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View views;
                CheckBox chkOkx;
                Spinner cmbSiap;
                for (int i = 0; i < jArray; i++) {
                    final ListItem2 newsItem = listData.get(i);
                    views = listView.getChildAt(i);
                    if (views == null) {
                        return;
                    } else {
                        chkOkx = (CheckBox) views.findViewById(R.id.chkOk);
                        cmbSiap = (Spinner) views.findViewById(R.id.cmbSiap);
                        if (chkOkx.isChecked()) {
                            newsItem.setchkOk(true);
                            newsItem.setcmbSiap(true);
                            chkOkx.setChecked(newsItem.getchkOk());
                            cmbSiap.setEnabled(newsItem.getcmbSiap());
                        } else {
                            newsItem.setchkOk(false);
                            newsItem.setcmbSiap(false);
                            chkOkx.setChecked(newsItem.getchkOk());
                            cmbSiap.setEnabled(newsItem.getcmbSiap());
                        }
                        idChkOk.add(i);
                    }
                }

                if (chkAll.isChecked()) {
                    txtBox.setEnabled(true);
                    numberChecked = 0;
                } else {
                    txtBox.setEnabled(false);
                    numberChecked = listviewChild;
                }
                listView.invalidateViews();
            }
        });
Автор: Leonard Febrianto Источник Размещён: 08.11.2019 11:00

Ответы (1)


1 плюс

Решение

In ListView when you scroll, the views are destroyed and re-created. To overcome the issue you need to preserve both of the checkbox status and spinner item's value.

For the checkbox, save the checked status from setOnClickListener inside a boolean array,

    if (((CheckBox) v).isChecked()) {
      checkBoxState[position] = true;
    } else {
      checkBoxState[position] = false;
    }

The boolean array should like this,

private boolean[] checkBoxState;

Later on getView() apply the check/uncheck status of each checkbox items based on the array

holder.checkBox.setChecked(checkBoxState[position]);

Similarly to save the spinner data, create a Hashmap

Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();

and save the spinner data once it's selected from the setOnItemSelectedListener

 myMap.put(position, pos);

Later restore the spinner selection position from the saved data,

if (myMap.containsKey(position)) {
            viewHolder.spinner.setSelection(myMap.get(position));
        }

Full code,

class CustomListView extends BaseAdapter {

    private ArrayList<ListItem2> listData;
    private LayoutInflater layoutInflater;
    private Context context;

    public CustomListView adapter = this;
    String jmlCmbSiap;
    ArrayList<String> a = new ArrayList<>();

    private boolean[] checkBoxState;
    private Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();

    public CustomListView(Context context, ArrayList<ListItem2> listData) {
        this.listData = listData;
        layoutInflater = LayoutInflater.from(context);
        checkBoxState = new boolean[listData.size()];
        this.context = context;
    }

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

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

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

    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        newsItem = listData.get(position);

        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.listview_detail_order, null);
            holder = new ViewHolder();
            newsItem.setAdapter(Integer.parseInt(newsItem.getJumlah()));
            holder.txtBarang = (TextView) convertView.findViewById(R.id.txtBarang);
            holder.txtJumlah = (TextView) convertView.findViewById(R.id.txtJumlah);
            holder.txtBox = (TextView) convertView.findViewById(R.id.txtBoxes);
            holder.cmbSiap = (Spinner) convertView.findViewById(R.id.cmbSiap);
            holder.cmbSiap.setAdapter(newsItem.getAdapter());
            holder.thumbImage = (ImageView) convertView.findViewById(R.id.thumbImage);
            holder.chkOk = (CheckBox) convertView.findViewById(R.id.chkOk);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.checkBox.setChecked(checkBoxState[position]);

        if (checkBoxState[position])
        {
            holder.chkOk.setChecked(true);
            newsItem.setcmbSiap(true);
            newsItem.settxtBox(true);

            holder.cmbSiap.setEnabled(true);   
            holder.cmbSiap.setClickable(true); 

            txtBox.setEnabled(true);
        }
        else
        {
            holder.chkOk.setChecked(false);
            newsItem.setcmbSiap(false);
            newsItem.settxtBox(false);

            holder.cmbSiap.setEnabled(false);   
            holder.cmbSiap.setClickable(false); 

            txtBox.setEnabled(false);
        }

        Picasso
                .with(context)
                .load(newsItem.getImg())
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.placeholder)
                .into(holder.thumbImage);


        holder.txtBarang.setText(newsItem.getNamaProduk().toUpperCase());
        holder.txtJumlah.setText(newsItem.getJumlah().toUpperCase());

        holder.cmbSiap.setSelection(Integer.parseInt(newsItem.getJumlah()));
        holder.cmbSiap.setEnabled(newsItem.getcmbSiap());
        holder.txtBox.setEnabled(newsItem.gettxtBox());

         if (myMap.containsKey(position)) {
            viewHolder.spinner.setSelection(myMap.get(position));
        }

        holder.cmbSiap.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                jmlCmbSiap = parent.getItemAtPosition(position).toString();
                newsItem.setJumlah(jmlCmbSiap);

                myMap.put(position, pos);

                System.out.println("JML : " + newsItem.getJumlah());

            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        holder.chkOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //is chkOk checked?
                if (((CheckBox) v).isChecked()) {
                    checkBoxState[position] = true;
                    viewHolder.spinner.setEnabled(true);
                    viewHolder.spinner.setClickable(true);
                } else {
                    checkBoxState[position] = false;
                    viewHolder.spinner.setEnabled(false);
                    viewHolder.spinner.setClickable(false);
                }
            }
        });

        cmdPak.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a.clear();
                for (int i = 0; i < listData.size(); i++)
                {
                    newsItem = listData.get(i);
                    a.add(newsItem.getJumlah().toString());
                }
                System.out.println("Pak : " + a);
            }
        });

        return convertView;
    }

    class ViewHolder {
        TextView txtBarang,txtJumlah,txtBox;
        Spinner cmbSiap;
        ImageView thumbImage;
        CheckBox chkOk;

    }
}

Update:

In order to make a select all/deselect all checkbox feature,

create a boolean flag at the top of adapter's class,

boolean isCheckAll = false;

then create a toggle method,

 public void toggleCheckAll() {

        isCheckAll = !isCheckAll;

        for (int i = 0; i < listData.size(); i++) {
            if (isCheckAll) {
                checkBoxState[i] = true;
                notifyDataSetInvalidated();
            } else {
                checkBoxState[i] = false;
                notifyDataSetInvalidated();
            }
        }
    }

Now call the method from your aactivity's check all button's click,

btnCheckAll.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                adapter.toggleCheckAll();

            }
        });
Автор: Prokash Sarkar Размещён: 22.08.2016 04:31
Вопросы из категории :
32x32