简体   繁体   English

带复选框的ListView,滚动问题

[英]ListView with Checkboxes, issues with scrolling

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. 我的适配器中有PackageInfo类,该类负责列出设备上安装的应用程序。 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). 每个应用程序旁边都有两个复选框,可将该应用程序分类为类别1或2。我将用户的选择存储在SharedPreference中(也可能会提供有关存储所有用户输入的更好方法的反馈,但这很有帮助,但这不是我的主要关注点)。

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

You are probably running into view recyling problem. 您可能会遇到视图重新整理问题。 You need to explicitly set the state of holder.category1 and holder.category2. 您需要显式设置holder.category1和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. 因为发生的事情是视图被回收时,并且您偶然从触发您的onclicklistener的另一行数据中获取了布尔值。

Try moving convertView.setTag(holder); 尝试移动convertView.setTag(holder); to just above return convertView; return convertView;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM