Android ListView-ViewHolder设计的错误回收行为

Android ListView-ViewHolder设计的错误回收行为,android,listview,android-arrayadapter,Android,Listview,Android Arrayadapter,说明: 我目前正在使用ViewHolder设计模式实现一个自定义ListViewAdapter。适配器正在使用带有按钮的布局,该按钮用于切换RelativeLayout的可见性 问题: 当我点击按钮并显示RelativeLayout时,在我向下滚动之前,一切似乎都正常当我向下滚动时,我看到其他列表项受到上一次按钮单击的影响,因此在其他(错误)项上可以看到RelativeLayout。受按钮单击影响的项似乎是我向下滚动时循环使用的项。请注意,其他所有操作都是正确的,文本等都设置在正确的位置 代

说明:


我目前正在使用ViewHolder设计模式实现一个自定义ListViewAdapter。适配器正在使用带有按钮的布局,该按钮用于切换RelativeLayout的可见性

问题:


当我点击按钮并显示RelativeLayout时,在我向下滚动之前,一切似乎都正常当我向下滚动时,我看到其他列表项受到上一次按钮单击的影响,因此在其他(错误)项上可以看到RelativeLayout。受按钮单击影响的项似乎是我向下滚动时循环使用的项。请注意,其他所有操作都是正确的,文本等都设置在正确的位置

代码:


CustomListAdapter

public class ItemsListAdapter extends ArrayAdapter<Item> {
private Context mContext;
private List<Item> mItems;

public ItemsListAdapter(Context context, int resource, List<Item> objects) {
    super(context, resource);
    mContext = context;
    mItems = objects;
}

static class ViewHolder {
    View mView;
    boolean mExpanded;

    public ViewHolder(View view, boolean expanded)
    {
        mView = view;
        mExpanded = expanded;
    }
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    final Item item = getItem(position);

    final ViewHolder holder;
    if (v == null) {

        LayoutInflater mInflater = (LayoutInflater)
                mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        v = mInflater.inflate(R.layout.custom_list_item, null);

        holder = new ViewHolder(v, false);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

    if(item != null)
    {
        TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
        tvName.setText(item.getName());

        RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
        if(holder.mExpanded) {
            rlExpand.setVisibility(View.VISIBLE);
        }
        else {
            rlExpand.setVisibility(View.GONE);
        }

        TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
        if(tvDescription != null)
            tvDescription.setText(item.getDescription());

        final ImageButton ibExpand = (ImageButton) holder.mView.findViewById(R.id.ib_expand);
        ibExpand.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
                if (rlExpand.getVisibility() == View.GONE) {
                    v.setVisibility(View.INVISIBLE);
                    rlExpand.setVisibility(View.VISIBLE);
                    holder.mExpanded = true;
                }
            }
        });

        ImageButton ibCollapse = (ImageButton) holder.mView.findViewById(R.id.ib_collapse);
        ibCollapse.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
                ibExpand.setVisibility(View.VISIBLE);
                rlExpand.setVisibility(View.GONE);
                holder.mExpanded = false;
            }
        });


    }

    return v;
}

@Override
public int getCount() {
    return mItems.size();
}

@Override
public Truism getItem(int position) {
    return mItems.get(position);
}
公共类ItemsListAdapter扩展了ArrayAdapter{
私有上下文;
私人名单;
public ItemsListAdapter(上下文上下文、int资源、列表对象){
超级(上下文、资源);
mContext=上下文;
mItems=对象;
}
静态类视窗夹{
视图视图;
布尔扩展;
公共视图持有者(视图视图,布尔展开)
{
mView=视图;
mExpanded=扩展;
}
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图v=转换视图;
最终项目=获取项目(位置);
最终持票人;
如果(v==null){
LayoutInflater mInflater=(LayoutInflater)
mContext.getSystemService(活动.布局\充气机\服务);
v=最小充气量(R.layout.custom\u list\u项,空);
holder=新的ViewHolder(v,false);
v、 setTag(支架);
}否则{
holder=(ViewHolder)v.getTag();
}
如果(项!=null)
{
TextView tvName=(TextView)holder.mView.findViewById(R.id.tv_name);
setText(item.getName());
RelativeLayout rExpand=(RelativeLayout)holder.mView.findViewById(R.id.rl_expand);
如果(持有者.mExpanded){
rlExpand.setVisibility(View.VISIBLE);
}
否则{
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription=(TextView)holder.mView.findViewById(R.id.tv_description);
if(tvDescription!=null)
tvDescription.setText(item.getDescription());
final ImageButton ibExpand=(ImageButton)holder.mView.findviewbyd(R.id.ib_expand);
ibExpand.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
RelativeLayout rExpand=(RelativeLayout)holder.mView.findViewById(R.id.rl_expand);
if(rlExpand.getVisibility()==View.GONE){
v、 设置可见性(视图不可见);
rlExpand.setVisibility(View.VISIBLE);
holder.mExpanded=true;
}
}
});
ImageButton ibCollapse=(ImageButton)holder.mView.findViewById(R.id.ib_collapse);
ibCollapse.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
RelativeLayout rExpand=(RelativeLayout)holder.mView.findViewById(R.id.rl_expand);
ibExpand.setVisibility(View.VISIBLE);
rlExpand.setVisibility(View.GONE);
holder.mExpanded=false;
}
});
}
返回v;
}
@凌驾
public int getCount(){
返回mItems.size();
}
@凌驾
公共真理getItem(内部位置){
返回mItems.get(位置);
}
非常感谢您的帮助!提前感谢您!

尝试更改:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    final Item item = getItem(position);

    final ViewHolder holder;
    if (v == null) {

        LayoutInflater mInflater = (LayoutInflater)
                mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        v = mInflater.inflate(R.layout.custom_list_item, null);

        holder = new ViewHolder(v, false);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

    if(item != null)
    {
        TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
        tvName.setText(item.getName());

        RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
        if(item.isExpanded) {
            rlExpand.setVisibility(View.VISIBLE);
        }
        else {
            rlExpand.setVisibility(View.GONE);
        }

        TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
        if(tvDescription != null)
            tvDescription.setText(item.getDescription());

        [...]
    }

    return v;
}

holder.mExpanded
更改为
item.isExpanded

将视图状态保存到您的模型中,例如isExpanded.s您的代码中的方法完全错误:
item
ViewHolder
之间有什么关系?非常感谢,这很有帮助。