web-dev-qa-db-fra.com

recyclerview Pas d'adaptateur attaché; sauter la mise en page

Je viens d’implémenter Recyclerview dans mon code, en remplacement de Listview.

tout fonctionne bien. Les objets sont affichés.

mais logcat dit

15: 25: 53.476 E/RecyclerView ﹕ Pas d'adaptateur fixé; sauter la mise en page

15: 25: 53.655 E/RecyclerView ﹕ Pas d'adaptateur fixé; sauter la mise en page

pour le code

ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

Comme vous pouvez le voir, j'ai connecté un adaptateur pour Recycleview .

j'ai lu d'autres questions liées au même problème, mais aucune aide.

177
equitharn

Pouvez-vous vous assurer que vous appelez ces instructions à partir du fil "principal" (par exemple, dans la méthode onCreate()) . Dès que j'appelle les mêmes instructions à partir d'une méthode "retardée" Dans mon cas, une ResultCallback, je reçois le même message.

Dans ma Fragment, appeler le code ci-dessous à partir d'une méthode ResultCallback génère le même message. Après avoir déplacé le code vers la méthode onConnected() dans mon application, le message avait disparu ...

LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
194
Peter

Je recevais les deux mêmes messages d'erreur jusqu'à ce que je corrige deux choses dans mon code: 

(1) Par défaut, lorsque vous implémentez des méthodes dans le RecyclerView.Adapter, il génère:

@Override
public int getItemCount() {
    return 0;
}

Assurez-vous de mettre à jour votre code afin qu'il indique:

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

Évidemment, si vous n'avez aucun article dans vos articles, vous n'aurez rien affiché à l'écran.

(2) Je ne faisais pas cela comme indiqué dans la réponse du haut: CardView layout_width = "match_parent" ne correspond pas à parent RecyclerView width

//correct
LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_listitem, parent, false);

//incorrect (what I had)
LayoutInflater.from(parent.getContext())
        .inflate(R.layout.card_listitem,null);

(3) EDIT: BONUS: Assurez-vous également de configurer votre RecyclerView comme ceci:

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/RecyclerView"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    />

Pas comme ça:

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

J'ai vu des tutoriels utilisant cette dernière méthode. Bien que cela fonctionne, je pense que cela génère aussi cette erreur. 

35
Micro

J'ai la même situation avec vous, l'affichage est correct, mais une erreur apparaît dans le locat ..__ C'est ma solution: (1) Initialisez l'adaptateur RecyclerView & bind sous CREATE ()

RecyclerView mRecycler = (RecyclerView) this.findViewById(R.id.yourid);
mRecycler.setAdapter(adapter);

(2) appelez notifyDataStateChanged lorsque vous obtenez les données

adapter.notifyDataStateChanged();

Dans le code source de recyclerView, il existe un autre thread pour vérifier l'état des données.

public RecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.mObserver = new RecyclerView.RecyclerViewDataObserver(null);
    this.mRecycler = new RecyclerView.Recycler();
    this.mUpdateChildViewsRunnable = new Runnable() {
        public void run() {
            if(RecyclerView.this.mFirstLayoutComplete) {
                if(RecyclerView.this.mDataSetHasChangedAfterLayout) {
                    TraceCompat.beginSection("RV FullInvalidate");
                    RecyclerView.this.dispatchLayout();
                    TraceCompat.endSection();
                } else if(RecyclerView.this.mAdapterHelper.hasPendingUpdates()) {
                    TraceCompat.beginSection("RV PartialInvalidate");
                    RecyclerView.this.eatRequestLayout();
                    RecyclerView.this.mAdapterHelper.preProcess();
                    if(!RecyclerView.this.mLayoutRequestEaten) {
                        RecyclerView.this.rebindUpdatedViewHolders();
                    }

                    RecyclerView.this.resumeRequestLayout(true);
                    TraceCompat.endSection();
                }

            }
        }
    };

Dans le dispatchLayout (), nous pouvons trouver qu'il y a une erreur:

void dispatchLayout() {
    if(this.mAdapter == null) {
        Log.e("RecyclerView", "No adapter attached; skipping layout");
    } else if(this.mLayout == null) {
        Log.e("RecyclerView", "No layout manager attached; skipping layout");
    } else {
19
Keith Gong

1) Créer ViewHolder cela ne fait rien :)

// SampleHolder.Java
public class SampleHolder extends RecyclerView.ViewHolder {
    public SampleHolder(View itemView) {
        super(itemView);
    }
}

2) Créez à nouveau RecyclerView cela ne fait rien :)

// SampleRecycler.Java
public class SampleRecycler extends RecyclerView.Adapter<SampleHolder> {
    @Override
    public SampleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(SampleHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

3) Lorsque votre véritable recycleur n’est pas prêt, utilisez simplement l’échantillon ci-dessous.

RecyclerView myRecycler = (RecyclerView) findViewById(R.id.recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
myRecycler.setAdapter(new SampleRecycler());

Ce n'est pas la meilleure solution, mais cela fonctionne! J'espère que c'est utile.

9
Madan Sapkota

j'ai ce problème, quelques problèmes de temps est recycleView mis dans ScrollView object

Après vérification de la mise en œuvre, la raison semble être la suivante. Si RecyclerView est placé dans un objet ScrollView, sa hauteur n'est pas spécifiée pendant l'étape de mesure (car ScrollView autorise toutes les hauteurs) et, par conséquent, est égale à la hauteur minimale (selon l'implémentation) qui est apparemment nulle.

Vous avez deux options pour résoudre ce problème:

  1. Définir une certaine hauteur sur RecyclerView
  2. Définissez ScrollView.fillViewport sur true
  3. Ou gardez RecyclerView en dehors de ScrollView. À mon avis, c'est de loin la meilleure option. Si la hauteur de RecyclerView n’est pas limitée - ce qui est le cas lorsqu’elle est placée dans ScrollView -, toutes les vues de l’adaptateur ont suffisamment d’emplacement vertical et sont créées en une seule fois. Il n'y a plus de recyclage de vues, ce qui brise un peu l'objectif de RecyclerView.

(Peut être suivi pour Android.support.v4.widget.NestedScrollView également)

9
FxRi4

Cela se produit lorsque vous ne configurez pas l'adaptateur pendant la phase de création:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    ....
}

public void onResume() {
    super.onResume();
    mRecyclerView.setAdapter(mAdapter);
    ....
}

Il suffit de déplacer la configuration de l'adaptateur dans onCreate avec des données vides et lorsque vous avez l'appel de données

mAdapter.notifyDataSetChanged();
6
Peter File

Assurez-vous de définir le gestionnaire de disposition pour votre RecyclerView en: 

mRecyclerView.setLayoutManager(new LinearLayoutManager(context));

Au lieu de LinearLayoutManager, vous pouvez également utiliser other gestionnaires de disposition.

3
Sumit Jha

Cela se produit car la disposition réellement gonflée est différente de celle que vous avez référée lorsque vous avez trouvé le recyclerView. Par défaut, lorsque vous créez le fragment, la méthode onCreateView apparaît comme suit: return inflater.inflate(R.layout.<related layout>,container.false);

Au lieu de cela, créez la vue séparément et utilisez-la pour faire référence à recyclerView View view= inflater.inflate(R.layout.<related layout>,container.false); recyclerview=view.findViewById(R.id.<recyclerView ID>); return view;

2
Prateek Agarwal

J'ai eu la même erreur que j'ai corrigé en faisant cela si vous attendez des données comme moi en utilisant la modification ou quelque chose comme ça

Mettez avant de créer

private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;

Mettez-les dans votre oncreate

 recyclerView = (RecyclerView) findViewById(R.id.cardList);
 recyclerView.setHasFixedSize(true);
 recyclerView.setLayoutManager(new LinearLayoutManager(this));
 adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
 recyclerView.setAdapter(adapter);

Quand vous recevez des données

adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);

Maintenant, allez dans votre classe ArtistArrayAdapter et faites ce que cela fera. Si votre tableau est vide ou est nul, GetItemCount renverra 0 sinon il en fera la taille du tableau artists

@Override
public int getItemCount() {

    int a ;

    if(artists != null && !artists.isEmpty()) {

        a = artists.size();
    }
    else {

        a = 0;

     }

   return a;
}
2
user3277530

Vérifiez si vous avez manqué d'appeler cette méthode dans votre adaptateur 

@Override
public int getItemCount() {
    return list.size();
}
2
Shabbir Ahmed

Ces lignes doivent être dans OnCreate:

mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
2
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

Il suffit de remplacer le code ci-dessus par ceci et cela devrait fonctionner. Ce que vous avez fait de mal, c'est que vous avez appelé setAdapter (adaptateur) avant d'appeler le gestionnaire de disposition.

1
Pradeep Bogati

J'ai résolu cette erreur. Vous devez simplement ajouter le gestionnaire de disposition .__ et ajouter l’adaptateur vide.

Comme ce code:

myRecyclerView.setLayoutManager(...//your layout manager);
        myRecyclerView.setAdapter(new RecyclerView.Adapter() {
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                return null;
            }

            @Override
            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

            }

            @Override
            public int getItemCount() {
                return 0;
            }
        });
//other code's 
// and for change you can use if(mrecyclerview.getadapter != speacialadapter){
//replice your adapter
//}
1
mehdi janbarari

C’est vraiment une simple erreur que vous obtenez, il n’est pas nécessaire de faire de code dans ceci .Cette erreur est due au mauvais fichier de présentation utilisé par l’activité. Par IDE, j’ai automatiquement créé une présentation v21 d’une présentation qui est devenue une présentation par défaut de l’activité. tous les codes que j’avais dans l’ancien fichier de présentation et le nouveau n’avaient que peu de codes xml, ce qui a conduit à cette erreur.

Solution: Copiez tous les codes de l'ancienne mise en page et collez-la dans la mise en page v 21

1
Vikash Sharma

Dans mon cas, je configurais l'adaptateur dans onLocationChanged(), rappel ET débogage dans l'émulateur. Comme il n'a pas détecté de changement de lieu, il n'a jamais été tiré. Lorsque je les ai définis manuellement dans les contrôles étendus de l'émulateur, cela a fonctionné comme prévu.

1
saiyancoder

D'abord initialiser l'adaptateur

public void initializeComments(){
    comments = new ArrayList<>();

    comments_myRecyclerView = (RecyclerView) findViewById(R.id.comments_recycler);
    comments_mLayoutManager = new LinearLayoutManager(myContext);
    comments_myRecyclerView.setLayoutManager(comments_mLayoutManager);

    updateComments();
    getCommentsData();

}

public void updateComments(){

    comments_mAdapter = new CommentsAdapter(comments, myContext);
    comments_myRecyclerView.setAdapter(comments_mAdapter);
}

Chaque fois que l'ensemble de données change, appelez simplement la méthode updateComments.

1
Roger

J'ai eu le même problème et je me suis rendu compte que je définissais à la fois les LayoutManage r et adapter après avoir récupéré les données de ma source au lieu de les définir dans la méthode onCreate .

salesAdapter = new SalesAdapter(this,ordersList);
        salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        salesView.setAdapter(salesAdapter);

Puis notifié l'adaptateur sur le changement de données 

               //get the Orders
                Orders orders;
                JSONArray ordersArray = jObj.getJSONArray("orders");
                    for (int i = 0; i < ordersArray.length() ; i++) {
                        JSONObject orderItem = ordersArray.getJSONObject(i);
                        //populate the Order model

                        orders = new Orders(
                                orderItem.getString("order_id"),
                                orderItem.getString("customer"),
                                orderItem.getString("date_added"),
                                orderItem.getString("total"));
                        ordersList.add(i,orders);
                        salesAdapter.notifyDataSetChanged();
                    }
0
ovicko

J'ai perdu 16 minutes de ma vie avec ce problème, je vais donc admettre cette erreur incroyablement embarrassante: j'utilise Butterknife et je lie la vue dans onCreateView dans ce fragment. 

Il m'a fallu beaucoup de temps pour comprendre pourquoi je n'avais pas de gestionnaire de mise en page - mais évidemment, les vues sont injectées afin qu'elles ne soient pas réellement nulles, de sorte que le recycleur ne sera jamais nul .. whoops!

@BindView(R.id.recycler_view)
RecyclerView recyclerView;

    @Override
public View onCreateView(......) {
    View v = ...;
    ButterKnife.bind(this, v);
    setUpRecycler()
 }

public void setUpRecycler(Data data)
   if (recyclerView == null) {
 /*very silly because this will never happen*/
       LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
       //more setup
       //...
    }
    recyclerView.setAdapter(new XAdapter(data));
}

Si vous rencontrez un problème comme celui-ci, tracez votre vue et utilisez quelque chose comme uiautomatorviewer

0
Saik Caskey

Pour ceux qui utilisent la RecyclerView dans un fragment et gonflez-le à partir d'autres vues: lorsque vous gonflez la vue fragmentée, assurez-vous de lier la variable RecyclerView à sa vue racine. 

Je me connectais et faisais tout pour l'adaptateur correctement, mais je n'ai jamais fait la reliure. Ce répondre par @Prateek Agarwal a tout pour moi, mais voici plus d'élaboration.

Kotlin

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    val rootView =  inflater?.inflate(R.layout.fragment_layout, container, false)
    recyclerView = rootView?.findViewById(R.id.recycler_view_id)
    // rest of my stuff
    recyclerView?.setHasFixedSize(true)
    recyclerView?.layoutManager = viewManager
    recyclerView?.adapter = viewAdapter
    // return the root view
    return rootView
}

Java

  @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView= inflater.inflate(R.layout.fragment_layout,container.false);
    recyclerview= rootView.findViewById(R.id.recycler_view_id);
    // rest ...
    return rootView;
}
0
N. Osil

Dans votre classe d'adaptateur RecyclerView, par exemple MyRecyclerViewAdapter, créez un constructeur avec les paramètres suivants.

MyRecyclerViewAdapter(Context context, List<String> data) {
    this.mInflater = LayoutInflater.from(context); // <-- This is the line most people include me miss
    this.mData = data;
}

mData correspond aux données que vous allez transmettre à l'adaptateur. Il est facultatif si vous n'avez aucune donnée à transmettremInflater est l'objet LayoutInflater que vous avez créé et que vous utilisez dans la fonction OnCreateViewHolder de l'adaptateur.

Ensuite, vous connectez l’adaptateur à MainActivity ou à l’endroit où vous le souhaitez sur le thread principal/UI, comme

MyRecyclerViewAdapter recyclerAdapter;
OurDataStuff mData;

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

        //Like this:

        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerAdapter = new RecyclerAdapter(this, mData); //this, is the context. mData is the data you want to pass if you have any
        recyclerView.setAdapter(recyclerAdapter);
    }
   ....
0
Neil Agarwal

Mon problème était que ma vue du recycleur ressemblait à ceci 

        <Android.support.v7.widget.RecyclerView
        Android:id="@+id/chatview"
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">
    </Android.support.v7.widget.RecyclerView>

Quand cela aurait dû ressembler à ça 

       <Android.support.v7.widget.RecyclerView
        Android:id="@+id/chatview"
        Android:layout_width="395dp"
        Android:layout_height="525dp"
        Android:layout_marginTop="52dp"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="8dp"></Android.support.v7.widget.RecyclerView>
</Android.support.constraint.ConstraintLayout>
0
Kingsley Mitchell

Pas vraiment une réponse, mais j'avais le même problème, même si le code était correct. Parfois, c'est juste la plus simple des marques. Dans ce cas, l’erreur de l’opérateur peut également être absente de <uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" /> dans le manifeste, ce qui reproduit la même erreur.

0
SpicyWeenie

Ajoutez simplement ce qui suit à RecyclerView

app:layoutManager="Android.support.v7.widget.LinearLayoutManager"

Exemple:

   <Android.support.v7.widget.RecyclerView xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/recyclerView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:scrollbars="vertical"
        app:layoutManager="Android.support.v7.widget.LinearLayoutManager"
        app:layout_constraintBottom_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </Android.support.v7.widget.RecyclerView>
0
Alan Deep

Dans mon cas, il est arrivé que j’ai incorporé un RecyclerView dans un LinearLayout.

J'ai précédemment eu un fichier de mise en page contenant uniquement une racine RecyclerView comme suit

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.RecyclerView
    Android:id="@+id/list"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:listitem="@layout/fragment_products"

    Android:name="Products.ProductsFragment"
    app:layoutManager="LinearLayoutManager"
    tools:context=".Products.ProductsFragment"

    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"/>

Je crois que le problème est dans les 3 lignes séparées. Quoi qu’il en soit, je pense que c’est un problème simple, je pourrai y travailler demain; J'ai pensé écrire ce que j'ai trouvé avant d'oublier ce sujet.

0
SoliQuiD

// Cela se produit lorsque vous ne configurez pas l'adaptateur pendant la phase de création: appelez notifyDataSetChanged () lorsque la réponse de l'API est en cours son fonctionnement

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


        magazineAdapter = new MagazineAdapter(getContext(), null, this );
        newClipRecyclerView.setAdapter(magazineAdapter);
        magazineAdapter.notifyDataSetChanged();

       APICall();
}

public void APICall() {
    if(Response.isSuccessfull()){
    mRecyclerView.setAdapter(mAdapter);
   }
}
Just move setting the adapter into onCreate with an empty data and when you have the data call:

mAdapter.notifyDataSetChanged();
0
Keshav Gera

Dans ma situation, c’était un composant oublié qui se localisait dans la classe ViewHolder, mais non dans le fichier

0
lomec

Ce problème est dû au fait que vous n’ajoutez aucune LayoutManager à votre RecyclerView

Une autre raison est que vous appelez ce code dans un fil NonUIT. Assurez-vous d'appeler cet appel dans le UIThread.

La solution consiste à ajouter une LayoutManager pour la RecyclerView avant setAdapter dans le thread d'interface utilisateur.

recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
0
Khalid Taha

Résolu en définissant la liste vide initialisée et l'adaptateur en bas et en appelant notifyDataSetChanged lorsque les résultats sont extraits.

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
    recyclerviewItems.setLayoutManager(linearLayoutManager);
    someAdapter = new SomeAdapter(getContext(),feedList);
    recyclerviewItems.setAdapter(someAdapter);
0
Tabraiz Malik

Ajoutant encore une autre réponse depuis que je suis tombé sur ce fil en recherchant l’erreur. J'essayais d'initialiser une PreferenceFragmentCompat mais j'ai oublié de gonfler le XML de préférence dans onCreatePreferences comme ceci:

class SettingsFragment : PreferenceFragmentCompat() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val inflater = LayoutInflater.from(context)
        inflater.inflate(R.layout.fragment_settings, null)
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        // Missing this line here:
        //   setPreferencesFromResource(R.xml.settings, rootKey)
    }
}

L'erreur était un mystère jusqu'à ce que je réalise que PreferenceFragmentCompat doit utiliser RecyclerView en interne.

0
aschmied