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()метод). Как только я вызываю те же операторы из "отложенного" метода. В моем случае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 при создании ()
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();
убедитесь, что вы установили менеджер макетов для вашего 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);когда вы получаете данные положить
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(Адаптер) перед вызовом диспетчера компоновки.
Это действительно просто ошибка, что вы получаете, нет необходимости делать какие-либо коды в этом. эта ошибка возникает из-за неправильного файла макета, используемого в деятельности. С помощью IDE я автоматически создал макет v21 макета, который стал макетом по умолчанию действия. все коды, которые я сделал в старом файле макета, а новый имел только несколько xml-кодов, что привело к этой ошибке.
решение: скопируйте все коды старого макета и вставьте в макет v 21
в моем случае, я устанавливал адаптер внутри
onLocationChanged()обратный вызов и отладка в эмуляторе. Поскольку он не обнаружил изменения местоположения, он никогда не стрелял. Когда я установил их вручную в расширенном управления эмулятора он работал, как ожидалось.
Я решил эту ошибку. Вам просто нужно добавить менеджер макетов и добавьте пустой адаптер.
такой код:
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()));
моя проблема заключалась в том, что мой вид рециркулятора выглядел так
<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 - но, очевидно, представления вводятся, поэтому они на самом деле не будут null, поэтому recycler никогда не будет null .. упс!
@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" />из манифеста, который воспроизводит ту же ошибку.
Comments