Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've looked into several other solutions for this problem, but none of them seem to do it for me, just because they are all fundamentally different. I have in my Adapter the PackageInfo class, which is responsible for listing the apps installed on the device. That part works. Next to each app are two checkboxes that sort that app into either category 1 or 2. I stored the user's selection in a SharedPreference (also helpful would be feedback on maybe a better way to store all the user input, but that's not my main concern).

I've looked through several of the other solutions, but I think I'm missing something fundamentally here, the issue being when the user scrolls, checkboxes are randomly checked or unchecked.

public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    LayoutInflater inflater = context.getLayoutInflater();


    if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_layout, null);
        holder = new ViewHolder();
        holder.apkName = (TextView) convertView.findViewById(R.id.appname);
        holder.category1 = (CheckBox) convertView.findViewById(R.id.arcade);
        holder.category1.setTag(position);
        holder.category2 = (CheckBox) convertView.findViewById(R.id.educational);
        holder.category2.setTag(position);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    PackageInfo packageInfo = (PackageInfo) getItem(position);
    Drawable appIcon = packageManager.getApplicationIcon(packageInfo.applicationInfo);
    final String appName = packageManager.getApplicationLabel(packageInfo.applicationInfo).toString();
    final String appPositionArcade = "cat1"+appName;
    final String appPositionEdu = "cat2"+appName;
    appIcon.setBounds(0, 0, 55, 55);
    holder.apkName.setCompoundDrawables(appIcon, null, null, null);
    holder.apkName.setCompoundDrawablePadding(15);
    holder.apkName.setText(appName);

    holder.category1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (holder.category1.isChecked()) {
                holder.category2.setChecked(false);
                SharedPreferences stored = context.getSharedPreferences("Shared Preferences", 0);
                SharedPreferences.Editor editor = stored.edit();

                editor.putBoolean(appPositionArcade, true);
                editor.putBoolean(appPositionEdu, false);
            } else if (!holder.category1.isChecked()) {
                SharedPreferences stored = context.getSharedPreferences("Shared Preferences", 0);
                SharedPreferences.Editor editor = stored.edit();

                editor.putBoolean(appPositionArcade, false);
            }
        }
    });

    holder.category2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (holder.category2.isChecked()) {
                SharedPreferences stored = context.getSharedPreferences("Shared Preferences", 0);
                SharedPreferences.Editor editor = stored.edit();

                holder.category1.setChecked(false);
                editor.putBoolean(appPositionArcade, false);
                editor.putBoolean(appPositionEdu, true);
            } else if (!holder.category2.isChecked()) {
                SharedPreferences stored = context.getSharedPreferences("Shared Preferences", 0);
                SharedPreferences.Editor editor = stored.edit();

                editor.putBoolean(appPositionEdu, false);
            }
        }
    });

    return convertView;
}
share|improve this question

2 Answers

You are probably running into view recyling problem. You need to explicitly set the state of holder.category1 and holder.category2.

Because what happen is when the view get recycled and you incidentally get left over boolean value from other row of data that trigger your onclicklistener.

share|improve this answer

Try moving convertView.setTag(holder); to just above return convertView;

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.