如何修复列表项的复选框消失的 Android ListView 呈现错误?

How to fix Android ListView Rendering Error where the checkboxes of the list items disappear?

我正在开发一个 android 应用程序,我在其中使用了一个列表视图,它在每个行项目中都有一个复选框。但是当它向上或向下滚动时,随机行会删除以整个列表中没有显示的复选框结尾的复选框。我尝试了在线教程中提供的许多解决方案,但其中 none 有效。他们都使用 ViewHolder class 来显示它。你能帮帮我吗?

这是我可以提供的所有代码:

列表项 XML:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center">

        <ImageView
            android:id="@+id/user_image_view"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:layout_margin="16dp"
            tools:src="@mipmap/ic_account_circle_bue" />

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingRight="16dp"
                android:layout_centerVertical="true">

                <TextView
                    android:id="@+id/user_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Name"
                    android:textSize="19dp"
                    android:textStyle="bold"
                    android:ellipsize="end"
                    android:maxLines="1"
                    android:textColor="#000000"
                    android:paddingRight="5dp"/>

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/user_roll_number"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Roll Number"
                        android:textSize="15dp" />

                    <TextView
                        android:id="@+id/user_department"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:paddingLeft="12dp"
                        android:text="Department"
                        android:textSize="15dp"
                        android:maxLines="1"
                        android:ellipsize="end"/>

                </LinearLayout>
            </LinearLayout>

            <CheckBox
                android:id="@+id/checkbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_gravity="center"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"/>
        </RelativeLayout>
    </LinearLayout>
</LinearLayout>

UsersSelection(模型 Class):

    package com.app.shubhamjhunjhunwala.heritagecompanion_students;

/**
 * Created by shubham on 09/05/17.
 */

public class UsersSelection {
    public Users users;
    public boolean isSelected;

    public UsersSelection (Users users, boolean isSelected) {
        this.users = users;
        this.isSelected = isSelected;
    }

    public Users getUsers() {
        return users;
    }

    public void setUsers(Users users) {
        this.users = users;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }
}

Users.java(自定义 class):

    package com.app.shubhamjhunjhunwala.heritagecompanion_students;

/**
 * Created by shubham on 23/01/17.
 */

public class Users {

    String name;
    String department;
    String roll;
    String dpDownloadUri;

    Users() {}

    public Users(String name, String department, String roll, String dpDownloadUri) {
        this.name = name;
        this.department = department;
        this.roll = roll;
        this.dpDownloadUri = dpDownloadUri;
    }

    public String getName() {
        return name;
    }

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

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getRoll() {
        return roll;
    }

    public void setRoll(String roll) {
        this.roll = roll;
    }

    public String getDpDownloadUri() {
        return dpDownloadUri;
    }

    public void setDpDownloadUri(String dpDownloadUri) {
        this.dpDownloadUri = dpDownloadUri;
    }
}

列表视图的自定义数组适配器:

    package com.app.shubhamjhunjhunwala.heritagecompanion_students;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.io.FileNotFoundException;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * Created by shubham on 09/05/17.
 */

public class UsersSelectionAdapter extends ArrayAdapter<UsersSelection> {
    public Context context;
    public String roll;
    public boolean isForGroup;
    public List<GroupMembers> groupMembersList;
    public List<UsersSelection> list;

    public CheckBox checkBox;

    public UsersSelectionAdapter(Context context, int resource, List<UsersSelection> objects) {
        super(context, resource, objects);
        this.context = context;
        list = objects;
    }

    public class ViewHolder {
        TextView nameTextView;
        TextView rollNumberTextView;
        TextView departmentTextView;
        ImageView dpImageView;
        CheckBox checkBox;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        SharedPreferences sharedPreferences = ((Activity) getContext()).getSharedPreferences("HCS", 0);
        roll = sharedPreferences.getString(AuthenticationActivity.ROLL_SHARED_PREFERENCE_KEY, "");

        ViewHolder viewHolder = null;

        if (convertView == null) {
            convertView = ((Activity) getContext()).getLayoutInflater().inflate(R.layout.user_list_item, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.nameTextView = (TextView) convertView.findViewById(R.id.user_name);
            viewHolder.departmentTextView = (TextView) convertView.findViewById(R.id.user_department);
            viewHolder.rollNumberTextView = (TextView) convertView.findViewById(R.id.user_roll_number);
            viewHolder.dpImageView = (ImageView) convertView.findViewById(R.id.user_image_view);
            viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);

            viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    int getPosition = (int) buttonView.getTag();
                    list.get(getPosition).setSelected(buttonView.isSelected());
                }
            });

            convertView.setTag(viewHolder);
            convertView.setTag(R.id.user_name, viewHolder.nameTextView);
            convertView.setTag(R.id.user_department, viewHolder.departmentTextView);
            convertView.setTag(R.id.user_roll_number, viewHolder.rollNumberTextView);
            convertView.setTag(R.id.user_image_view, viewHolder.dpImageView);
            convertView.setTag(R.id.checkbox, viewHolder.checkBox);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.checkBox.setTag(position);

        /*TextView nameTextView = (TextView) convertView.findViewById(R.id.user_name);
        TextView departmentTextView = (TextView) convertView.findViewById(R.id.user_department);
        TextView rollNumberTextView = (TextView) convertView.findViewById(R.id.user_roll_number);
        ImageView dpImageView = (ImageView) convertView.findViewById(R.id.user_image_view);
        checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);*/

        UsersSelection usersSelection = getItem(position);
        Users user = usersSelection.getUsers();

        if (!isForGroup) {
            viewHolder.checkBox.setVisibility(View.GONE);
        } else {
            if (user.getRoll().equals(roll)) {
                viewHolder.checkBox.setVisibility(View.GONE);
            }
        }

        viewHolder.nameTextView.setText(user.getName());
        viewHolder.nameTextView.setTag(usersSelection);
        viewHolder.departmentTextView.setText(user.getDepartment());
        viewHolder.departmentTextView.setTag(usersSelection);
        viewHolder.rollNumberTextView.setText(user.getRoll());
        viewHolder.rollNumberTextView.setTag(usersSelection);

        viewHolder.checkBox.setChecked(list.get(position).isSelected());
        viewHolder.checkBox.setTag(usersSelection);

        Bitmap bitmap = null;

        if (!user.getDpDownloadUri().equals("")) {

            DPAsyncTask dpAsyncTask = new DPAsyncTask(context, viewHolder.dpImageView.getContext(), viewHolder.dpImageView, user);
            dpAsyncTask.execute();

        } else {

            Glide.clear(viewHolder.dpImageView);
            viewHolder.dpImageView.setImageDrawable(getContext().getResources().getDrawable(R.mipmap.ic_account_circle_bue));

        }

        return convertView;
    }

    public boolean isForGroup() {
        return isForGroup;
    }

    public void setForGroup(boolean forGroup) {
        isForGroup = forGroup;
    }

    public List<GroupMembers> getGroupMembersList() {
        return groupMembersList;
    }

    public void setGroupMembersList(List<GroupMembers> groupMembersList) {
        this.groupMembersList = groupMembersList;
    }

    public CheckBox getCheckBox() {
        return checkBox;
    }

    public void setCheckBox(CheckBox checkBox) {
        this.checkBox = checkBox;
    }
}

感谢您解决我的问题。希望你帮忙:)

    if (!isForGroup) {
        viewHolder.checkBox.setVisibility(View.GONE);
    } else {
        if (user.getRoll().equals(roll)) {
            viewHolder.checkBox.setVisibility(View.GONE);
        }
    }

你只能做到 CheckBox GONE。您永远不会将其重置为 VISIBLE.

记住ListView、otherAdapterView类、RecyclerView后面的重点是回收视图。您不能也不应该假设您的小部件在 getView() 中处于任何特定状态。如果你修改一个小部件(例如,改变它的可见性),你需要一直修改那个状态。

所以,把上面的代码改成:

    if (!isForGroup || user.getRoll().equals(roll)) {
        viewHolder.checkBox.setVisibility(View.GONE);
    } else {
        viewHolder.checkBox.setVisibility(View.VISIBLE);
    }

或类似的东西,这样你总是声明CheckBox是否应该可见。