向下滚动列表视图时,CheckBox 将取消选中并选中

CheckBox will uncheck and check when scrolling down the listview

在我的应用程序中,我使用它来实时计算选中的复选框,这意味着当勾选复选框时,上面的计数将增加或减少。但是当向下滚动列表视图时,复选框将被取消选中。我的代码有什么建议或问题吗?

MainActivity

public class Main2Activity extends AppCompatActivity {
    ListView lstdept;
    CheckBox list_view_item_checkbox;
    SimpleAdapter ADAhere;
    Connection con;
    String un, pass, db, ip, z,country;
    int test = 0;
    ArrayList<String> selectedItems = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        country = getIntent().getStringExtra("country");
        SelectRes(country);
          lstdept.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

        lstdept.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (view != null) {
                    CheckBox checkBox = (CheckBox) view.findViewById(R.id.list_view_item_checkbox);
                    checkBox.setChecked(!checkBox.isChecked());
                    if (!checkBox.isChecked()) {
                        test = test - 1 ;
                    } else {
                        test = test + 1 ;
                    }
                }
               getSupportActionBar().setTitle(country + "              Total Count: " + lstdept.getCount()+"       " + test);
            }

        });

    }

用于填充列表视图

void SelectRes(String dept) {
        ip = "172.18.130.19";
        db = "DTRSPH";
        un = "moreface";
        pass = "moreface1234";
        try {
            con = connectionclass(un, pass, db, ip);        // Connect to database
            if (con == null) {
                toast.makeText(this,"Check Your Internet Access!",Toast.LENGTH_LONG).show();
            } else {
                String query = "SELECT FULLNAME FROM tblEPR where DEPT ='"+ dept +"'";
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery(query);
                List<Map<String, String>> data = null;
                data = new ArrayList<Map<String, String>>();

                while (rs.next()) {
                    Map<String, String> datanum = new HashMap<String, String>();
                    datanum.put("A", rs.getString("FULLNAME"));
                    data.add(datanum);
                }

                String[] fromwhere = {"A"};
                int[] viewswhere = {R.id.lblDept};
                ADAhere = new SimpleAdapter(Main2Activity.this, data,
                        R.layout.list_emp, fromwhere, viewswhere);
                lstdept = (ListView) findViewById(R.id.lstemployee);
                lstdept.setAdapter(ADAhere);
                con.close();
                getSupportActionBar().setTitle(dept + "              Total Count: " + lstdept.getCount());
            }
        } catch (Exception ex) {
            z = ex.getMessage();
        }
    }

连接到数据库

@SuppressLint("NewApi")
    public Connection connectionclass(String user, String password, String database, String server) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        Connection connection = null;
        String ConnectionURL = null;
        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            ConnectionURL = "jdbc:jtds:sqlserver://" + server + ";databaseName=" + database + ";user=" + user + ";password=" + password + ";";
            connection = DriverManager.getConnection(ConnectionURL);
        } catch (SQLException se) {
            Log.e("error here 1 : ", se.getMessage());
        } catch (ClassNotFoundException e) {
            Log.e("error here 2 : ", e.getMessage());
        } catch (Exception e) {
            Log.e("error here 3 : ", e.getMessage());
        }
        return connection;
    }
}

您必须维护选中复选框的列表,然后 setunset 基于该列表的复选框。

假设您有 selectedcheckBox 列表,其中包含所选复选框的列表。

ArrayList<> selectedcheckBox = new ArrayList<>();

所以你可以做的是:

lstdept.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (view != null) {
                    selectedcheckBox.add(//Add item to the list)
                    CheckBox checkBox = (CheckBox) view.findViewById(R.id.list_view_item_checkbox);
                    checkBox.setChecked(!checkBox.isChecked());
                    if (!checkBox.isChecked()) {
                        test = test - 1 ;
                    } else {
                        test = test + 1 ;
                    }
                }
               getSupportActionBar().setTitle(country + "              Total Count: " + lstdept.getCount()+"       " + test);
            }

        });

当您在适配器中填充 listView 时,请检查 selectedcheckBox 列表。 如果在列表中设置了值,则 set 复选框,否则 unset.

之所以会发生这种情况,是因为 listView 在移出视图并再次可见时会自行回收。因此,当它再次可见时,所有值都会重新设置。所以应该保持适当的检查来膨胀视图。

在您的适配器对象中添加一个用于检查和取消检查的布尔参数。默认情况下,为列表中的每个项目设置 false,在适配器中选中设置为 true 并调用 notifyDataSetChanged()。

Use a model class

     public class ContactModel {
        String phone,name;
        boolean sel;


        public ContactModel(String phone, String name, boolean sel) {
            this.phone = phone;
            this.name = name;
            this.sel = sel;

        }

        public String getPhone() {
            return phone;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isSel() {
            return sel;
        }

        public void setSel(boolean sel) {
            this.sel = sel;
        }

我的自定义适配器

public class ContactADAPTER extends BaseAdapter {
    String phone,name;
    boolean sel;
 Activity act;
    List<ContactModel> contactModels;

    public ContactADAPTER(Activity act, List<ContactModel> contactModels) {
        this.act = act;
        this.contactModels = contactModels;
    }



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

    @Override
    public Object getItem(int i) {
        return contactModels.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        LayoutInflater inflater=LayoutInflater.from(context);
        view=inflater.inflate(R.layout.phone_list_item,viewGroup,false);
        TextView phone1= (TextView) view.findViewById(R.id.phone1);
        TextView name1= (TextView) view.findViewById(R.id.name1);
        CheckBox tick= (CheckBox) view.findViewById(R.id.tick);
        phone1.setText(contactModels.get(i).getPhone());
        name1.setText(contactModels.get(i).getName());
        if(contactModels.get(i).isSel())
        {
            tick.setSelected(true);
        }
        else
        {
            tick.setSelected(true);
        }
 tick.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                contactModels.get(i).setSel(isChecked);
                notifyDataSetChanged();
//for getting ticked count

int count=0;
for(ContactModel c:contactModels)
{
if(c.isSel())
{
count++;
}
}
// show count
act.getActionBar().setTitle(String.valueOf(count));
                }
            });
            return view;
        }
    }

在Activity

 List<ContactModel> cmodelList= new ArrayList<>();
      cmodelList.add(new ContactModel(phonenumber, name, false));
      cmodelList.add(new ContactModel(phonenumber2, name2, false));
      cmodelList.add(new ContactModel(phonenumber3, name3, false));

           ContactADAPTER contactAdapter=new ContactADAPTER(Phone_Contact_List.this,cmodelList);
            listView.setAdapter(contactList);

您的适配器将有一个“getView()”方法,您将完成填充单元格数据的所有工作,使用 getItem(position) 获取项目,然后在该 getView 期间更新单元格中的所有视图() 方法

我猜问题出在没有使用 holder
制作一个 beanadapter 就像@Athira 说的
然后在 getView 中的内部适配器试试这个

@Override
        public View getView(int i, View view, ViewGroup viewGroup) {
   ViewHolder holder = null;

 if (view == null) {
            LayoutInflater inflater=LayoutInflater.from(context);
            view=inflater.inflate(R.layout.phone_list_item,viewGroup,false);
            holder.phone1= (TextView) view.findViewById(R.id.phone1);
            holder.name1= (TextView) view.findViewById(R.id.name1);
            holder.tick= (CheckBox) view.findViewById(R.id.tick);
 view.setTag(holder);
}else{
            holder = (ViewHolder) view.getTag();
        }
           holder.phone1.setText(contactModels.get(i).getPhone());
           holder.name1.setText(contactModels.get(i).getName());
            if(contactModels.get(i).isSel())
            {
                holder.tick.setSelected(true);
            }
            else
            {
                holder.tick.setSelected(true);
            }
     holder.tick.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    contactModels.get(i).setSel(isChecked);
                    notifyDataSetChanged();
                }
            });
            return view;
        }
 public class ViewHolder {
        TextView phone1,name1;
CheckBox tick;

    }
    }