ArrayAdapter.NotifyDataSetChanged() 不工作?

Posted

技术标签:

【中文标题】ArrayAdapter.NotifyDataSetChanged() 不工作?【英文标题】:ArrayAdapter.NotifyDataSetChanged() is not working? 【发布时间】:2013-02-07 23:38:36 【问题描述】:

我有一个可由用户更新的列表,但notifyDataSetChanged() 不适用于与listView 关联的适配器。我在片段中使用它。数据库得到更新,但 adpater 没有。以下是我的实现:

我的主要片段:

public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    myArrayList = new ArrayList<myList>();
    myArrayList = Database.getSharedObject(getActivity()).getMyList();
    if (myArrayList != null && myArrayList.size() > 0) 
        adapter = new myListAdapter(getActivity(), 0, myArrayList);
    



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

    View v = inflater.inflate(R.layout.mainfragment, container, false);
    myListView = (ListView) v.findViewById(R.id.my_list_view);
    myListView.setOnItemClickListener(this);
    if (adapter != null) 
        myListView.setAdapter(adapter);
    

    return v;

在一些导航过程 List 得到更新后,在我的 onResume() 方法中,我从数据库中获取更新后的 List 并调用 notifyDatasetChanged() 方法,该方法不会更新我的视图,但是来自 DB 的相应数组会更新一个。

@Override
public void onResume() 
    super.onResume();
    myArrayList = Database.getSharedObject(getActivity()).getMyList();
    adapter.setItems (myArrayList);
    adapter.notifyDataSetChanged();


MyListAdapter

public class MyListAdapter extends ArrayAdapter<Message> 

    private ArrayList<Message> myList;

    /* Context */
    private Context context;

    public void setItems (ArrayList<Message> myList) 
        this.myList = myList;
    

    public MyListAdapter (Context context, int textViewResourceId, ArrayList<Message> myList) 
        super(context, textViewResourceId, myList);
        this.context = context;
        this.myList = myList;
    

    @Override
    public View getView (int position, View v, ViewGroup parent) 
        // Keeps reference to avoid future findViewById()
        MyViewHolder viewHolder;

        if (v == null) 
            LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = li.inflate(R.layout.list_row, parent, false);

            viewHolder = new MyViewHolder();
            viewHolder.txtImage = (ImageView) v.findViewById(R.id.message_icon);
            viewHolder.txtMessage = (TextView) v.findViewById(R.id.message);
            viewHolder.txtDate = (TextView) v.findViewById(R.id.date);

            v.setTag(viewHolder);
         else 
            viewHolder = (MyViewHolder) v.getTag();
        

        Message myMessage = new Message();
        myMessage = myList.get(position);
        if (myMessage != null) 
            viewHolder.txtMessage.setText(myMessage.getText());
            viewHolder.txtDate.setText(myMessage.getDate());
        
        return v;
    

    static class MyViewHolder 
        ImageView txtImage;
        TextView txtMessage;
        TextView txtDate;
    

对出了什么问题有任何想法吗?为什么列表视图没有更新?任何帮助表示赞赏。

【问题讨论】:

adapter.setItems是你自定义的方法吗? @Sean yes..这是自定义方法。 @blackbelt 我现在也添加了。 【参考方案1】:

notifyDataSetChanged() 不适合你。原因

    您的适配器丢失了对您列表的引用。 始终创建新列表并将其添加到适配器。这样做: 在全局声明时初始化 ArrayList。

ArrayList&lt;MyItemType&gt; myArrayList=new ArrayList&lt;&gt;(); // 作为全局变量

直接将List添加到适配器,不检查null和empty条件。直接将适配器设置为列表(不检查任何条件)

myListView.setAdapter(adapter);

    每次向 myArrayList 添加数据(如果您的数据是全新的,那么您可以在实际向列表添加数据之前调用 adapter.clear() 和 myArrayList.clear())但不要设置适配器 即如果新数据填充在 myArrayList 中,则只需 adapter.notifyDataSetChanged()

     adapter = new myListAdapter(getActivity(), 0, myArrayList);
    

    删除这一行

    adapter.setItems (myArrayList);

【讨论】:

总是提供新列表并不是一件好事,而不是@hovo888s 解决方案有效 @jayantsingh 3年前发表,现在不确定上下文...不过答案应该是根据问题的上下文来的。当我现在快速查看问题时,我可以看到他正在使用片段。当您切换片段时,您需要这样做,因为在它们之间切换时数据会丢失 我们可以有一个函数说 setItems() 它将更改列表(数据)并通知。所以只需调用该函数而不是重复定义 @jayantsingh 您应该将其发布为答案。如果您在初始化时有 setItems(list) 而不是发送列表,则必须调用 setItems(list) 而不是 notifyDataSetChanged()【参考方案2】:

只需覆盖 getCount 方法

    @Override
    public int getCount() 
        return myArrayList.count();
    

【讨论】:

拯救了我的一天。愚蠢的错误。谢谢。【参考方案3】:

在您的 setItems 方法中尝试清除旧的 ArrayList。

而不是这个:

public void setItems(ArrayList<Message> myList) 
this.myList = myList;

试试这个:

public void setItems(ArrayList<Message> myList) 
this.myList.clear();
this.myList.addAll(myList);
notifyDataSetChanged();

【讨论】:

【参考方案4】:

问题出在 MyListAdapter 的构造函数中

代替

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) 
    super(context, textViewResourceId, scheduledMessageList);
    this.context = context;
    this.myList = myList;

试试

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) 
    super(context, textViewResourceId, myList);
    this.context = context;
    this.myList = myList;

除了你自己的方法 setItems 你应该调用adapter.clear(); 后跟adapter.addAll(myArrayList);

【讨论】:

【参考方案5】:

如果您可以使用 notifyDataSetChanged() 但在适配器中! 在里面创建一个小方法

【讨论】:

我已经通过签名setItems(myArrayList)创建了

以上是关于ArrayAdapter.NotifyDataSetChanged() 不工作?的主要内容,如果未能解决你的问题,请参考以下文章