数据已更改但notifyDataSetChanged无法正常工作

时间:2017-02-06 14:05:32

标签: android android-fragments expandablelistadapter audio-player notifydatasetchanged android-music-player

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

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

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

这里是播放列表片段类的代码

    @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类的代码

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类中更改播放列表的数据。那么我如何以及在何处调用notifyDataSetChanged()方法?

1 个答案:

答案 0 :(得分:0)

var nodes = _administrationSystem.GetNodes(); //This code works fine var translators = _phonesSystem.GetPhoneNumberTranslators(); if (rptAdd.Items.Count > 0) { for (var count = 0; count < rptAdd.Items.Count; count++) { var ddlNode = (DropDownList)rptAdd.Items[count].FindControl("ddlNode"); var ddlTranslator = (DropDownList)rptAdd.Items[count].FindControl("ddlTranslator"); ddlNode.DataSource = nodes; ddlNode.DataTextField = "NodeName"; ddlNode.DataValueField = "ID"; ddlNode.DataBind(); ddlTranslator.DataSource = translators; ddlTranslator.DataTextField = "Description"; ddlTranslator.DataValueField = "ID"; ddlTranslator.DataBind(); } } if (rptList.Items.Count > 0) //This code does not work fine { for (var count = 0; count < rptList.Items.Count; count++) { var ddlNodeEdit = (DropDownList)rptList.Items[count].FindControl("ddlNodeEdit"); var ddlTranslatorEdit = (DropDownList)rptList.Items[count].FindControl("ddlTranslatorEdit"); var getNode = _administrationSystem.GetNode(userId, ddlNodeEdit.SelectedIndex + 1); var getTranslator = _phonesSystem.GetPhoneNumberTranslator(Convert.ToInt32(ddlTranslatorEdit.SelectedValue)); ddlNodeEdit.DataSource = getNode; ddlNodeEdit.DataTextField = "NodeName"; ddlNodeEdit.DataValueField = "ID"; ddlNodeEdit.DataBind(); ddlTranslatorEdit.DataSource = getTranslator; ddlTranslatorEdit.DataTextField = "Description"; ddlTranslatorEdit.DataValueField = "ID"; ddlTranslatorEdit.DataBind(); } } 用于通知适配器数据已更改。您在适配器/视图设置/创建时使用它,这没有任何意义。您应该做什么以及您可能缺少的是将所选歌曲添加到适配器的数据中,然后调用notifyDataSetChanged()方法

编辑:从OP

我试图实现一个监听器,但由于必须将消息从主活动发送到片段,所以无法使其工作。在我看来,没有办法实现它。

无论如何,所以我按照建议尝试了EventBus但是即使然后notifyDataSetChanged方法也没有工作,也没有通知notifyDataSetInvalidated。

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

notifyDataSetChanged()

我再次尝试了一下,看看如果删除了notify方法会发生什么,并且如果组视图被展开,则看到视图没有得到更新。当组视图折叠并再次展开时,它已更新。所以这里的notify方法确实有效,但只有在清除了视图之后。 当我没有清除视图时,通知方法不起作用。

<强>课 在调用notify方法之前,始终清除视图并注入新数据。也许在其他一些Android apis上你不需要清除视图,但我不认为任何人都应该抓住机会。我在Android api 19上测试过。