【问题标题】:Checkbox inside List View automatically checking and un-checking when scrollListview中的复选框在滚动时自动选中和取消选中
【发布时间】:2018-04-20 15:53:54
【问题描述】:

我知道这个问题被问了一遍又一遍,但我仍然没有找到/理解我发现的任何东西。每当列表向下滚动时,复选框不会被选中,或者当列表向上滚动时,某些复选框会被选中。

这是我的代码:

@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();
    }
}

【问题讨论】:

标签: android listview checkbox unchecked


【解决方案1】:

您应该将复选框是否选中存储在您的视图模型类中。例如。 boolean isChecked;比在 getView() 中设置 viewmodel 的复选框被选中。

【讨论】:

    【解决方案2】:

    您必须在模型类中管理检查状态。在您的情况下,您必须管理 PayFull、PayPartial 和 SelectInvoiceCB 复选框选中状态的三个布尔值。 当您完成 setChecked 时,更新模型类检查行为,例如:

        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();
                                }
                            });
    

    一般来说,我更喜欢在复选框上执行单击事件,而不是在列表项中检查更改侦听器,检查更改将在滚动时调用并在每次滚动时更新 UI,以便更好地在复选框上应用单击事件并从模型管理检查状态就像我提到的那样上课。

    【讨论】:

    • 您好,先生,这很好!谢谢你。但是当我取消选中该复选框并滚动列表视图时,它又回到了被选中状态。
    【解决方案3】:

    在回答您的问题时,检查和取消检查的原因在于您在所有 CheckChangedListeners 中的这段代码

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

    您将在选中该复选框后立即取消选中该复选框。

    另外,您需要在视图回收期间处理选中状态。 否则复选框将不会保持正确的状态。滚动时。

    一种选择是将状态与数据一起保存在 ArrayList 中。为复选框保留 3 个布尔变量 state1,state2,state3。

    在 InvoicePopulate(...) 方法中 -

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

    在检查更改的侦听器中添加以下行

    invoicelists.get(position).setState1(isChecked)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多