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.
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 );
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.
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 {
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.
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:
(Peut être suivi pour Android.support.v4.widget.NestedScrollView
également)
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();
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.
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;
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;
}
Vérifiez si vous avez manqué d'appeler cette méthode dans votre adaptateur
@Override
public int getItemCount() {
return list.size();
}
Ces lignes doivent être dans OnCreate
:
mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
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.
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
//}
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
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.
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.
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();
}
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
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;
}
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);
}
....
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>
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.
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>
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.
// 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();
Dans ma situation, c’était un composant oublié qui se localisait dans la classe ViewHolder, mais non dans le fichier
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()));
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);
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.