ListView - ViewHolder 设计的错误回收行为
ListView - Wrong Recycling behavior with ViewHolder Design
描述:
我目前正在使用 ViewHolder 设计模式实现自定义 ListViewAdapter。适配器使用的布局带有一个切换 RelativeLayout 可见性的按钮。
问题:
当我单击按钮并显示 RelativeLayout 时,一切似乎都正常,直到我向下滚动。 当我向下滚动时,我看到其他列表项已受到上一个按钮单击的影响,因此 RelativeLayout 在其他(错误的)项目上可见。 受按钮单击影响的项目似乎是我向下滚动时回收的那个。请注意,其他一切正常,文本等设置在正确的位置。
代码:
自定义列表适配器
public class ItemsListAdapter extends ArrayAdapter<Item> {
private Context mContext;
private List<Item> mItems;
public ItemsListAdapter(Context context, int resource, List<Item> objects) {
super(context, resource);
mContext = context;
mItems = objects;
}
static class ViewHolder {
View mView;
boolean mExpanded;
public ViewHolder(View view, boolean expanded)
{
mView = view;
mExpanded = expanded;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(holder.mExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
final ImageButton ibExpand = (ImageButton) holder.mView.findViewById(R.id.ib_expand);
ibExpand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if (rlExpand.getVisibility() == View.GONE) {
v.setVisibility(View.INVISIBLE);
rlExpand.setVisibility(View.VISIBLE);
holder.mExpanded = true;
}
}
});
ImageButton ibCollapse = (ImageButton) holder.mView.findViewById(R.id.ib_collapse);
ibCollapse.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
ibExpand.setVisibility(View.VISIBLE);
rlExpand.setVisibility(View.GONE);
holder.mExpanded = false;
}
});
}
return v;
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Truism getItem(int position) {
return mItems.get(position);
}
非常感谢任何帮助!提前致谢!
尝试改变:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(item.isExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
[...]
}
return v;
}
将holder.mExpanded
更改为item.isExpanded
描述:
我目前正在使用 ViewHolder 设计模式实现自定义 ListViewAdapter。适配器使用的布局带有一个切换 RelativeLayout 可见性的按钮。
问题:
当我单击按钮并显示 RelativeLayout 时,一切似乎都正常,直到我向下滚动。 当我向下滚动时,我看到其他列表项已受到上一个按钮单击的影响,因此 RelativeLayout 在其他(错误的)项目上可见。 受按钮单击影响的项目似乎是我向下滚动时回收的那个。请注意,其他一切正常,文本等设置在正确的位置。
代码:
自定义列表适配器
public class ItemsListAdapter extends ArrayAdapter<Item> {
private Context mContext;
private List<Item> mItems;
public ItemsListAdapter(Context context, int resource, List<Item> objects) {
super(context, resource);
mContext = context;
mItems = objects;
}
static class ViewHolder {
View mView;
boolean mExpanded;
public ViewHolder(View view, boolean expanded)
{
mView = view;
mExpanded = expanded;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(holder.mExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
final ImageButton ibExpand = (ImageButton) holder.mView.findViewById(R.id.ib_expand);
ibExpand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if (rlExpand.getVisibility() == View.GONE) {
v.setVisibility(View.INVISIBLE);
rlExpand.setVisibility(View.VISIBLE);
holder.mExpanded = true;
}
}
});
ImageButton ibCollapse = (ImageButton) holder.mView.findViewById(R.id.ib_collapse);
ibCollapse.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
ibExpand.setVisibility(View.VISIBLE);
rlExpand.setVisibility(View.GONE);
holder.mExpanded = false;
}
});
}
return v;
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Truism getItem(int position) {
return mItems.get(position);
}
非常感谢任何帮助!提前致谢!
尝试改变:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(item.isExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
[...]
}
return v;
}
将holder.mExpanded
更改为item.isExpanded