在ListAdapter中设置Android视图的可见性

3

我有一个带有ArrayAdapter的ListView。当点击列表项内的按钮时,我希望该项中特定的视图(而不是其他项中的视图)可见或隐藏。

以下是在适配器的getView()方法中所做的代码:

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

    if (convertView == null) {

        convertView = vi.inflate(layoutResourceId, null, false);
        holder = new Holder();
        holder.setShare((ImageView) convertView.findViewById(R.id.share));
        holder.setShareButtons((LinearLayout)convertView.findViewById(R.id.shareButtons));
        convertView.setTag(holder);


    }
    holder = (Holder) convertView.getTag();


    holder.getShare().setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            if(holder.getShareButtons().getVisibility()==View.GONE){
                holder.getShareButtons().setVisibility(View.VISIBLE);

            }
            else{
                holder.getShareButtons().setVisibility(View.GONE);

            }


        }
    });

    return convertView;
}

但是我得到的结果却很奇怪。虽然 OnClickListener 和 setVisibility 方法被正确调用,但我的视图有时可见,有时不可见,这取决于列表滚动位置。

我做错了什么?该如何解决?

3个回答

4

当列表视图滚动时,子视图被重用并重新分配到新位置。这是为提高效率,因为创建新视图是昂贵的。然而,这将责任放在程序员身上-在每次getView调用中,您必须完全重置视图的每个值。因此,如果在子项中按下按钮更改了其中某个成员的可见性,则需要记住每个数值位置应该是什么可见性,并在getView中为每个元素设置适当的可见性。


1
这是我的自定义适配器的一部分代码片段,它将为您提供一个示例,展示如何在适配器内响应项目点击:
功能:每行代表一个对象,可以看到或者看不到。无论是否可见,图像都是不同的。单击项目切换图像的开/关状态。
public class Exampledapter extends ArrayAdapter<CustomObject> {

    private Context mContext;
    private int mLayoutResourceId;
    private ArrayList<CustomObject> mData = null;

    public ExampleAdapter(Context context, int layoutResourceId, ArrayList<CustomObject> data, DataSource datasource) {
        super(context, layoutResourceId, data);
        this.mLayoutResourceId = layoutResourceId;
        this.mContext = context;
        this.mData = data;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View lRow = convertView;
        ViewHolder holder = null;

        if (lRow == null) {
            LayoutInflater lInflater = ((Activity) mContext).getLayoutInflater();
            lRow = lInflater.inflate(mLayoutResourceId, parent, false);

            holder = new ViewHolder();
            holder.txtTitle = (TextView) lRow.findViewById(R.id.text_);
            holder.imageSeen = (ImageView) lRow.findViewById(R.id.image_toggle);

            lRow.setTag(holder);
        } else {
            holder = (ViewHolder) lRow.getTag();
        }

        holder.imageSeen.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                onListItemClick(position);
            }
        });

        if (mData.get(position).getSeen() == 1) {
            holder.imageSeen.setImageBitmap(mImageSeen);
        } else {
            holder.imageSeen.setImageBitmap(mImageUnseen);
        }

        holder.txtTitle.setText(mData.get(position).getTitle());
        return lRow;
    }

    protected void onListItemClick(int position) {
        if (mData.get(position).isSeen()) {       
            mData.get(position).setSeen(0);
        } else {  
            mData.get(position).setSeen(1);
        }
        notifyDataSetChanged();
    }

    class ViewHolder {
        TextView txtTitle;
        ImageView imageSeen;
    }
}

1
这个 holder 的作用是为了性能考虑而保留内部视图的引用。它与你列表中呈现的数据无关,仅与列表中的“单元格”相关。你应该根据你的数据来确定东西是否可见,而不是根据 holder。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接