Android:只有我的ListView的最后一行响应OnClickListener

问题描述:

我有一个ListView与查看持有人。当我在我的ListView的其中一行中按下按钮时,它应该在该位置展开该行并在我再次按下时折叠。我在布局上使用show/hide来做到这一点。但是,点击不会扩展正确的行。Android:只有我的ListView的最后一行响应OnClickListener

例子:

​​

出现这种情况我随时滚动,只有最后一排,在我的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事件做出反应?谢谢

+0

我会试试这个。尽管如此,它的确有一些类似的方法。由于我有两个布局,这意味着我必须用条件语句过滤每个方法,或者我必须为每个类型创建两个方法,即使它们执行相同的操作。 –

+0

是否在适配器类中持有引用?那通常工作不正常。而不是将视图持有人作为参考,为什么不通过你的函数?你知道每个列表视图只有一个适配器类的实例吗? – Bhargav

+0

@Bhargav是的,我只是认为这会更容易,然后通过每个功能。重构现在试试 –

RecyclerView,视图被回收。所以第一行的视图重新用于后面的行,它仍然是OnClickListener。您必须将每个onBindViewHolder()设置为中的听众。

+0

我相信我正在那样做。如果不是,请告诉我如何打破查看模式。 –

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

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