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无效的原因

Android-12-Adapter数据适配器

按钮未显示在android的自定义列表视图中

Android 回收站视图更新

Android Paging 3 不显示 Loadstate Adapter

View(视图)——ListView概述Adapter分类