数据已更改但 notifyDataSetChanged 不起作用

Data has changed but notifyDataSetChanged not working

我正在尝试构建一个音乐播放器。 我有一个名为 MusicData 的 class,它提供播放列表数据,另一个 class 用于播放列表片段,因为我使用的是 viewpager。 播放列表片段使用自定义 expandableListAdapter class.

加载数据

现在的问题是这样的。当用户点击一首歌曲时,它应该被添加到最近播放的播放列表中,这应该反映在播放列表片段中。 基础数据确实发生了变化,因为当我点击播放列表中的第一首歌曲时,它确实播放相同但包含歌曲标题的视图没有改变

因此问题本质上是视图没有反映底层数据。我试图将 notifyDataSetChanged 方法放在播放列表片段 class 中,但它不起作用。该怎么办?

这是播放列表片段的代码class

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.playlist, container, false);
    expandableListView = (ExpandableListView)v.findViewById(R.id.expandableListViewPlaylist);
    Log.e(TAG,"1");
    expandableListTitle = new ArrayList<>(MusicData.getExpandableListDetailPlayList().keySet());
    expandableListAdapter = new CustomExpandableListAdapter(this.getContext(), expandableListTitle, MusicData.getExpandableListDetailPlayList());
    expandableListView.setAdapter(expandableListAdapter);
    expandableListAdapter.notifyDataSetChanged();
    .......

这是 MusicData 的代码 class

public static LinkedHashMap<String, ArrayList<Song>> getExpandableListDetailPlayList(){return expandableListDetailPlayList;}

这是适配器

public class CustomExpandableListAdapter extends BaseExpandableListAdapter {

private Context context;
private ArrayList<String> expandableListTitle;
private LinkedHashMap<String, ArrayList<Song>> expandableListDetail;
private String TAG = "AdapterClass";
public CustomExpandableListAdapter(Context context, ArrayList<String> expandableListTitle,
                                   LinkedHashMap<String, ArrayList<Song>> expandableListDetail) {
    this.context = context;
    this.expandableListTitle = expandableListTitle;
    this.expandableListDetail = expandableListDetail;

}

@Override
public Object getChild(int listPosition, int expandedListPosition) {
    return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
            .get(expandedListPosition);
}

@Override
public long getChildId(int listPosition, int expandedListPosition) {
    return expandedListPosition;
}
......    

MainActivity 中的播放列表数据已更改 class。那么如何以及在何处调用 notifyDataSetChanged() 方法?

notifyDataSetChanged()用于通知适配器数据已经改变。您在 adapter/view setup/creation 处使用它,这没有任何意义。您应该做的以及您可能遗漏的是将所选歌曲添加到 适配器 的数据中,然后调用 notifyDataSetChanged() 方法

编辑:来自 OP

我试图实现一个侦听器,但无法让它工作,因为消息必须从主 activity 发送到片段,在我看来没有办法做到这一点。

无论如何,所以我按照建议尝试了 EventBus,但即便如此,notifyDataSetChanged 方法也不起作用,notifyDataSetInvalidated 也不起作用。

最终我不得不在适配器中编写另一个函数 class 以清除视图并设置新数据。我从播放列表片段中调用了这个函数。这是代码

    public void refresh(ArrayList<String> expandableListTitle,
                    LinkedHashMap<String, ArrayList<Song>> expandableListDetail){
    this.expandableListDetail.clear();
    this.expandableListTitle.clear();
    this.expandableListDetail.putAll(expandableListDetail);
    this.expandableListTitle.addAll(expandableListTitle);
    this.notifyDataSetChanged();
    }

我再次进行了一些实验,看看如果删除通知方法会发生什么,并且发现如果展开组视图,视图不会更新。当组视图折叠并再次展开时,它会更新。所以这里的通知方法确实有效,但只有在清除视图之后。 当我没有清除视图时,通知方法不起作用。

课程 在调用通知方法之前始终清除视图并注入新数据。也许在其他一些 Android api 上你不需要清除视图和所有但我认为任何人都不应该冒险。我在 Android api 19.

上测试过