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 和 setVisibilty 方法被正确调用,但我的视图有时会变得可见,有时不可见,这取决于列表滚动位置。

我做错了什么,我应该如何解决这个问题?

4

3 回答 3

4

当滚动列表视图时,子视图被重用并重新分配到新位置。这是为了提高效率,因为创建新视图的成本很高。然而,它给程序员带来了负担——在每次 getView 调用时,您必须完全重置视图的每个值。因此,如果在子项中按下按钮会更改其成员之一的可见性,您需要记住每个数字位置的可见性应该是什么,并且在 getView 中您必须为每个元素设置适当的可见性。

于 2013-03-14T14:40:04.007 回答
1

出于性能原因,持有者旨在保留对内部视图的引用。它与列表中显示的数据无关- 仅与列表中的“单元格”有关。您应该根据您的数据确定内容是否可见。

于 2013-03-14T14:40:02.663 回答
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;
    }
}
于 2013-03-14T14:51:06.453 回答