web-dev-qa-db-fra.com

RecyclerView n'appelle pas onCreateViewHolder ou onBindView

Ne pas obtenir d'erreurs et toutes les données semblent valables. Pour une raison quelconque, les méthodes associées aux vues sont appelées. Je me suis assuré de ce qui suit:

  • getItemCount () est la seule méthode d'adaptateur appelée et renvoie une valeur entière positive (je sais que ce sera la zone que vous examinerez)

    • Le constructeur est appelé, les variables membres sont valides.

    • La vue parente est un LinearLayout vertical; aucune vue de défilement, ou toute autre vue avec leurs propres propriétés de défilement en vue.

    • contenant la vue fragmentée est créé et affiché à l’écran.

Voici la déclaration dans le fragment suivie par l'adaptateur. Toute aide serait appréciée, car cela a été complètement dérouté.

SubMenuAdapter adapter = new SubMenuAdapter(getActivity(), mContentItems);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(adapter);
public class SubMenuAdapter extends RecyclerView.Adapter<SubMenuAdapter.ViewHolder> {
private static final String TAG = String.format("==> %S", SubMenuAdapter.class.getSimpleName());

private final List<ContentItem> mContentItems;
private Context mContext;

public SubMenuAdapter(Context context, List<ContentItem> contenItems) {
    Log.d(TAG, "Constructor called");
    mContentItems = contenItems;
    mContext = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Log.d(TAG, "onCreateViewHolder called");
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_resource_efficiency, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Log.d(TAG, "onBindViewHolder called");

    ContentItem item = mContentItems.get(position);
    holder.textName.setText(item.getName());
    FontSetter.setMyriadProRegular(mContext, holder.textName);
    Picasso.with(mContext).load("file://" + item.getPreviewImageDefault()).into(holder.imageIcon);
}

@Override
public int getItemCount() {
    Log.d(mContext, String.format("getItemCount: %d", mContentItems.size()));
    return mContentItems.size();
}

// ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {

    TextView textName;
    ImageView imageIcon;

    public ViewHolder(View view) {
        super(view);
        textName = (TextView) view.findViewById(R.id.tv_resource_efficiency_option);
        imageIcon = (ImageView) view.findViewById(R.id.iv_resource_efficiency_icon);
    }
}
47
Conti

Cela peut aussi aider quelqu'un

Première utilisation

recyclerView.setAdapter(adapter);

Et alors:

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

Donc ça va ressembler à ça:

recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

L'ordre est inversé

74
Aerim

Je cherche la réponse depuis plus d'une heure. 

N'oubliez pas d'appeler cette ligne avant de régler votre adaptateur.

recyclerView.setLayoutManager(new LinearLayoutManager(this));

Il semble que la vue Recycler n’ait pas d’option de gestionnaire de disposition par défaut intégrée;.

Bravo si vous l'avez trouvé utile.

26
ralphgabb

Assurez-vous de recycler la vue n'est pas enfant de nestedscrollview

par exemple, ce code ne fonctionnera pas. 

<Android.support.v4.widget.NestedScrollView
    Android:id="@+id/responder_scroll"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@color/darkGray"
    Android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <Android.support.v7.widget.CardView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_marginTop="24dp"
            app:cardElevation="@dimen/spacing_medium"
            app:cardUseCompatPadding="true">

            <RelativeLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content">

                <TextView
                    Android:id="@+id/responder_testimonial"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_alignParentTop="true"
                    Android:text="Testimonial"
                    Android:textSize="@dimen/general_font_size" />

                <TextView
                    Android:id="@+id/responder_counter_testimonial"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_toRightOf="@+id/responder_testimonial"
                    Android:text="170"
                    Android:textSize="@dimen/general_font_size_small" />

                <Button
                    Android:id="@+id/responder_btn_testimonial"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_alignParentRight="true"
                    Android:layout_alignParentTop="true"
                    Android:text="Go" />

               <view
                    Android:id="@+id/responder_list_testimonial"
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:layout_below="@+id/responder_testimonial"
                    class="Android.support.v7.widget.RecyclerView"/>
            </RelativeLayout>
        </Android.support.v7.widget.CardView>

    </FrameLayout>
</Android.support.v4.widget.NestedScrollView>

alors j'utilise,

<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">

<view
    Android:id="@+id/responder_list_testimonial"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_below="@+id/responder_testimonial"
    class="Android.support.v7.widget.RecyclerView"/>

19
raditya gumay

Je ne sais pas si cela sera utile à quiconque, mais j'ai presque eu exactement le même problème… .. Mon problème n'était pas dans la classe fragment/class ni dans l'adaptateur de recycleur. Le problème était dans la présentation XML parente où la barre d’action utilisait match_parent, où la FrameLayout -dans laquelle le fragment est remplacé- n’a obtenu aucun emplacement disponible à afficher. C'est pourquoi les méthodes n'ont pas été appelées.

Je suppose que des scénarios similaires pourraient être le cas pour ceux confrontés au même problème. Vérifiez à nouveau que chaque largeur et hauteur de chaque fichier XML se trouvent dans la même arborescence, car le problème ne semble pas résulter de l'adaptateur.

11
Abdul-Rahman Ahmad

Mes deux sous ici. Je viens de passer plus de trois heures à déboguer cela.

Assurez-vous que vous n'avez pas utilisé la ligne suivante de manière négligente.

recyclerView.setHasFixedSize(true);

Définissez la taille fixe uniquement lorsque vous êtes sûr que la vue aura une taille constante . Dans le cas contraire, les méthodes onCreateViewHolder et onBindView pourraient ne pas être appelées du tout.

7
Venkatesh Shukla

J'avais aussi le même problème où la méthode onCreateViewHolder ou onBindView n'était pas appelée, mais seulement getItemCount. Il s’agissait donc essentiellement d’un problème de hauteur et de poids de RecyclerView qui avait été défini sur wrap_content ou 0dp. Après avoir changé à une certaine valeur résolu le problème.

4
Vijay Pal

C’est déjà très vieux, mais dans mon cas, j’utilisais une variable ConstraintLayout et la hauteur était incorrecte; mon affichage aurait donc 0dp et l’adaptateur enregistrerait pour faire son travail, car la vue est 0dp.

Assurez-vous que la hauteur et la largeur sont correctes et que RecyclerView a une taille positive.

2
Rafael Ruiz Muñoz

Si vous définissez wrap_content comme hauteur de votre liste et de celle de votre liste d'éléments, rien ne s'affiche et aucune de vos fonctions recyclerView ne sera appelée.

2
Meriam

Dans mon cas, il utilisait setHasStableIds (true); dans l'adaptateur alors que certains éléments de la liste renvoyaient -1 dans getItemID (), je suppose donc que RecyclerView pensait qu'ils étaient égaux.

1
David

Je sais que ce sujet est ancien, mais si vous commettez la même erreur d’apprentissage, comme moi, vous trouverez peut-être cela utile.

Alors que j'étudiais sur un site Web sur RecyclerView et sur la copie de code et l'adaptation à mon contexte, j'ai créé différentes variables (utilisateurs et données, par exemple) destinées à faire la même chose, sauf que certaines méthodes appelaient des données et d'autres appelaient des utilisateurs. . C'est une erreur facile à faire lorsque vous essayez de comprendre le code d'autrui et les fonctionnalités Java (cela m'arrive tout le temps). 

Il est bon de savoir que vous pouvez imprimer dans votre console n'importe où dans votre code Java, afin de pouvoir déboguer comme cela assez facilement. 

Bonne chance!

1
bemihai22

Lorsque vous implémentez FirebaseListAdapter, vous devez prendre en compte les points suivants pour le configurer correctement.

  1. Vérifiez si recyclerview en xml a tous les attributs corrects. N'utilisez pas le contenu enveloppant pour la hauteur et la largeur, par exemple.
  2. Veuillez vérifier si layoutManager est défini et que setHasFixedSize () est pris en charge.
  3. Créez des variables de classe POJO afin qu'elles correspondent aux attributs enfant de Firebase.
  4. FirebaseRecyclerOptions est configuré.
  5. OnCreateViewHolder () et onBindViewHolder de FirebaseRecyclerAdapter sont là.
  6. Les événements du cycle de vie sont pris en charge.

Remarque- Utiliser wrap_content comme hauteur de recyclerview est l'une des erreurs les plus simples que quelqu'un puisse faire. Alors, vérifiez cela en premier.

1
Prashant Paliwal

Dans mon cas, j'ai défini l'ID de mon RecyclerView sur "recyclerView". Il semble que cet ID ait déjà été défini quelque part, car lorsque j'ai changé pour un autre ID, les méthodes de l'adaptateur ont été appelées correctement.

Lien vers la réponse

0

Faites attention au fil que vous utilisez avec l'adaptateur.
Dans mon cas, le problème consistait à appeler notifyDataSetChanged() depuis une activité lorsque mes données provenaient d’un service. En fait, la méthode appelait depuis le fil d’arrière-plan. Mais l'application ne s'est pas bloquée et il n'y avait rien dans Logcat (!).
Je me suis donc appelé notifyDataSetChanged() dans le fil de l'interface utilisateur et le problème a été résolu.

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        adapter.notifyDataSetChanged();
    }
});
0
Seyyed

J'ai récemment rencontré ce problème et apparemment, il existe de nombreuses causes possibles. Essayez une ou plusieurs de ces options et voyez laquelle vous convient (s) :)

1. Gestionnaire de mise en page
Assurez-vous de définir un gestionnaire de disposition sur votre vue recycleur comme indiqué ci-dessous

// create a layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(my_context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

// get recycler view
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
// set
recyclerView.setLayoutManager(linearLayoutManager);

2. Taille fixe
Assurez-vous d'indiquer si votre vue du recycleur a une taille fixe ou non

// set fixed size
recyclerView.setHasFixedSize(true); // or false depending on implementation

3. XML
Assurez-vous que votre recycleur n'est pas imbriqué dans un trop grand nombre de dispositions, ce qui peut créer une confusion, telle qu'une combinaison de ScrollView et de RelativeLayout. Faites-le simple, voyez si cela résout votre problème

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">

<Android.support.v7.widget.RecyclerView
Android:id="@+id/thread_list"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</LinearLayout>
0
Jonathan Kibet

Dans mon cas, a avait Fragment avec RecyclerView à l'intérieur de ViewPager. Le problème est apparu parce que j'ai utilisé Fragment.getFragmentManager() au lieu de Fragment.getChildFragmentManager pour le constructeur de ma FragmentStatePagerAdapter.

P.S. Utiliser Layout Inspector peut être d'une grande aide pour résoudre ce type de problème.

0
Daniil

J'ai eu ce même problème où ni onCreateViewHolder ni onBindViewHolder n'étaient appelés. Changer votre méthode onCreateViewHolder pour utiliser le contexte auquel vous avez enregistré une référence dans le constructeur au lieu de faire parent.getContext () devrait résoudre ce problème:

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Log.d(TAG, "onCreateViewHolder called");
    View view = LayoutInflater.from(mContext).inflate(R.layout.row_resource_efficiency, parent, false);
    return new ViewHolder(view);
0
dpspae03

Dans mon cas, après avoir remplacé Activity par ViewModel et utilisé Binding, j'avais oublié de supprimer la méthode setContentView de onCreate. En le supprimant, mon problème est résolu.

0
Siamak Ferdos