1

I know that this question has been asked over and over again but still I haven't found/understand anything that I found. The checkbox is unchecked whenever the list is scrolled down or some of the checkbox is checked whenever the list is scrolled up.

Here is my code:

@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
    //View v = View.inflate(mContext, R.layout.sales_invoice_custom,null);
    final ViewHolder holder;

    if (view == null) {
        view = View.inflate(mContext, R.layout.sales_invoice_custom, null);
        holder = new ViewHolder();

        holder.SelectInvoiceCB = (CheckBox) view.findViewById(R.id.selectInvoiceCB);
        holder.SalesInvoiceNo = (TextView) view.findViewById(R.id.SINo);
        holder.InvoiceDate = (TextView) view.findViewById(R.id.SIDate);
        holder.InvoiceAmount = (TextView) view.findViewById(R.id.SIAmount);
        holder.AmountDue = (TextView) view.findViewById(R.id.SIAmountDue);
        holder.DueDate = (TextView) view.findViewById(R.id.SIdueDate);
        holder.PayFull = (CheckBox) view.findViewById(R.id.SIFull);
        holder.PayPartial = (CheckBox) view.findViewById(R.id.SIPartial);
        holder.TotalAmount = (EditText) view.findViewById(R.id.SITotalAmount);
        holder.CreditMemoID = (TextView) view.findViewById(R.id.creditMemoID);
        holder.CreditMemoDate = (TextView) view.findViewById(R.id.creditMemoDate);
        holder.CreditMemoReason = (TextView) view.findViewById(R.id.creditMemoReason);
        holder.LL2 = (LinearLayout) view.findViewById(R.id.ll2);
        holder.LL3 = (LinearLayout) view.findViewById(R.id.ll3);

        view.setTag(holder);

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

    InvoicePopulate(holder,position);

    return view;
}


public void InvoicePopulate(final ViewHolder holder, final int position) {
    dbHelper = new DBHelper(mContext);

    Calendar c = Calendar.getInstance();
    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
    final String formattedDate = df1.format(c.getTime());


            //holder.SelectInvoiceCB.setChecked(false);
            holder.SalesInvoiceNo.setText(invoiceLists.get(position).getSales_Invoice_ID());
            holder.InvoiceDate.setText(invoiceLists.get(position).getInvoice_Date());
            holder.DueDate.setText(invoiceLists.get(position).getDue_Date());

            float invAmount = 0;
            invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
            holder.InvoiceAmount.setText(String.format("%,.2f",invAmount));
            holder.AmountDue.setText(String.format("%,.2f",invAmount));


            try {
                if (invoiceLists.get(position).getAmount_Paid().toString().equals("") ||
                        invoiceLists.get(position).getAmount_Paid().toString().equals("0")) {
                    invAmount = 0;
                    invAmountDue = 0;
                    invAmountPaid = 0;

                    invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
                    invAmountDue = invAmount - invAmountPaid;
                    Log.e("Without AmountPaid ", "Amount Due : " + String.valueOf(invAmountDue));
                } else {
                    invAmount = 0;
                    invAmountDue = 0;
                    invAmountPaid = Math.round(Float.parseFloat(invoiceLists.get(position).getAmount_Paid())*100.00)/(float)100.00;
                    invAmount = Math.round(Float.parseFloat(invoiceLists.get(position).getInvoice_Amount())*100.00)/(float)100.00;
                    invAmountDue = invAmount - invAmountPaid;
                    Log.e("With AmountPaid ", "Amount Due : " + String.valueOf(invAmountDue));
                }

                final float finalInvAmount = invAmountDue;
                holder.PayFull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if (holder.PayFull.isChecked()) {
                            holder.PayPartial.setChecked(false);
                            if (holder.SelectInvoiceCB.isChecked()) {
                                invoiceStatusValue = "PAID_FULL";
                                holder.TotalAmount.setText(String.valueOf(Math.round(finalInvAmount*100.00)/100.00));
                                //holder.TotalAmount.setText(holder.InvoiceAmount.getText().toString());
                            }
                        }
                    }
                });

                holder.PayPartial.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if (holder.PayPartial.isChecked()) {
                            holder.PayFull.setChecked(false);
                            if (holder.SelectInvoiceCB.isChecked()) {
                                invoiceStatusValue = "PAID_PARTIAL";
                                holder.TotalAmount.setText("0.00");
                            }
                        }
                    }
                });

                holder.AmountDue.setText(String.format("%,.2f",invAmountDue));
            } catch (Exception e) {
                e.getMessage();
            }

            if (TotalPaymentAmount >= Float.parseFloat(String.valueOf(invAmountDue))) {
                holder.SelectInvoiceCB.setChecked(true);
                holder.PayFull.setChecked(true);
                holder.PayFull.setClickable(true);
                holder.PayPartial.setClickable(true);

                holder.TotalAmount.setText(String.valueOf(Math.round(invAmountDue*100.00)/100.00));
            }

        }


    } catch (Exception e){
        e.getMessage();
        System.out.println("Error - " + e);
    } finally {
        dbHelper.close();
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Eugene Santos
  • 61
  • 1
  • 11
  • try from this link, may be this is useful to you. https://stackoverflow.com/questions/10895763/checkbox-unchecked-when-i-scroll-listview-on-android https://stackoverflow.com/questions/9309250/checkbox-gets-unchecked-on-scroll-in-a-custom-listview – Jinal Awaiya Nov 08 '17 at 04:37

3 Answers3

0

You should store the checkbox is checked or not in your viewmodel class.Ex. boolean isChecked; than in getView() set the checkbox from viewmodel ischecked.

Nirav Shah
  • 263
  • 3
  • 12
0

You have to manage checked state in model class. In your case you have to manage three booleans for PayFull, PayPartial and SelectInvoiceCB checkbox checked state. When you done setChecked at that time update the model class checked behaviour like:

    class YourModel{
              public boolean isPayFull, isPayPartial, isSelectInvoice;
        }

        //This will update UI from model check behaviour
        holder.PayFull.setChecked(invoiceLists.get(position).isPayFull);
        holder.PayPartial.setChecked(invoiceLists.get(position).isPayPartial);
        holder.SelectInvoiceCB.setChecked(invoiceLists.get(position).isSelectInvoice);    
        holder.PayFull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                            @Override
                            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                if (holder.PayFull.isChecked()) {
                                    holder.PayPartial.setChecked(false);
                                    if (holder.SelectInvoiceCB.isChecked()) {
                                        invoiceStatusValue = "PAID_FULL";

                                    }
                                }
    //This is to manage the state of checkbox in model
    invoiceLists.get(position).isPayFull = holder.PayFull.isChecked();
    invoiceLists.get(position).isPayPartial= holder.PayPartial.isChecked();
    invoiceLists.get(position).isSelectInvoice= holder.SelectInvoiceCB.isChecked();
                            }
                        });

                        holder.PayPartial.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                            @Override
                            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                if (holder.PayPartial.isChecked()) {
                                    holder.PayFull.setChecked(false);
                                    if (holder.SelectInvoiceCB.isChecked()) {
                                        invoiceStatusValue = "PAID_PARTIAL";
                                        holder.TotalAmount.setText("0.00");
                                    }
                                }
    //This is to manage the state of checkbox in model
    invoiceLists.get(position).isPayFull = holder.PayFull.isChecked();
    invoiceLists.get(position).isPayPartial= holder.PayPartial.isChecked();
    invoiceLists.get(position).isSelectInvoice= holder.SelectInvoiceCB.isChecked();
                            }
                        });

Generally, I prefer to do click events on checkbox rather than checked change listeners in list item, checked change will get call on scroll and update the UI on every scroll so better to appy click event on checkbox and manage checked state from model class as I mentioned you.

Ready Android
  • 3,529
  • 2
  • 26
  • 40
  • Hi Sir, This is good! Thank you. But when I uncheck the checkbox and scroll the listview it is turning back to being checked. – Eugene Santos Nov 08 '17 at 07:01
0

In Answer to your Question , the reason it's checking and unchecking lies in this piece of your code in all the CheckChangedListeners

if (holder.PayFull.isChecked()) {
      holder.PayPartial.setChecked(false);

You are unchecking the check box as soon as its checked.

On a separate note you need to handle the checked states during view recycling. Other wise the check boxes will not maintain the proper states. when scrolling.

One choice is to save the states in the ArrayList along with your data. Keep 3 boolean variables state1,state2,state3 for the check boxes.

In the InvoicePopulate(...) method -

holder.PayFull.setChecked(invoiceLists.get(position).getState1())  

In the check changed listener add following line

invoicelists.get(position).setState1(isChecked)

Deepak
  • 1,238
  • 3
  • 22
  • 47