带有复选框的ListView在滚动时会失真

时间:2014-12-25 09:02:05

标签: android listview android-listview

我有一个包含Checkable项的ListView的活动。每个项目都是自定义视图名称CheckableContact,它实现Checkable。一切都工作正常,除非我向下滚动ListView中的项目以不同的速度移动到不合适的位置。看看下面的截图。
要记住的是ListView在到达滚动结束时使用sociket.io进行更新。

ListView distorted ListView distorted

这是我课程的完整来源。

CheckableContact.java

public class CheckableContact extends LinearLayout implements Checkable {
    private final View v;
    private ImageView imageView;
    private TextView name;

    public int getProfileID() {
        return profileID;
    }

    public void setProfileID(int profileID) {
        this.profileID = profileID;
    }

    private int profileID;

    public TextView getDesc() {
        return desc;
    }

    public TextView getName() {
        return name;
    }

    public ImageView getImageView() {
        return imageView;
    }

    private TextView desc;
    boolean checked = false;

    public CheckableContact(Context context) {
        super(context);
        LayoutInflater inflater = LayoutInflater.from(context);
        v = inflater.inflate(R.layout.contact_item_check, this, true);
        CheckBox cb = (CheckBox) v.findViewById(R.id.select_contact);
        cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                setChecked(b);
            }
        });

        imageView = (ImageView) v.findViewById(R.id.avatar);
        name = (TextView) v.findViewById(R.id.contact_title);
        desc = (TextView) v.findViewById(R.id.contact_desc);
    }


    @Override
    public void setChecked(boolean b) {
        Log.d("Checkable", "Checking: " + profileID);
        this.checked = b;
    }

    @Override
    public boolean isChecked() {
        return checked;
    }

    @Override
    public void toggle() {
        checked = !checked;
    }
}

CheckParticipantsAdapter.java

public class CheckParticipantsAdapter extends ArrayAdapter<Profile> {
    LayoutInflater inflater;
    ArrayList<Profile> myProfiles;
    AQuery aq;
    private Context context;
    int contactLayout = R.layout.conversation_item;
    Map<Integer, CheckableContact> checks = new HashMap<>();

    public CheckParticipantsAdapter(Context context, ArrayList<Profile> myProfiles) {
        super(context, R.layout.friend_list, myProfiles);
        this.myProfiles = myProfiles;
        this.context = context;
        aq = new AQuery(context);

    }

    public void setContactLayout(int layoutID) {
        contactLayout = layoutID;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        Profile profile = myProfiles.get(position);
        if (row == null) {
            row = new CheckableContact(context);

            ((CheckableContact) row).getName().setText(profile.getFullName());

            ((CheckableContact) row).setProfileID(profile.getProfileID());
            if (checks.containsKey(profile.getProfileID())) {
                ((CheckableContact) row).setChecked(checks.get(profile.getProfileID()).isChecked());
            } else {
                checks.put(profile.getProfileID(), (CheckableContact) row);
            }
        } else {
            row = checks.get(profile.getProfileID());
        }


//        TextView username = (TextView) row.findViewById(R.id.conversation_name);

//        if (!profile.getPhotoPath().equals("")) {
        String path = Util.URL_USERS_PHOTOS + profile.getPhotoPath();
        aq.id(((CheckableContact) row).getImageView()).image(path, true, true, 100, R.drawable.avatar);
//        }

        return row;
    }

    public ArrayList<Integer> getCheckIds() {
        ArrayList<Integer> ids = new ArrayList<>();
        Iterator it = checks.keySet().iterator();
        while (it.hasNext()) {
            CheckableContact c = (CheckableContact) it.next();
            if (c.isChecked()) {
                ids.add(c.getProfileID());
            }
        }
        return ids;
    }
}

1 个答案:

答案 0 :(得分:1)

当您在列表项中使用自定义视图时,我认为您的视图不知道自己的高度,因此在滚动时您会看到不同的视图高度,因为您始终创建新视图,因此您必须使用ViewHolder以获得更好的性能和修复你的问题。

你可以看到以下链接,以便更好地理解我的话,我也为你提供了一些示例代码。

ListView with ArrayAdapter and ViewHolder

Android Developer

所有步骤是:

1- convertView为空时启动您的视图

2-使用setTag方法在视图中存储此信息

3-如果convertView不为空,请使用getTag

获取该信息 在其他部分后,您的视图的4-init数据。

if (convertView == null)
{
   ViewHolder holder = new ViewHolder();
   .....  // init holder


   convertView.setTag(holder);

}

else
{
   holder = (ViewHolder)convertView.getTag();
} 

 // init data with holder object