[完成]notifyDataSetChanged() 不会自动更新 ListActivity

Posted

技术标签:

【中文标题】[完成]notifyDataSetChanged() 不会自动更新 ListActivity【英文标题】:[done]notifyDataSetChanged() does not update ListActivity automatically 【发布时间】:2011-07-08 08:47:19 【问题描述】:

我在使用 BaseAdapter 的 notifyDataSetChanged() 时遇到了一些问题。此方法在 refreshItems() 中调用,并将更新我的 ListActivity 的 BaseAdapter。在调用 notifyDataSetChanged() 时,除非我使用箭头键向下滚动 ListView,否则不会发生任何事情。不知何故,修改后的 getView() 方法也没有被调用。也许你可以给我一个提示 - 谢谢! :)

public class WinampControlClientPlaylist extends ListActivity 

static WinampControlClientPlaylist activity = null;

static EfficientAdapter adapter = null;


static class EfficientAdapter extends BaseAdapter 


    public EfficientAdapter(Context context) 
        mInflater = LayoutInflater.from(context);
    

    private LayoutInflater mInflater;

    @Override
    public int getCount() 
        return Settings.playlistlength;
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 
        ViewHolder holder;


        if (convertView == null) 
        
            holder = new ViewHolder();

            convertView = mInflater.inflate(R.layout.listview, null);

            holder.text = (TextView) convertView.findViewById(R.string.playlist_title);
            holder.image = (ImageView) convertView.findViewById(R.string.playlist_play);

            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        


        holder.text.setText(Settings.playlist[position]);

        if (position == Settings.playlistPosition)
        
            holder.text.setTypeface(null, Typeface.ITALIC);
            holder.image.setVisibility(0);
        
        else
        
            holder.text.setTypeface(null, Typeface.NORMAL);
            holder.image.setVisibility(4);
        


        return convertView;
    


    static class ViewHolder 
        TextView text;
        ImageView image;
    

    @Override
    public Object getItem(int position) 
        return Settings.playlist[position];
    





void initialize()

    adapter = new EfficientAdapter(this);
    setListAdapter(adapter);

    //registerForContextMenu(getListView());



@Override
public void onResume()

    super.onResume();

    // REFRESH PLAYLIST
    if (getListAdapter() == null && Settings.playlist != null)
        initialize();


@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.playlist);

    activity = this;


static void refreshItems()

    try 
        adapter.notifyDataSetChanged();
     catch (Exception e) 


【问题讨论】:

好吧,也许我不明白你的问题,但是如果他们的数据集发生了变化,ListView 会更新,并且通知的方式是将 notifyDataSetChanged() 调用到 ListView。但是在这里我看不到你在哪里更改数据集,设置在其他线程或地方发生变化? 是的,另一个Activity调用Settings.playlistPosition = newNumber和WinampControlClientPlaylist.refreshItems();但是当这种情况发生时,ListView 不会更新。之后在模拟器中按向上/向下箭头时,我只会看到变化。 【参考方案1】:
Why it works in first code ?

---因为您将值设置为临时列表并将其传递给适配器并将其显示到列表视图中。

Why not work in second code ?

--- 因为您在将值设置为 temp 之前将 temp 设置为适配器 其次,当您将新值设置为 temp 时,您的适配器类可能无法获得更新的值。这是因为 temp 不是公共的或不在类级别或不是静态的。将 temp 声明放在根级别并尝试。

如果您收到任何警告,请尽可能多地显示您的完整代码和 Logcat。

【讨论】:

【参考方案2】:

这背后的主要原因是您调用 notifyDataSetChanged() 的适配器的错误引用;

我认为您需要确保只创建一次适配器对象并在同一对象上调用 notifyDataSetChanged()。

您可以在创建适配器对象时以及调用 notifyDataSetChanged() 方法时调试对象引用值。

【讨论】:

【参考方案3】:

我遇到了同样的问题,我尝试在适配器上调用notifyDataSetChanged()。此外,我还尝试在视图上调用refreshDrawableState()invalidateViews(),但这些都不起作用。所有这些方法都在 UI 线程中调用。然后我找到了这个How to clear the views which are held in the ListView's RecycleBin?。最后setAdapter() 工作,只有当我创建一个新的适配器。

【讨论】:

【参考方案4】:

在 BaseAdapter.notifyDataSetChanged() 之后在您的列表视图上调用 AbsListView.invalidateViews()

【讨论】:

【参考方案5】:

正如 Franco 所指出的,notifyDataSetChanged() 用于告诉ListView 其适配器的内容已更改,而不是它需要重绘自身。您只是在更改影响某些内容呈现方式的设置。尝试调用refreshDrawableState 告诉列表重绘。

【讨论】:

【参考方案6】:

我认为适配器可能存在一些问题; 可能没有设置。

根据我的经验,总是有某种原因阻止列表视图(和适配器)更新。

【讨论】:

不是真的 - 现在我有不想刷新的 ListActivity。有趣的是,如果在调试器中运行它会刷新而不是在本机运行......【参考方案7】:

我遇到了同样的问题(ListView 仅在我滚动时更新,甚至 notifyDataSetChanged 也无济于事)。我以这种方式解决它:只需尝试在创建用户界面的线程中进行“视图修改”,即

activity.runOnUiThread(new Runnable()          
        public void run() 
              //do your modifications here

              // for example    
              adapter.add(new Object());
              adapter.notifyDataSetChanged()  
        
);

【讨论】:

2天后得到了这个解决方案。谢谢@almaz_from_kazan先生【参考方案8】:

我遇到了同样的问题,我的解决方案是在 ListView 上调用 requestLayout()。

【讨论】:

【参考方案9】:

尝试在您的 ListView 上调用 invalidate()

【讨论】:

以上是关于[完成]notifyDataSetChanged() 不会自动更新 ListActivity的主要内容,如果未能解决你的问题,请参考以下文章

notifyDataSetChanged 示例

Android RecyclerView:notifyDataSetChanged() IllegalStateException

ArrayAdapter.NotifyDataSetChanged() 不工作?

notifyDataSetChanged() 上的 WinDeath

安卓:notifyDataSetChanged();不工作

在 customAdapter.notifyDataSetChanged 之后 ListView 不更新