mr.jm
mr.jm

Reputation: 37

CheckBox will uncheck and check when scrolling down the listview

In my application I use this to count the checked checkbox in real time meaning when tick the box the count above will increase or decrease. but when scrolling down the listview the checked box will be uncheck. any suggestion or problem in my codes?

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

        });

    }

Use to populate listview

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

Connection to database

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

Upvotes: 0

Views: 1812

Answers (4)

Athira
Athira

Reputation: 1213

In your adapter object add a boolean parameter for check and un-check. By default set false for each item in the list, when checked set as true in adapter and call 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;
        }

My custom adapter

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

In 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);

Upvotes: 2

Kevin Kurien
Kevin Kurien

Reputation: 842

I guess the problem is not using holder
make a bean and adapter like @Athira says
then inside adapter in getView try this

@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;

    }
    }

Upvotes: 1

Brandon
Brandon

Reputation: 1407

Your adapter will have a “getView()” method that you will do all the work for populating the cells data, use getItem(position) to get the item and then update all your views in the cell during that getView() method

Upvotes: 0

Prithvi Bhola
Prithvi Bhola

Reputation: 3151

You have to maintain the list of selected checkbox and then set or unset the checkbox based on that list.

So let's say you have selectedcheckBox list which have the list of the selected checkbox.

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

So what you can do is:

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

        });

And when you are populating the listView in your adapter, make a check with selectedcheckBox list. If the value is set in the list then set the checkbox else unset.

The reason why is this happening because listView recycles itself as it moves out of the view and becomes visible again. So all the values are set again as it becomes visible again. So one should maintain proper checks to inflate the view.

Upvotes: 0

Related Questions