Android Adapter 的转换视图未更新
Posted
技术标签:
【中文标题】Android Adapter 的转换视图未更新【英文标题】:Android Adapter's convertview not updated 【发布时间】:2015-07-25 06:01:55 【问题描述】:我在 listview 的自定义适配器的 getView() 方法中发生了一些奇怪的事件。似乎缓存视图仅在应用程序结束时更新。我已经阅读了很多教程,但从未见过这样的问题。
当我将第一个项目添加到适配器时,一切都很好 - convertView 为空,我膨胀视图并返回它。但是,当我尝试添加第二个项目时,getView() 会发送完全相同的 convertView,用于位置 0 和 1(即使位置 1 应该为空),从而产生相同的项目。
重新启动应用后,每个添加的项目都可以正常查看(数据已序列化),但尝试添加更多项目仍会导致与第一个相同的视图。
我确定问题出在适配器 getView() 上,因为当我停止使用 convertView 并且每次都为项目充气时,它工作得非常好。
这就是我的方法的样子。 mNames 是向量;当它发生变化时,它会被序列化并通知适配器。此向量设置适配器计数(请参阅 getCount)。在传递给适配器之前,它在 onCreate() 中被反序列化。
@Override
public int getCount()
return mNames.size();
@Override
public View getView(int position, View convertView, ViewGroup parent)
if(convertView == null)
convertView = layoutInflater.inflate(R.layout.grouplist_listview_item, null);
//just saying, there are more subviews; I didn't find it relevant
((TextView)convertView.findViewById(R.id.grouplist_listview_item_text)).setText(mNames.elementAt(position));
return convertView;
所以这里有两点我不太明白:
为什么所有 getView() 调用都使用相同的 convertView? 为什么它们在应用启动期间没有这样发送,然后它可以工作?【问题讨论】:
将((TextView)convertView.findViewById(R.id.grouplist_listview_item_text)).setText(mNames.elementAt(position));
移到if之外
哇...那是快速和正确的。谢谢!
附带说明:每次运行 getView 时都执行 findViewById,这确实损害了这件事的性能。您应该使用 Viewholder 模式 (developer.android.com/training/improving-layouts/smooth-scrolling.html)。
哦,是的,忘了说,我知道;我只是不想使发布的示例复杂化。不过谢谢!
getview() 被调用来告诉适配器嘿需要在这个视图中这个位置需要什么。每次您想要触发它或显示新视图时都会触发它。我认为视图将是空的,直到适配器已满,然后它只是重用视图,根据其所在的位置更改其中的内容。
【参考方案1】:
我认为你需要阅读一个好的教程。我知道很好的网页@Using an ArrayAdapter with ListView。搜索“定义适配器”文本以查看 getView()
代码。
代码sn-p:
@Override
public View getView(int position, @Nullable View convertView, ViewGroup parent)
// Get the data item for this position
User user = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null)
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false);
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
// Populate the data into the template view using the data object
tvName.setText(user.name);
// Return the completed view to render on screen
return convertView;
注意:代码使用setText
方法。这将使用 ArrayAdapter 和您的布局测试您的代码。
【讨论】:
以上是关于Android Adapter 的转换视图未更新的主要内容,如果未能解决你的问题,请参考以下文章
Android开发之关于ListView中adapter调用notifyDataSetChanged无效的原因