我有一个ExpandableListView样式的购物车。
我正在尝试更新子项的正确可绘制图形。所有子项开始时都显示一个“ +”,我希望在单击时将其更改为“-”。
我尝试在适配器中执行此操作,但是当我滚动浏览列表并打开其他组选项卡时,我注意到那些以前未单击的项目中的项目也正在被修改。
我不确定适配器中的视图回收是否存在问题,或者是否有其他原因导致此问题。这是我的代码:
自定义适配器getChildView方法
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View childView, ViewGroup parent) {
final View row;
final FullMenuItemHolder fullMenuItemHolder;
if (childView == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.full_menu_child_item, parent, false);
fullMenuItemHolder = new FullMenuItemHolder(row);
row.setTag(fullMenuItemHolder);
}
else {
row = childView;
fullMenuItemHolder = (FullMenuItemHolder) row.getTag();
}
// set item name
fullMenuItemHolder.title.setText(getChild(groupPosition, childPosition).getVenue_item_name());
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//check to see if item flagged as added to cart and set the respective drawable image
if (!getChild(groupPosition,childPosition).getAddedToCart()) {
getChild(groupPosition,childPosition).setAddedToCart(true);
fullMenuItemHolder.title.setCompoundDrawablesWithIntrinsicBounds(null, null, fragment.getResources().getDrawable(R.drawable.remove), null);
} else {
getChild(groupPosition,childPosition).setAddedToCart(false);
fullMenuItemHolder.title.setCompoundDrawablesWithIntrinsicBounds(null, null, fragment.getResources().getDrawable(R.drawable.add), null);
}
}
});
return row;
}
在Fragment中设置适配器 (服务器下载后从asyncTask中的onPostExecute调用)
fullMenuExpListAdapter = new FullMenuExpListAdapter(this.getActivity(), listHeaderNames, listChildItems, this);
expandableListView.setAdapter(fullMenuExpListAdapter);
ListView可以重新使用行视图,这就是为什么单击看起来会更改多行的原因。如果您要稍微摆动一下列表,您还会注意到加号/减号实际上是随机的,之前单击过的哪个都无所谓。
在此行之后,您应手动更新复合可绘制对象,类似于OnClickListener:
// set item name
fullMenuItemHolder.title.setText(getChild(groupPosition, childPosition).getVenue_item_name());
这样可以确保新行和重用行均显示正确的图标。
(我对您的评论的回复太长了。)
实际上,这个问题没有任何随机性,对我来说,这只是一个捷径。:)
这样想:将最后一个像素滚动出来时,任何完全离开屏幕的行都会扔到回收堆上。它保持原样-没有子视图会自动清除或修改。
当新行进入屏幕时,ListView首先检查堆中是否有剩余的(所需视图类型)。如果找到,则您的适配器将有一次机会用新数据更新所有内容。如果您忘记更新任何内容,则将留下较早项目的剩余内容-例如原始问题中的可绘制对象。
但是请记住,这不仅适用于视觉状态,还适用于行为!
如果您没有创建新OnClickListener
实例(例如,将代码放在if
上面),则groupPosition
和childPosition
不会与初始值发生变化,因此单击一行可能会更新完全不同的模型对象!即使UI看起来似乎正确,但该模型还是不一致的。
将视图更新逻辑从适配器移动到ViewHolder,并为它提供一个bindModel(ChildType child)
设置标题,侦听器等的单一方法,可能会很有用。读取和验证每次正确设置所有内容都更加容易。
(新的RecyclerView的工作原理与此类似,您应该进行查找。)
TL;博士:你必须确保你的适配器实现以更新一切依赖于该行的数据模型,或龙会消耗我们所有人。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句