【发布时间】:2016-03-20 19:42:30
【问题描述】:
我有一个带有 View Holder 的 ListView。当我在ListView 的某一行中按下一个按钮时,它应该在该位置展开该行并在我再次按下它时折叠。我在布局上使用显示/隐藏来做到这一点。但是,单击并未扩展正确的行。
示例:
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);
}
};
}
设置可见性
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 事件做出反应。谢谢
【问题讨论】:
-
我会试试这个。不过,它确实采用了一些类似的方法。由于我有两个布局,这意味着我必须使用条件语句过滤每个方法,或者我必须为每种类型创建两个方法,即使它们做同样的事情
-
你在你的适配器类中持有对持有者的引用吗?这通常不能很好地工作。与其将 viewholder 作为参考,为什么不将它传递给您的函数呢?您知道每个列表视图只有一个适配器类实例吗?
-
@Bhargav 是的,我只是认为通过每个函数传递它会更容易。现在重构试试
-
@Rah ty 你是对的
-
@Bhargav 它的工作原理是将其本地化并每次都通过它
标签: android listview android-listview onclicklistener