Android 正在ExpandableListView中更新子项
我有一个可扩展列表视图样式的购物车 我正在尝试更新子项的右侧可绘制图形。所有子项都以“+”开头,我希望单击时将其更改为“-”。 我尝试在适配器中执行此操作,但当我滚动列表并打开其他组选项卡时,我注意到以前未单击的项目中的项目也在被修改 我不确定我的适配器中是否存在视图回收问题,或者是否是其他原因导致了这一问题。这是我的密码: 自定义适配器getChildView方法Android 正在ExpandableListView中更新子项,android,expandablelistview,expandablelistadapter,Android,Expandablelistview,Expandablelistadapter,我有一个可扩展列表视图样式的购物车 我正在尝试更新子项的右侧可绘制图形。所有子项都以“+”开头,我希望单击时将其更改为“-”。 我尝试在适配器中执行此操作,但当我滚动列表并打开其他组选项卡时,我注意到以前未单击的项目中的项目也在被修改 我不确定我的适配器中是否存在视图回收问题,或者是否是其他原因导致了这一问题。这是我的密码: 自定义适配器getChildView方法 @Override public View getChildView(final int groupPositi
@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;
}
正在片段中设置适配器
(服务器下载后从asyncTask中的onPostExecute调用)
行视图被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;dr:您必须确保在适配器实现中更新依赖于行的数据模型的所有内容,否则龙将消耗我们所有人。这似乎已经成功了!我想弄明白为什么会发生这种事。我想知道为什么点击是随机的?我发现listview视图回收有点混乱。这很好。非常感谢您抽出时间为我提供一些关于这个话题的背景知识。
// set item name
fullMenuItemHolder.title.setText(getChild(groupPosition, childPosition).getVenue_item_name());