recyclerview не подключен адаптер; пропуск макета
просто реализовал Recyclerview в моем коде, заменив Listview.
все работает нормально. Отображаются объекты.
но logcat говорит
15: 25: 53.476 E / RecyclerView﹕ адаптер не подключен; пропуск макета
15: 25: 53.655 E / RecyclerView﹕ адаптер не подключен; пропуск макета
код
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Как вы можете видеть, я подключил адаптер для Recycleview. так почему же я продолжаю получать эту ошибку?
Я прочитал другие вопросы, связанные с той же проблемой, но ни один не помогает.
24 ответов
можете ли вы убедиться, что вызываете эти операторы из" основного " потока (например, внутри onCreate()
метод).
Как только я вызову те же утверждения из метода "delayed". В моем случае ResultCallback
, Я получаю то же сообщение.
в своем Fragment
, назвав код внутри ResultCallback
метод выдает то же сообщение. После перемещения кода onConnected()
метод в моем приложении, сообщение исчезло...
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
я получал те же два сообщения об ошибках, пока не исправил две вещи в своем коде:
(1) по умолчанию, когда вы реализуете методы в RecyclerView.Adapter
Он генерирует:
@Override
public int getItemCount() {
return 0;
}
убедитесь, что вы обновили свой код, чтобы он сказал:
@Override
public int getItemCount() {
return artists.size();
}
очевидно, если у вас есть нулевые элементы в ваших элементах, то вы получите нулевые вещи, отображаемые на экране.
(2) я не делал этого, как показано в верхней ответ: CardView layout_width= " match_parent" не соответствует родительской ширине RecyclerView
//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) ИЗМЕНИТЬ: БОНУС:
Также убедитесь, что вы настроили свой RecyclerView
такой:
<android.support.v7.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
не так:
<view
android:id="@+id/RecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Я видел некоторые учебники, используя второй метод. Пока он работает, я думаю, что он также генерирует эту ошибку.
у меня такая же ситуация с вами, дисплей в порядке, но ошибка появляется в locat. Это мое решение: (1) инициализируйте адаптер RecyclerView & bind при CREATE ()
RecyclerView mRecycler = (RecyclerView) this.findViewById(R.id.yourid);
mRecycler.setAdapter(adapter);
(2) вызов notifyDataStateChanged при получении данных
adapter.notifyDataStateChanged();
в исходном коде recyclerView есть другой поток для проверки состояния данных.
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();
}
}
}
};
в dispatchLayout () мы можем найти в нем ошибку:
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 {
У меня есть эта проблема, несколько проблем времени recycleView положить в ScrollView объект
после проверки реализации причина выглядит следующим образом. Если RecyclerView помещается в ScrollView, то во время шага измерения его высота не указана (потому что ScrollView допускает любую высоту) и, в результате, получает равную минимальной высоте (согласно реализации), которая, по-видимому, равна нулю.
у вас есть несколько вариантов для крепления это:
- установите определенную высоту для RecyclerView
- Установить ScrollView.fillViewport в true
- или сохранить RecyclerView вне ScrollView. На мой взгляд, это самый лучший вариант. Если высота RecyclerView не ограничена - что имеет место, когда она помещается в ScrollView - тогда все виды адаптера имеют достаточно места по вертикали и создаются сразу. Нет вид утилизации, который немного ломает целью RecyclerView .
(можно следовать за android.support.v4.widget.NestedScrollView
а)
1) Создать ViewHolder что ничего не делает :)
// SampleHolder.java
public class SampleHolder extends RecyclerView.ViewHolder {
public SampleHolder(View itemView) {
super(itemView);
}
}
2) Опять создать RecyclerView что ничего не делает :)
// 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) Теперь, когда ваш реальный recycler не готов, просто используйте образец, как показано ниже.
RecyclerView myRecycler = (RecyclerView) findViewById(R.id.recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
myRecycler.setAdapter(new SampleRecycler());
Это не лучшее решение, но оно работает! Надеюсь, это поможет.
это происходит, когда вы не устанавливаете адаптер на этапе создания:
@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);
....
}
просто переместите настройку адаптера в onCreate с пустыми данными и когда у вас есть вызов данных:
mAdapter.notifyDataSetChanged();
убедитесь, что вы установили менеджер макетов для вашего RecyclerView по:
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
вместо LinearLayoutManager
, вы можете использовать другое менеджеры по расположению тоже.
у меня была такая же ошибка, я исправил это, если вы ждете таких данных, как я, используя retrofit или что-то в этом роде
поставить перед Oncreate
private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;
поместите их в свой 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);
когда вы получаете данные put
adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);
Теперь перейдите в свой класс ArtistArrayAdapter и сделайте это, что он будет делать, если Ваш массив пуст или равен нулю, он заставит GetItemCount вернуть 0, если нет, это сделает его размером художников массив
@Override
public int getItemCount() {
int a ;
if(artists != null && !artists.isEmpty()) {
a = artists.size();
}
else {
a = 0;
}
return a;
}
эти строки должны быть в 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);
просто замените код выше этим, и он должен работать. То, что вы сделали неправильно, вы назвали setAdapter(adapter) перед вызовом диспетчера макетов.
Это действительно просто ошибка, что вы получаете, нет необходимости делать какие-либо коды в этом. эта ошибка возникает из-за неправильного файла макета, используемого в деятельности. По IDE я автоматически создал макет v21 макета, который стал макетом действия по умолчанию. все коды, которые я сделал в старом файле макета, а новый имел только несколько xml-кодов, что привело к этой ошибке.
решение: скопируйте все коды старого макета и вставьте в макет v 21
в моем случае я устанавливал адаптер внутри onLocationChanged()
обратный вызов и отладка в эмуляторе. Поскольку он не обнаружил изменения местоположения, он никогда не стрелял. Когда я устанавливал их вручную в расширенных элементах управления эмулятора, он работал так, как ожидалось.
Я решил эту ошибку. Вам просто нужно добавить layout manager и добавьте пустой адаптер.
такой код:
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
//}
это происходит потому, что фактический завышенный макет отличается от того, на который вы ссылаетесь при поиске recyclerView. По умолчанию при создании фрагмента, метод onCreateView следующим образом:
return inflater.inflate(R.layout.<related layout>,container.false);
вместо этого отдельно создайте представление и используйте его для ссылки на recyclerView
View view= inflater.inflate(R.layout.<related layout>,container.false);
recyclerview=view.findViewById(R.id.<recyclerView ID>);
return view;
сначала инициализировать адаптер
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);
}
когда когда-либо есть изменение в наборе данных, просто вызовите метод updateComments.
в моей ситуации это был забытый компонент, который находится в классе ViewHolder, но он не был расположен в файле макета
у меня была та же проблема, и я понял, что устанавливаю оба LayoutManager и адаптер после извлечения данных из моего источника вместо установки двух в onCreate метод.
salesAdapter = new SalesAdapter(this,ordersList);
salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
salesView.setAdapter(salesAdapter);
затем уведомил адаптер об изменении данных
//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();
}
эта проблема заключается в том, что вы не добавляете никаких LayoutManager
для RecyclerView
.
другая причина заключается в том, что вы вызываете этот код в NonUIThread. Обязательно вызовите этот вызов в UIThread.
решение только вы должны добавить LayoutManager
на RecyclerView
перед setAdapter
в потоке пользовательского интерфейса.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
моя проблема заключалась в том, что мой вид recycler выглядел так
<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>
когда это должно было выглядеть так
<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>
в своем RecyclerView
класс адаптера, например MyRecyclerViewAdapter
, создайте конструктор со следующими параметрами.
MyRecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context); // <-- This is the line most people include me miss
this.mData = data;
}
mData
- это данные, которые вы передадите адаптеру. Это необязательно, если у вас нет данных для передачи.
mInflater
- это LayoutInflater
объект, который вы создали и используете в OnCreateViewHolder
функции адаптера.
после этого вы прикрепляете адаптер в MainActivity или везде, где хотите, в основном потоке/UI правильно, как
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);
}
....
решается путем установки инициализированного пустого списка и адаптера внизу и вызова notifyDataSetChanged при получении результатов.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
recyclerviewItems.setLayoutManager(linearLayoutManager);
someAdapter = new SomeAdapter(getContext(),feedList);
recyclerviewItems.setAdapter(someAdapter);
Я потерял 16 минут своей жизни с этой проблемой, поэтому я просто признаю эту невероятно неловкую ошибку, которую я делал - я использую Butterknife, и я связываю представление в onCreateView в этом фрагменте.
потребовалось много времени, чтобы понять, почему у меня не было layoutmanager - но, очевидно, представления вводятся, поэтому они на самом деле не будут нулевыми, поэтому recycler никогда не будет нулевым .. упс!
@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));
}
Если вы получаете такую проблему, как эта трассировка вашего представления и использования что-то вроде uiautomatorviewer
для тех, кто использует RecyclerView
внутри фрагмент и надуть его из других видов: при раздувании всего вида фрагмента убедитесь, что вы связываете RecyclerView
в его корне посмотреть.
я подключался и делал все для адаптера правильно, но я никогда не делал привязку. Это ответ by @Prateek Agarwal все это для меня, но вот еще разработка.
Котлин
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;
}
Не так много ответа, но у меня была такая же проблема, даже с правильным кодом. Иногда, это просто самый простой из решений. В этом случае ошибка OP также может отсутствовать <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
из манифеста, который воспроизводит ту же ошибку.