Android:我的ListView的最后一行只对OnClickListener做出反应

时间:2015-12-15 05:56:45

标签: android listview android-listview onclicklistener

我有一个ListView带有View Holder。当我按下ListView的其中一行中的按钮时,它应该在那个位置展开行并在我再按一次时折叠。我在布局上使用show / hide来做到这一点。但是,单击不会扩展正确的行。

示例:

I was clicked
I am a row that was not clicked
I am a row that was not clicked
I am a row that was not clicked // yet my layout was shown and hidden

每当我滚动时都会发生这种情况,只有我ListView中可见的最后一行会对我按下的任何行做出反应。

代码

public class PetAdapter extends BaseAdapter {
...
...

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

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (mPetList.get(position).getPetType().equals(ConstantValues.CAT)) {
            return 0;
        } else {
            return 1;
        }
    }

    @Override
    public Object getItem(int position) {
        return mPetList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return Integer.parseInt(mPetList.get(position).getId());
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Pet pet;
        View view = convertView;

        switch (getItemViewType(position)) {
            case 0:
                pet = mPetList.get(position);
                mRowType = ConstantValues.CAT;
                view = createCatRow(pet, convertView, parent);
                break;
            case 1:
                pet = mPetList.get(position);
                mRowType = ConstantValues.DOG;
                view = createDogRow(pet, convertView, parent);
                break;
        }

        return view;
    }

充气行

    public View createCatRow(Pet pet, View convertView, ViewGroup parent) {
        if (convertView != null) {
            mCatHolder = (CatViewHolder) convertView.getTag();
        } else {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.cat_row, parent, false);
            mCatHolder= new CatViewHolder(convertView);
            convertView.setTag(mCatHolder);
        }

        setCatText(pet);
        setCatListeners(pet);

        return convertView;
    }

设置文字

    public void setCatText(Pet pet) {
        mCatHolder.catName.setText(pet.getName());         
    }

设置监听器

public void setCatListeners(Pet pet) {      
    mCatHolder.catName.setOnClickListener(getCatNameListener(pet));
}

public View.OnClickListener getCatNameListener(final Pet pet) {
     return new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             expandCard(pet);
         }
     };
}

SetVisibility

public void expandCard(Pet pet) {
    if (mCatHolder.expanded.getVisibility() == View.GONE) {
        mCatHolder.collapsed.setVisibility(View.GONE);
        mCatHolder.expanded.setVisibility(View.VISIBLE);
    } else {
        mCatHolder.collapsed.setVisibility(View.VISIBLE);
        mCatHolder.expanded.setVisibility(View.GONE);
    }
}

查看持有人

public static class CatViewHolder {            
    @Bind(R.id.expanded) RelativeLayout expanded;
    @Bind(R.id.collapsed ) RelativeLayout collapsed;
    @Bind(R.id.cat_name) TextView catName;

    public CatViewHolder(View view) {
        ButterKnife.bind(this, view);
    }
}

请帮助我理解为什么会发生这种情况。为什么最后一行对第一行中的OnClick事件做出反应。谢谢

2 个答案:

答案 0 :(得分:2)

RecyclerView中,视图会被回收。因此,第一行中的视图将重新用于以后的行,并且它仍然具有OnClickListener。您必须在每个 onBindViewHolder()中设置侦听器。

答案 1 :(得分:0)

您在适配器类中持有对viewholder的引用,然后将onClicklistener应用于视图。这意味着viewholder变量将引用最后渲染的视图,并将onclicklistener设置为最后渲染的视图。

您需要在getview方法中将视图引用设置为局部变量,并将其传递给需要视图持有者的所有函数。