0

J'essaye de construire un lecteur de musique. J'ai une classe appelée MusicData qui fournit des données de playlist et une autre classe pour le fragment de playlist puisque j'utilise viewpager. Le fragment de playlist charge les données à l'aide d'une classe expandableListAdapter personnalisée.Les données ont changé mais notifyDataSetChanged ne fonctionne pas

Maintenant, le problème est le suivant. Lorsque l'utilisateur clique sur une chanson, elle devrait être ajoutée à la liste de lecture récemment lue et cela devrait se refléter dans le fragment de la liste de lecture. Les données sous-jacentes changent car lorsque je clique sur la première chanson de la playlist, elle joue la même chose mais la vue, qui contient le titre de la chanson, ne change pas

Par conséquent, le problème est essentiellement que les vues ne ne reflète pas les données sous-jacentes. J'ai essayé de placer la méthode notifyDataSetChanged dans la classe de fragment de liste de lecture, mais cela ne fonctionne pas. Que faire?

Voici le code pour la classe de fragments de playlist

@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(); 
    ....... 

Et ce code est pour la classe MusicData

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

Et ceci est l'adaptateur

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; 
} 
......  

Les données de la liste de lecture est modifiée dans la classe MainActivity. Alors, comment et où j'appelle la méthode notifyDataSetChanged()?

+0

Veuillez partager la partie du code qui gère le clic de l'utilisateur et ajoute ce morceau à la liste en conséquence –

+0

où dois-je appeler la méthode notifyDataSetChanged()? après que vos données ont changé –

Répondre

0

notifyDataSetChanged() est utilisé pour indiquer à l'adaptateur que les données ont été modifiées. Vous l'utilisez à la configuration de l'adaptateur/vue, ce qui n'a aucun sens. Ce que vous devez faire et ce que vous êtes probablement manquant est d'ajouter la chanson sélectionnée aux données de l'adaptateur , puis en appelant la méthode notifyDataSetChanged()

EDIT: OP DE

J'ai essayé de mettre en œuvre un auditeur mais ne pouvait pas le faire fonctionner puisque le message devait être envoyé de l'activité principale au fragment et il me semble qu'il n'y a aucun moyen de le faire.

Quoi qu'il en soit, j'ai donc essayé EventBus comme suggéré mais même alors, la méthode notifyDataSetChanged ne fonctionnait pas, ni notifyDataSetInvalidated.

Finalement, j'ai dû écrire une autre fonction dans la classe de l'adaptateur qui a effacé les vues et définir de nouvelles données. J'ai appelé cette fonction du fragment Playlist. Voici le code

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(); 
    } 

Encore une fois, j'expérimente un peu pour voir ce qui est arrivé si la méthode est retirée notification et vu que les vues ne sont mis à jour si la vue du groupe est élargi. Il a été mis à jour lorsque la vue de groupe a été réduite et étendue à nouveau. Donc ici, notifier la méthode a fonctionné mais seulement après avoir effacé les vues. Lorsque je n'ai pas effacé les vues, la méthode de notification n'a pas fonctionné.

LESSON Toujours effacer les vues et injecter de nouvelles données avant d'appeler la méthode de notification. Peut-être que sur d'autres apis Android, vous n'avez pas besoin d'effacer les vues et tout, mais je ne pense pas que quiconque devrait prendre une chance. J'ai testé sur Android api 19.

+0

voir le problème est que les données sont modifiées dans l'activité principale. la classe de fragments est uniquement à des fins de visualisation et de définition de l'adaptateur. donc comment saurai-je quand appeler la méthode notify? Autant que je puisse comprendre je devrais probablement implémenter dataSetObserver mais je ne sais pas comment faire cela –

+0

Vous pouvez utiliser un eventbus ou une interface pour communiquer entre l'activité et le fragment. Ces deux méthodes vous fourniront un moyen de dire au fragment de faire quelque chose de l'activité https://developer.android.com/training/basics/fragments/communicating.html https://github.com/greenrobot/ EventBus –

+0

Merci d'avoir suggéré eventbus. qui a aidé @howdoidothis –