recyclerview Нет прилагаемого адаптера; пропускающий макет
Только что реализовал Recyclerview в моем коде, заменив Listview.
все отлично работает Объекты отображаются.
но LogCat говорит
15:25:53.476 E/RecyclerView adapter Адаптер не подключен; пропускающий макет
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. так почему я продолжаю получать эту ошибку?
Я прочитал другие вопросы, связанные с той же проблемой, но ни один не помогает.
40 ответов
Можете ли вы убедиться, что вы вызываете эти операторы из "основного" потока (например, внутри onCreate()
метод). Как только я вызываю те же утверждения из "отложенного" метода. В моем случае 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" />
Я видел некоторые учебники, использующие последний метод. Хотя это работает, я думаю, что это тоже генерирует эту ошибку.
У меня такая же ситуация с вами, с дисплеем все в порядке, но в локации появляется ошибка. Вот мое решение: (1) Инициализировать RecyclerView и адаптер привязки ON 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) Теперь, когда ваш настоящий переработчик не готов, просто используйте образец, как показано ниже.
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();
Проверьте, не пропустили ли вы вызов этого метода в вашем адаптере
@Override
public int getItemCount() {
return list.size();
}
В Kotlin у нас возникла эта странная нелогичная проблема.
Это не сработало:
mBinding.serviceProviderCertificates.apply {
adapter = adapter
layoutManager = LinearLayoutManager(activity)
}
Пока это сработало:
mBinding.serviceProviderCertificates.adapter = adapter
mBinding.serviceProviderCertificates.layoutManager = LinearLayoutManager(activity)
Как только я получу больше в нерабочее время, я поделюсь новыми идеями.
Убедитесь, что вы установили менеджер макета для вашего RecyclerView:
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
Вместо LinearLayoutManager
Вы также можете использовать другие менеджеры по расположению.
У меня была та же ошибка, я исправил это, делая это, если вы ждете данных, таких как я, используя модификацию или что-то подобное
Поставить перед созданием
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);
Когда вы получаете данные положить
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;
}
Для тех, кто использует RecyclerView
внутри фрагмента и накачайте его из других представлений: при надувании всего фрагмента убедитесь, что вы связываете RecyclerView
в его корне зрения.
Я подключался и делал все правильно для адаптера, но я никогда не делал привязку. В этом ответе @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
}
Джава
@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;
}
В моем XML-файле макета отсутствовала нижняя строка с layoutManager. Ошибка исчезла после того, как я ее добавил.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_chat"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layoutManager="LinearLayoutManager"/>
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
Просто замените приведенный выше код этим, и он должен работать. То, что вы сделали неправильно, вы назвали setAdapter(адаптер) перед вызовом менеджера по расположению.
Это происходит потому, что фактический раздутый макет отличается от того, на который вы ссылались при поиске 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;
Эти строки должны быть в OnCreate
:
mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
В моем случае я просто добавил диспетчер компоновки в recyclerview и исправил. В recyclerview в вашем файле XML просто добавьтеapp:layoutManager
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewData"
.
.
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
.
./>
Сначала инициализируйте адаптер
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.
У меня была эта ошибка, и я некоторое время пытался исправить, пока не нашел решение.
Я создал частный метод buildRecyclerView и дважды вызвал его, сначала в onCreateView, а затем после обратного вызова (в котором я получаю данные из API). Это мой метод buildRecyclerView в моем фрагменте:
private void buildRecyclerView(View v) {
mRecyclerView = v.findViewById(R.id.recycler_view_loan);
mLayoutManager = new LinearLayoutManager(getActivity());
((LinearLayoutManager) mLayoutManager).setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new LoanAdapter(mExampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
Кроме того, мне нужно изменить метод get-Item-Count в моем адаптере, потому что при on-Create-View список равен нулю, а это из-за ошибки. Итак, мой get-Item-Count следующий:
@Override
public int getItemCount() {
try {
return mLoanList.size();
} catch (Exception ex){return 0;}
}
В моем случае я устанавливал адаптер внутри onLocationChanged()
обратный вызов и отладка в эмуляторе. Так как он не обнаружил изменение местоположения, он никогда не срабатывал. Когда я установил их вручную в расширенных элементах управления эмулятора, все заработало как положено.
Это действительно простая ошибка, которую вы получаете, нет необходимости делать какие-либо коды в этом. Эта ошибка возникает из-за неправильного файла макета, используемого операцией. В IDE я автоматически создал макет v21 макета, который стал макетом по умолчанию для действия. все коды, которые я делал в старом файле макета и в новом, содержали только несколько кодов XML, что привело к этой ошибке.
Решение: Скопируйте все коды старого макета и вставьте в макет v 21
Я решил эту ошибку. Вам просто нужно добавить менеджер раскладки и добавить пустой адаптер.
Понравился этот код:
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
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
Пример:
<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>
Если вы все еще получаете ошибку при использовании ViewBinding, убедитесь, что вы используете привязку для возврата раздутого представления, т.е.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return fragmentBinding.getRoot();
}
В моем случае это произошло, потому что я встроил RecyclerView в LinearLayout.
Ранее у меня был файл макета, содержащий только один корневой RecyclerView следующим образом
<?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"/>
Я считаю, что проблема в разделенных 3 строчках. Во всяком случае, я думаю, что это простая проблема, я буду работать над этим завтра; думал, что я должен написать то, что я нашел, прежде чем забывать об этой теме.
У меня возникла та же проблема, и я понял, что настраивал LayoutManage r и адаптер после получения данных из моего источника вместо того, чтобы устанавливать их в методе 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();
}
Обязательно установите для атрибута attachToRoot значение false в методе .inflate вашей привязки данных или в том, что вы используете для отображения таких представлений:
.inflate(layoutInflater, родитель, ложь)
Немного ответа, но у меня была такая же проблема, даже с правильным кодом. Иногда это просто самое простое из того, что делает. В этом случае ошибка ОП также может отсутствовать <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
из Манифеста, который воспроизводит ту же ошибку.
Это связано с тем, что вы не добавляете LayoutManager
для тебя RecyclerView
,
Другая причина в том, что вы вызываете этот код в NonUIThread. Обязательно вызовите этот вызов в UIThread.
Решение только вы должны добавить LayoutManager
для RecyclerView
до тебя setAdapter
в теме пользовательского интерфейса.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Добавление еще одного ответа, так как я наткнулся на эту тему, погуглив ошибку. Я пытался инициализировать PreferenceFragmentCompat
но я забыл раздуть предпочтение XML в onCreatePreferences
как это:
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)
}
}
Ошибка была загадкой, пока я не понял, что PreferenceFragmentCompat
должен использовать RecyclerView
внутренне.
У меня возникла такая же проблема, я все сделал правильно, за исключением файла xml:
Шаг первый 1: инициализировать recyclerview и список и адаптер:
RecyclerView recyclerview; List<ModelName> list; ProvideBidAdaptor adaptor;
шаг 2: привяжите его к onCreate-
recyclerview = findByViewId(R.id.providerBidRV); recyclerview.setLayoutManager(new LinearLayoutManager(this)); recyclerview.setHasFixedSize(true); list = new ArrayList<>();
шаг 3: Где вы получаете ответ или список - добавьте список- (я получаю из ответа)>
responseList.addAll(response.getResponse()); adaptor = new ProvideBidAdaptor(this, responseList); binding.detailsRV.setAdapter(adaptor);
Вот мой xml-файл, в котором я реализую RecyclerView
: Я забыл ориентацию в LinearLayout
, после этой коррекции- RecyclerView
прилагается.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".activities.Bidding.ProvideBid">
<include
android:id="@+id/toolbar"
layout="@layout/app_toolbar"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/providerBidRV"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</layout>
Вот адаптер:
public class ProvideBidAdaptor extends RecyclerView.Adapter<ProvideBidAdaptor.ViewHolder> {
Context context;
List<Response> responseList;
DateTime dateTimeInstance = new DateTime();
public ProvideBidAdaptor(Context context, List<Response> responseList) {
this.context = context;
this.responseList = responseList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.geo_presence_item_list, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final Response detailsResponse = responseList.get(position);
if (!detailsResponse.getUserId().isEmpty()) {
holder.day.setText(detailsResponse.getDay());
holder.locationType.setText(detailsResponse.getLocationType());
}
}
@Override
public int getItemCount() {
return responseList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView date,locationType;
CardView provideBidCV;
LinearLayout dayLLayout,locationTypeLLayout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
date = itemView.findViewById(R.id.date_value);
day = itemView.findViewById(R.id.day_value);
locationType = itemView.findViewById(R.id.locationType_value);
locationTypeLLayout = itemView.findViewById(R.id.locationTypeLLayout);
}
}
}