4 votes

RecyclerView n'affiche pas les éléments de la liste

J'ai essayé de créer un RecyclerView qui affiche les chansons que j'ai sur mon téléphone à partir d'une ArrayList pré-remplie. Voici le code de mon activité :

public class HomeActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private RecyclerView songRecyclerView;
private RecyclerView.Adapter songRecyclerAdapter;
private RecyclerView.LayoutManager recyclerLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    //get the songs list for the adapter
    ArrayList<Audio> songList;
    StorageUtils storageUtils = new StorageUtils(getApplicationContext());
    songList = storageUtils.loadAudio();

    //Recycler view setup for songs display
    songRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    songRecyclerView.setHasFixedSize(true);

    recyclerLayoutManager = new LinearLayoutManager(this);
    songRecyclerView.setLayoutManager(recyclerLayoutManager);

    songRecyclerAdapter = new SongAdapter(songList);
    songRecyclerView.setAdapter(songRecyclerAdapter);
}

La classe Audio possède les méthodes getTitle() et getArtist(), qui fonctionnent. La méthode loud audio() fonctionne également, donc Songlist contient certainement des éléments. Voici le xml de l'élément recyclerview :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recycler_item"
    android:layout_width="match_parent"
    android:layout_height="72dp"
    android:visibility="visible">
<TextView
    android:id="@+id/recycler_item_songName"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="8dp"
    android:text="song name"
    android:textColor="@color/textPrimary"
    android:textSize="16sp"
    android:textStyle="normal"
    android:visibility="visible"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/recycler_item_artistName"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="16dp"
    android:layout_marginStart="16dp"
    android:text="song artist"
    android:textColor="@color/textSecondary"
    android:textSize="16sp"
    android:textStyle="normal"
    android:visibility="visible"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/recycler_item_songName" />

</android.support.constraint.ConstraintLayout>

Voici mon implémentation de l'adaptateur :

package com.ecebuc.gesmediaplayer;

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {

    // The dataset
    private ArrayList<Audio> songList;

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView recyclerTitleView, recyclerArtistView;

        public ViewHolder(View itemView) {
            super(itemView);
            this.recyclerTitleView = (TextView) itemView.findViewById(R.id.recycler_item_songName);
            this.recyclerArtistView = (TextView) itemView.findViewById(R.id.recycler_item_artistName);
        }
    }

    // Constructor
    public SongAdapter(ArrayList<Audio> songList){
        this.songList = songList;
    }

    @Override
    public SongAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View listItemView = layoutInflater.inflate(R.layout.song_list_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(listItemView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Audio currentSong = songList.get(position);
        holder.recyclerTitleView.setText(currentSong.getTitle());
        holder.recyclerArtistView.setText(currentSong.getArtist());
        Log.d("onBind: ", (String)holder.recyclerTitleView.getText() + (String)holder.recyclerArtistView.getText());
    }

    @Override
    public int getItemCount() {
        return songList.size();
    }

}

Ce qui est frustrant, c'est que lors de ma toute première tentative de création de la recycleView, celle-ci a fonctionné et a affiché le texte. J'ai essayé d'ajouter une imageView comme couverture des chansons à la mise en page de chaque élément de la liste, et le code pour l'afficher également, et cela ne fonctionnait plus. Lorsque j'ai essayé de revenir en arrière et de n'avoir que le code pour le texte, cela a cessé de fonctionner complètement.

Je me casse la tête parce que si j'ai fait un petit changement quelque part, je ne sais plus où il se trouve maintenant. Mais j'ai essayé de recréer la classe de l'adaptateur et le fichier de mise en page pour l'ensemble de la fonctionnalité du recycleur à partir de zéro, et ça ne marche toujours pas. Les éléments de mise en page doivent être là car je vois l'ombre du rouleau.

De plus, dans le onBindViewHolder de l'adaptateur, ce Log.d affiche correctement chaque titre de chanson et artiste. Et il appelle le getText() des vues nouvellement créées. C'est comme si le texte était blanc. Et non, les valeurs de @color/text primary et textSecondary dans le XML sont #212121 et #424242 et ont toujours été comme ça (encore une fois, il a affiché les valeurs la première fois, et je n'ai pas touché aux couleurs).

J'ai cherché des problèmes similaires sur StackOverflow et en ligne, mais je ne semble pas avoir ce genre d'erreurs. Je ne sais plus quoi faire. Heck, je vais même inclure le XML de l'écran qui a le recyclerView réel en elle. À ce stade, je ne sais pas ce qui pourrait rendre ces vues invisibles :

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".HomeActivity"
    tools:showIn="@layout/app_bar_home">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Finalement, j'ai pensé à regarder les options du développeur sur mon téléphone et à afficher les contours de la mise en page, et voici ce que j'ai obtenu... comme si les deux textViews n'étaient pas créés, pourtant j'ai pu obtenir leur contenu textuel après l'avoir défini, alors comment est-ce possible ? Merci à tous ceux qui peuvent m'aider, j'essaie juste d'apprendre... Layout outlines

2voto

Emilian Cebuc Points 302

Pour référence future, au cas où quelqu'un aurait un problème similaire, j'ai réussi à le résoudre en changeant simplement la disposition de mes contraintes dans le XML de l'élément de vue du recycleur, en disposition linéaire (ou je suppose n'importe quel type de disposition autre que la contrainte) et en compilant.

Il a bien fonctionné, affichant tout correctement. Ensuite, j'ai changé le XML pour revenir à la mise en page par contrainte comme avant, et tout fonctionnait toujours bien. À ce stade, je dirais que cela restera à jamais un mystère.

0voto

Android Team Points 7530

Faites quelques changements dans le constructeur de l'adaptateur comme le code ci-dessous

    public Context context;
// Constructor
public SongAdapter(Context context,ArrayList<Audio> songList){
    this.context=context;
    this.songList = songList;
}

Ensuite, après l'activité principale, créez un objet adaptateur comme ci-dessous.

SongAdapter adapter;

et supprimez cette ligne de code .

private RecyclerView.Adapter songRecyclerAdapter;

et j'ai utilisé l'adaptateur comme le code ci-dessous

RecyclerView recyclerView;
SongAdapter songRecyclerAdapter;
private void setAdapter(){
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    if (songRecyclerAdapter==null) {
        songRecyclerAdapter = new SongAdapter(this,songList);
        recyclerView.setAdapter(songRecyclerAdapter);
        songRecyclerAdapter.notifyDataSetChanged();
    } 
    else{
        songRecyclerAdapter.notifyDataSetChanged();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X