可扩展列表视图重复视图

Expandable List View Duplicate Views

我的问题如下。
我正在实现一个 ExapndableListView,第一组有 children 有一个由这 3 个组成的布局:TextView、ImageView、ImageView。
现在,当单击 child 时,我使用 v.findViewById().setVisibility() 设置了两个图像视图之一的可见性,并且它的工作效果和我想象的一样好。
问题是当列表超过 10 children 时,android 系统在向下滚动时使用顶部最后一个隐藏的视图回收视图,现在当我单击位置“0”的 child ”,我只切换那个视图的图像,而其他视图没有改变,到目前为止还不错,但是当我向下滚动并且 android 系统使用 child“0”视图回收视图child 的位置“11”,它更改了对应于 child“11”的 textView,但用于 child“11”的视图是 child 的视图“0”因此与之前切换的相同图像出现在 child“11”的视图中,就好像它也被点击了,但事实并非如此! 我正在这样做:

@Override
    public View getChildView(final int parentPosition, final int childPosition,  boolean isLastChild, View convertView, ViewGroup parent) {

    Log.d("status","parent : "+parentPosition + " child : " + childPosition + " View : "+convertView + " ViewGroup : "+parent);
    int itemType = 25;
    itemType = getChildType(parentPosition, childPosition);
    String child_title = (String) getChild(parentPosition,childPosition);
    if (convertView == null)
    {
        if (itemType == 0)
        {
            LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.activities2_child_layout, parent, false);

        } else if (itemType == 1) {
            LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
        } else if (itemType == 2) {
            LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
        }
    }
    if (itemType == 0)
    //region parent 0 child handling
    {
        Log.d("Child", childPosition + " : " + child_title);

        final TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child_txt);
        final ImageView img_Likes = (ImageView) convertView.findViewById(R.id.activities2_img_like);
        final ImageView img_Dislikes = (ImageView) convertView.findViewById(R.id.activities2_img_dislike);
        child_textview.setText(child_title);

        child_textview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                switch (AAChildClicks[childPosition]) {
                    case 0:
                        AAChildClicks[childPosition]++;
                        img_Likes.setVisibility(View.VISIBLE);
                        //add to total
                        All_Likes.add(child_textview.getText().toString());
                        Log.d("Likes", "Likes + " + child_textview.getText().toString());
                        break;
                    case 1:
                        AAChildClicks[childPosition]++;
                        img_Likes.setVisibility(View.GONE);
                        img_Dislikes.setVisibility(View.VISIBLE);
                        String child = child_textview.getText().toString();
                        //remove from total
                        All_Likes.remove(child_textview.getText().toString());
                        Log.d("Likes", "Likes - " + child_textview.getText().toString());
                        //add to total
                        All_Dislikes.add(child_textview.getText().toString());
                        Log.d("Likes", "Dislikes + " + child_textview.getText().toString());
                        break;
                    case 2:
                        AAChildClicks[childPosition] = 0;
                        img_Likes.setVisibility(View.GONE);
                        img_Dislikes.setVisibility(View.GONE);
                        String child2 = child_textview.getText().toString();
                        //remove from total
                        All_Dislikes.remove(child_textview.getText().toString());
                        Log.d("Likes", "Dislikes - " + child_textview.getText().toString());
                        break;
                }
            }

        });
    }
    //endregion

    if (itemType == 1)
    //region parent 1 child handling
    {
        TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
        child_textview.setText(child_title);
    }
    //endregion

    if (itemType == 2)
    //region parent 2 child handling
    {
        TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
        child_textview.setText(child_title);
    }
    //endregion

    return convertView;
}

如何避免这种情况 duplication/error ?!

目前您将状态存储在 itemView 中 img_Likes.setVisibility(View.VISIBLE);

你也必须将它存储在你的模型中

  ((MyType) getChild(parentPosition,childPosition)).setIsVisible(true)

如果您(重新)创建列表视图项目,您可以使用该信息来获得(en/dis)可见性

 img_Likes.setVisibility((((MyType) getChild(parentPosition,childPosition)).getIsVisible()) ? View.VISIBLE : View.GONE);

当视图被回收时,其组件将保持与之前相同的可见性状态。因此,如果您隐藏了 View 的部分内容,那么当它被回收时,这些部分将被隐藏。

因此,您需要做两件事:

  1. 每次调用 GetChildView 时都将视图的可见性设置为正确的状态。

  2. 您需要跟踪视图之外的位置数据。现在,您对视图可见性的唯一记录是在视图本身上。当该视图被回收时,您的记录将丢失(视图的状态成为其他位置的起始状态——这就是我们必须在#1 中覆盖它的原因)。

您应该在某种列表或节点类型的体系结构中跟踪视图可见性——您不能将该数据存储在视图上,因为它们不会与任何一个位置永久关联。