Search code examples
androidlistviewswitchcompat

Switches in listview automatically gets check when scrolled


I know this question is duplicate to this one

Switches in listview automatically gets check android when scrolled but the answer doesen't work for me

I am stuck at same problem when i scroll through listview switch get check automatically. My logic is set switch to on if data is equal to '1' which is retrived from database and its working fine but when i scroll through list all switch get checked.

here is my code

public View getView(final int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if(null==view){
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.list_item,null);
    }
    final ApplicationInfo data = appList.get(position);
    if(null !=data){
        final SwitchCompat appName = (SwitchCompat)view.findViewById(R.id.appName);
        ImageView iconView = (ImageView)view.findViewById(R.id.app_icon);
        //Read Data
        dbHelper db = new dbHelper(context);
        SQLiteDatabase database1 = db.getReadableDatabase();
        Cursor cursor = database1.rawQuery("select isLocked from apps where package='"+appList.get(position).packageName+"'",null);
        if(cursor !=null){
            cursor.moveToFirst();
            if(cursor.getInt(0) == 1){
                appName.setChecked(true);
            }
        }

        appName.setText(data.loadLabel(packageManager));
        iconView.setImageDrawable(data.loadIcon(packageManager));

        appName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if(b){
                    //appList.get(position).packageName
                    dbHelper dbHelper = new dbHelper(context);
                    SQLiteDatabase database = dbHelper.getWritableDatabase();
                    database.execSQL("update apps set 'isLocked'=1 where package='"+appList.get(position).packageName+"'");
                }else {
                    dbHelper dbHelper = new dbHelper(context);
                    SQLiteDatabase database = dbHelper.getWritableDatabase();
                    database.execSQL("update apps set 'isLocked'=0 where package='"+appList.get(position).packageName+"'");
                }
            }
        });
    }
    return view;
}

Solution

  • In ListView, the items are reused when scrolling. If the checkbox is already checked, it needs to be unchecked before using it.

    Use:

    if(cursor.getInt(0) == 1){
        appName.setChecked(true);
    } else {
        appName.setChecked(false);
    }
    

    in place of

    if(cursor.getInt(0) == 1){
        appName.setChecked(true);
    }
    

    Or reset/uncheck the checkbox before performing other tasks:

    View view = convertView;
    if(null==view){
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.list_item,null);
    }
    
    final SwitchCompat appName = (SwitchCompat)view.findViewById(R.id.appName);
    appName.setOnCheckedChangeListener(null);
    appName.setChecked(false);
    
    final ApplicationInfo data = appList.get(position);
    if(null !=data){
        // your code.
    }