RecyclerView crashes when used in fragment but not in activity - android

I was using a recyclerview in an activity and now decided to use it in a fragment instead. Now my code crashes at layoutmanager = new LinearLayoutManager (globalContext); with a NullPointerException.
I have no idea why. As I said it worked perfectly fine when used in activity.
I'm using Xamarin but that really doesn't make any difference.
I have only included the first parts of the code as app crashes before reaching others.
private Context globalContext = null;
RecyclerView recyclerview;
RecyclerView.LayoutManager layoutmanager;
NewsAdapter adapter;
public LatestNewsFragment()
{
this.RetainInstance = true;
}
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.fragment_latestnews, null);
// Get our RecyclerView layout:
recyclerview = view.FindViewById<RecyclerView> (Resource.Id.recyclerView);
return view;
}
public override async void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
globalContext = this.Context;
//............................................................
// Layout Manager Setup:
// Use the built-in linear layout manager:
layoutmanager = new LinearLayoutManager (globalContext);
// Plug the layout manager into the RecyclerView:
recyclerview.SetLayoutManager (layoutmanager);
//............................................................
// Adapter Setup:
// Create an adapter for the RecyclerView, and pass it the
// data set to manage:
var rest = new RestAccess();
var listofarticles = await rest.ListArticlesAsync("somesource", "1");
adapter = new NewsAdapter (listofarticles, globalContext);
// Register the item click handler (below) with the adapter:
adapter.ItemClick += OnItemClick;
// Plug the adapter into the RecyclerView:
recyclerview.SetAdapter (adapter);
}
// Handler for the item click event:
void OnItemClick (object sender, int position)
{
// Display a toast that briefly shows the enumeration of the selected photo:
int photoNum = position + 1;
Toast.MakeText(globalContext, "This is card number " + photoNum, ToastLength.Short).Show();
}
}
Edit:
So I changed the OnCreateView to :
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.fragment_latestnews, null);
// Get our RecyclerView layout:
recyclerview = view.FindViewById<RecyclerView> (Resource.Id.recyclerView);
// Plug the layout manager into the RecyclerView:
recyclerview.SetLayoutManager (new LinearLayoutManager (Activity));
return view;
}
And still getting nullpointer exception at recyclerview.SetLayoutManager (new LinearLayoutManager (Activity));
Edit 2:
variable recyclerview is actually null. Don't know why.
Answer:
My app was crashing for two reasons:
1- layoutmanager must be defined in OnCreateView but I was doing it in OnActivityCreated.
2- My fragment layout file didn't include the RecyclerView.

You need to set LayoutManager in onCreateView() after initializing RecyclerView, instead of setting in onActivityCreated():
mRecyclerView = (RecyclerView)v.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(newLinearLayoutManager(mRecyclerView.getContext()));

Instead of this.Context use getActivity() to get Context in Fragment class. Change:
globalContext = this.Context;
to
globalContext = getActivity();

Try with getActivity()
layoutmanager = new LinearLayoutManager (getActivity());

Related

My RecyclerView is not displaying anything. No adapter attached; skipping layout [duplicate]

Just implemented RecyclerView in my code, replacing ListView.
Everything works fine. The data is displayed.
But error messages are being logged:
15:25:53.476 E/RecyclerView: No adapter attached; skipping layout
15:25:53.655 E/RecyclerView: No adapter attached; skipping layout
for the following code:
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
As you can see I have attached an adapter for RecyclerView.
So why do I keep getting this error?
I have read other questions related to the same problem but none of them help.
Can you make sure that you are calling these statements from the "main" thread outside of a delayed asynchronous callback (for example inside the onCreate() method).
As soon as I call the same statements from a "delayed" method. In my case a ResultCallback, I get the same message.
In my Fragment, calling the code below from inside a ResultCallback method produces the same message. After moving the code to the onConnected() method within my app, the message was gone...
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
I was getting the same two error messages until I fixed two things in my code:
(1) By default, when you implement methods in the RecyclerView.Adapter it generates:
#Override
public int getItemCount() {
return 0;
}
Make sure you update your code so it says:
#Override
public int getItemCount() {
return artists.size();
}
Obviously if you have zero items in your items then you will get zero things displayed on the screen.
(2) I was not doing this as shown in the top answer: CardView layout_width="match_parent" does not match 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:
Also make sure you set up your RecyclerView like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
NOT like this:
<view
android:id="#+id/RecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I have seen some tutorials using the latter method. While it works I think it generates this error too.
I have the same situation with you, display is ok, but error appear in the locat.
That's my solution:
(1) Initialize the RecyclerView & bind adapter ON CREATE()
RecyclerView mRecycler = (RecyclerView) this.findViewById(R.id.yourid);
mRecycler.setAdapter(adapter);
(2) call notifyDataStateChanged when you get the data
adapter.notifyDataStateChanged();
In the recyclerView's source code, there is other thread to check the state of data.
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();
}
}
}
};
In the dispatchLayout(), we can find there is the error in it:
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 {
i have this problem , a few time problem is recycleView put in ScrollView object
After checking implementation, the reason appears to be the following. If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and, as a result, gets equal to minimum height (as per implementation) which is apparently zero.
You have couple of options for fixing this:
Set a certain height to RecyclerView
Set ScrollView.fillViewport to true
Or keep RecyclerView outside of ScrollView. In my opinion, this is the best option by far. If RecyclerView height is not limited - which is the case when it's put into ScrollView - then all Adapter's views have enough place vertically and get created all at once. There is no view recycling anymore which kinda breaks the purpose of RecyclerView .
(Can be followed for android.support.v4.widget.NestedScrollView as well)
1) Create ViewHolder that does nothing :)
// SampleHolder.java
public class SampleHolder extends RecyclerView.ViewHolder {
public SampleHolder(View itemView) {
super(itemView);
}
}
2) Again create RecyclerView that does nothing :)
// 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) Now when your real recycler is not ready just use the sample one like below.
RecyclerView myRecycler = (RecyclerView) findViewById(R.id.recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
myRecycler.setAdapter(new SampleRecycler());
This is not best solution though but it works! Hope this is helpful.
It happens when you are not setting the adapter during the creation phase:
#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);
....
}
Just move setting the adapter into onCreate with an empty data and when you have the data call:
mAdapter.notifyDataSetChanged();
Check if you have missed to call this method in your adapter
#Override
public int getItemCount() {
return list.size();
}
In Kotlin we had this weird illogical issue.
This didn't work:
mBinding.serviceProviderCertificates.apply {
adapter = adapter
layoutManager = LinearLayoutManager(activity)
}
While this worked:
mBinding.serviceProviderCertificates.adapter = adapter
mBinding.serviceProviderCertificates.layoutManager = LinearLayoutManager(activity)
Once I get more after work hours, I will share more insights.
Make sure you set the layout manager for your RecyclerView by:
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
Instead of LinearLayoutManager, you can use other layout managers too.
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
Just replace above code with this and it should work. What you did wrong is you called setAdapter(adapter) before calling layout manager.
I had the same error I fixed it doing this if you are waiting for data like me using retrofit or something like that
Put before Oncreate
private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;
Put them in your 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);
When you receive data put
adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);
Now go in your ArtistArrayAdapter class and do this what it will do is if your array is empty or is null it will make GetItemCount return 0 if not it will make it the size of artists array
#Override
public int getItemCount() {
int a ;
if(artists != null && !artists.isEmpty()) {
a = artists.size();
}
else {
a = 0;
}
return a;
}
For those who use the RecyclerView within a fragment and inflate it from other views: when inflating the whole fragment view, make sure that you bind the RecyclerView to its root view.
I was connecting and doing everything for the adapter correctly, but I never did the binding.
This answer by #Prateek Agarwal has it all for me, but here is more elaboration.
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);
return rootView;
}
These Lines must be in OnCreate:
mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
This happens because the actual inflated layout is different from that which is being referred by you while finding the recyclerView. By default when you create the fragment, the onCreateView method appears as follows:
return inflater.inflate(R.layout.<related layout>,container.false);
Instead of that, separately create the view and use that to refer to recyclerView
View view= inflater.inflate(R.layout.<related layout>,container.false);
recyclerview=view.findViewById(R.id.<recyclerView ID>);
return view;
In my layout xml file, the bottom line with layoutManager was missing. The error disappeared after I added it.
<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"/>
First initialize the adapter
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);
}
When ever there is a change in the dataset set, just call the updateComments method.
I had this error, and I tried to fix for a while until I found the solution.
I made a private method buildRecyclerView, and I called it twice, first on onCreateView and then after my callback (in which I fetch data from an API). This is my method buildRecyclerView in my Fragment:
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);
}
Besides, I have to modify the method get-Item-Count in my adapter, because On on-Create-View the list is null and it through an error. So, my get-Item-Count is the following:
#Override
public int getItemCount() {
try {
return mLoanList.size();
} catch (Exception ex){return 0;}
}
This is really a simple error you are getting, there in no need of doing any codes in this.
This error occurs due to the wrong layout file used by the activity. By IDE i automatically created a layout v21 of a layout which became a default layout of the activity.
all codes I did in the old layout file and new one was only having few xml codes, which led to that error.
Solution: Copy all codes of old layout and paste in layout v 21
In my case, I was setting the adapter inside onLocationChanged() callback AND debugging in the emulator. Since it didn't detected a location change it never fired. When I set them manually in the Extended controls of the emulator it worked as expected.
I have solved this error. You just need to add layout manager
and add the empty adapter.
Like this 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
//}
Just add the following to RecyclerView
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
Example:
<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>
In case you're getting still error while using ViewBinding, make sure you're using the binding to return the inflated view ie
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return fragmentBinding.getRoot();
}
In my situation it was a forgotten component which locates in ViewHolder class but it wasn't located in layout file
I had the same problem and realized I was setting both the LayoutManager and adapter after retrieving the data from my source instead of setting the two in the onCreate method.
salesAdapter = new SalesAdapter(this,ordersList);
salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
salesView.setAdapter(salesAdapter);
Then notified the adapter on data change
//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();
}
This issue is because you are not adding any LayoutManager for your RecyclerView.
Another reason is because you are calling this code in a NonUIThread. Make sure to call this call in the UIThread.
The solution is only you have to add a LayoutManager for the RecyclerView before you setAdapter in the UI Thread.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Solved by setting the initialized empty list and adapter at the bottom and calling notifyDataSetChanged when results are fetched.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
recyclerviewItems.setLayoutManager(linearLayoutManager);
someAdapter = new SomeAdapter(getContext(),feedList);
recyclerviewItems.setAdapter(someAdapter);
I lost 16 minutes of my life with this issue, so I'll just admit to this incredibly embarrassing mistake that I was making- I'm using Butterknife and I bind the view in onCreateView in this fragment.
It took a long time to figure out why I had no layoutmanager - but obviously the views are injected so they won't actually be null, so the the recycler will never be null .. 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));
}
If you are getting an issue like this trace your view and use something like uiautomatorviewer
In my case it happened cause i embedded a RecyclerView in a LinearLayout.
I previously had a layout file only containing one root RecyclerView as follows
<?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"/>
I believe the problem is within the 3 lines separated. Anyway, I think its a simple problem, ill be working on it tomorrow; thought i should write what i found before forgetting about this thread.
Adding yet another answer since I came across this thread googling the error. I was trying to initialize a PreferenceFragmentCompat but I forgot to inflate the preference XML in onCreatePreferences like this:
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)
}
}
The error was a mystery until I realized that PreferenceFragmentCompat must be using a RecyclerView internally.
// It happens when you are not setting the adapter during the creation phase: call notifyDataSetChanged() when api response is getting Its Working
#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();

How to add items in a recycler view from a different class

Have implemented a recycler view found on my notification fragments on adding itesm on the same fragments no problem occurs but when i try to add items from another fragment it throws and eror JavaNullPointException.
here is my fragment that has the recycler view
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View v = inflater.inflate (R.layout.fragment_notificationcict, container, false);
notimodels = new ArrayList<> ();
mRecyclerView = v.findViewById(R.id.notificationsRecycler);
fillNotification (R.drawable.logo, "OCApp", "Welcome to Online Clearance Application,Get cleared now , avoid queing up in offices , save time and money.",+ minutes+"min");
// get data from the notificiation
return v;
}
#Override
public void onStart() {
super.onStart ();
swipeRefreshLayout.setRefreshing(true);
fillNotification (R.drawable.logo, "OCApp", "Welcome to Online Clearance Application,Get cleared now , avoid queing up in offices , save time and money.",+ minutes+"min");
}
public void fillNotification(int mImage, String mtext, String mtext2, String mDate)
{
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager (getContext ());
mAdapter = new NotificationAdapter (notimodels);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
notimodels.add (0,new NotificationModel (mImage,mtext,mtext2,mDate));
}
}
**When i try to call the function from other fragments like tis forexample""
NotificationFragmentCict notificationFragmentCict =new NotificationFragmentCict ();
notificationFragmentCict.fillNotification (R.drawable.bursar, "Bursar", "your clreard","min");
My App crushes and throws this error
Process: com.univibezstudios.ocappservice.ocapp, PID: 3380
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setHasFixedSize(boolean)' on a null object reference
The problem is this one This error is showing because your fragment's view is not created yet. That's why recyclerview is null and you're invoking setHasFixedSize(...) method on you null recyclerview. but icant solve it any help guys
You need to initialize the recycler view which you left out of the function fillNotification:
mRecyclerView = v.findViewById(R.id.notificationsRecycler);
you also need the ArrayList in the second fragment:
notimodels = new ArrayList<> ();

private variable inside fragment are all null, why?

I have of null object inside a fragment. The basic idea is that I have an activity that fetches a database asynchronously. However my recyclerview where I will populate the data lives into a fragment. The pseudo-code is more or less
ACTIVITY:
public void onCreate(Bundle savedInstanceState) {
//kicks off a query to the server
mData = new Gson().fromJson(getIntent().getExtras().getString(Constants.MYDATA), MyData.class);
if (mVenue == null) {
finish();
return;
}
// a bunch of stuff
// create a fragment
mMyFrag = new MyFrag();
}
public void CallBackWhenDone(final List<DataSet> dataset) {
// notify the frag that we are done
mMyFrag.notifyDataSetChanged(messages);
}
FRAGMENT:
private RecyclerView mRV;
private ParentActivity mActivity;
private ActivityAsynchData mAsynchData;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recycler, container, false);
mRV = (RecyclerView) view.findViewById(R.id.list);
mRV.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext(), LinearLayoutManager.VERTICAL, false));
if (null != mActivity) {
mAsynchData = mActivity.GetAsynchData();
}
if (null != mAsynchData) {
mRV.setAdapter(new MyRecyclerAdapter(getActivity(), mAsynchData));
}
}
// mRV is null when the activity "CallBackWhenDone" calls the frag
// all private variables are gone! why?
public void notifyDataSetChanged(final List<Message> messages) {
MyRecyclerAdapter adapter = ((MyRecyclerAdapter) mRV.getAdapter());
adapter.setMessageList(messages);
adapter.notifyDataSetChanged();
}
I ended up hacking my recycler (mRV in this case) view to be static, but this looks super hacked.
any way around? In other words how can I fetch my "mRV" after the fragment has been created and the private vars are all gone.
What i could understand is, that you initialised the fragment and try to access the recycler view in that but its throwing you null. I am not surprised to see it being as null. The way you have called the method is not correct.You need to get the hosted and already running fragment, instance try doing this:
if you are using support fragment use getSupportFragmentManager instead of getFragmentManager.
MyFrag fragment = (MyFrag) getFragmentManager().findFragmentById(R.id.fragmentHolder);
fragment.<specific_function_name>();
Here , the R.id.fragmentHolder is the id of the frame layout or any layout that you are using to host your fragment inside the an activity.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmentHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>

recyclerview No adapter attached; skipping layout

Just implemented RecyclerView in my code, replacing ListView.
Everything works fine. The data is displayed.
But error messages are being logged:
15:25:53.476 E/RecyclerView: No adapter attached; skipping layout
15:25:53.655 E/RecyclerView: No adapter attached; skipping layout
for the following code:
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
As you can see I have attached an adapter for RecyclerView.
So why do I keep getting this error?
I have read other questions related to the same problem but none of them help.
Can you make sure that you are calling these statements from the "main" thread outside of a delayed asynchronous callback (for example inside the onCreate() method).
As soon as I call the same statements from a "delayed" method. In my case a ResultCallback, I get the same message.
In my Fragment, calling the code below from inside a ResultCallback method produces the same message. After moving the code to the onConnected() method within my app, the message was gone...
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
I was getting the same two error messages until I fixed two things in my code:
(1) By default, when you implement methods in the RecyclerView.Adapter it generates:
#Override
public int getItemCount() {
return 0;
}
Make sure you update your code so it says:
#Override
public int getItemCount() {
return artists.size();
}
Obviously if you have zero items in your items then you will get zero things displayed on the screen.
(2) I was not doing this as shown in the top answer: CardView layout_width="match_parent" does not match 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:
Also make sure you set up your RecyclerView like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
NOT like this:
<view
android:id="#+id/RecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I have seen some tutorials using the latter method. While it works I think it generates this error too.
I have the same situation with you, display is ok, but error appear in the locat.
That's my solution:
(1) Initialize the RecyclerView & bind adapter ON CREATE()
RecyclerView mRecycler = (RecyclerView) this.findViewById(R.id.yourid);
mRecycler.setAdapter(adapter);
(2) call notifyDataStateChanged when you get the data
adapter.notifyDataStateChanged();
In the recyclerView's source code, there is other thread to check the state of data.
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();
}
}
}
};
In the dispatchLayout(), we can find there is the error in it:
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 {
i have this problem , a few time problem is recycleView put in ScrollView object
After checking implementation, the reason appears to be the following. If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and, as a result, gets equal to minimum height (as per implementation) which is apparently zero.
You have couple of options for fixing this:
Set a certain height to RecyclerView
Set ScrollView.fillViewport to true
Or keep RecyclerView outside of ScrollView. In my opinion, this is the best option by far. If RecyclerView height is not limited - which is the case when it's put into ScrollView - then all Adapter's views have enough place vertically and get created all at once. There is no view recycling anymore which kinda breaks the purpose of RecyclerView .
(Can be followed for android.support.v4.widget.NestedScrollView as well)
1) Create ViewHolder that does nothing :)
// SampleHolder.java
public class SampleHolder extends RecyclerView.ViewHolder {
public SampleHolder(View itemView) {
super(itemView);
}
}
2) Again create RecyclerView that does nothing :)
// 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) Now when your real recycler is not ready just use the sample one like below.
RecyclerView myRecycler = (RecyclerView) findViewById(R.id.recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
myRecycler.setAdapter(new SampleRecycler());
This is not best solution though but it works! Hope this is helpful.
It happens when you are not setting the adapter during the creation phase:
#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);
....
}
Just move setting the adapter into onCreate with an empty data and when you have the data call:
mAdapter.notifyDataSetChanged();
Check if you have missed to call this method in your adapter
#Override
public int getItemCount() {
return list.size();
}
In Kotlin we had this weird illogical issue.
This didn't work:
mBinding.serviceProviderCertificates.apply {
adapter = adapter
layoutManager = LinearLayoutManager(activity)
}
While this worked:
mBinding.serviceProviderCertificates.adapter = adapter
mBinding.serviceProviderCertificates.layoutManager = LinearLayoutManager(activity)
Once I get more after work hours, I will share more insights.
Make sure you set the layout manager for your RecyclerView by:
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
Instead of LinearLayoutManager, you can use other layout managers too.
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
Just replace above code with this and it should work. What you did wrong is you called setAdapter(adapter) before calling layout manager.
I had the same error I fixed it doing this if you are waiting for data like me using retrofit or something like that
Put before Oncreate
private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;
Put them in your 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);
When you receive data put
adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);
Now go in your ArtistArrayAdapter class and do this what it will do is if your array is empty or is null it will make GetItemCount return 0 if not it will make it the size of artists array
#Override
public int getItemCount() {
int a ;
if(artists != null && !artists.isEmpty()) {
a = artists.size();
}
else {
a = 0;
}
return a;
}
For those who use the RecyclerView within a fragment and inflate it from other views: when inflating the whole fragment view, make sure that you bind the RecyclerView to its root view.
I was connecting and doing everything for the adapter correctly, but I never did the binding.
This answer by #Prateek Agarwal has it all for me, but here is more elaboration.
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);
return rootView;
}
These Lines must be in OnCreate:
mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
This happens because the actual inflated layout is different from that which is being referred by you while finding the recyclerView. By default when you create the fragment, the onCreateView method appears as follows:
return inflater.inflate(R.layout.<related layout>,container.false);
Instead of that, separately create the view and use that to refer to recyclerView
View view= inflater.inflate(R.layout.<related layout>,container.false);
recyclerview=view.findViewById(R.id.<recyclerView ID>);
return view;
In my layout xml file, the bottom line with layoutManager was missing. The error disappeared after I added it.
<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"/>
First initialize the adapter
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);
}
When ever there is a change in the dataset set, just call the updateComments method.
I had this error, and I tried to fix for a while until I found the solution.
I made a private method buildRecyclerView, and I called it twice, first on onCreateView and then after my callback (in which I fetch data from an API). This is my method buildRecyclerView in my Fragment:
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);
}
Besides, I have to modify the method get-Item-Count in my adapter, because On on-Create-View the list is null and it through an error. So, my get-Item-Count is the following:
#Override
public int getItemCount() {
try {
return mLoanList.size();
} catch (Exception ex){return 0;}
}
This is really a simple error you are getting, there in no need of doing any codes in this.
This error occurs due to the wrong layout file used by the activity. By IDE i automatically created a layout v21 of a layout which became a default layout of the activity.
all codes I did in the old layout file and new one was only having few xml codes, which led to that error.
Solution: Copy all codes of old layout and paste in layout v 21
In my case, I was setting the adapter inside onLocationChanged() callback AND debugging in the emulator. Since it didn't detected a location change it never fired. When I set them manually in the Extended controls of the emulator it worked as expected.
I have solved this error. You just need to add layout manager
and add the empty adapter.
Like this 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
//}
Just add the following to RecyclerView
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
Example:
<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>
In case you're getting still error while using ViewBinding, make sure you're using the binding to return the inflated view ie
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return fragmentBinding.getRoot();
}
In my situation it was a forgotten component which locates in ViewHolder class but it wasn't located in layout file
I had the same problem and realized I was setting both the LayoutManager and adapter after retrieving the data from my source instead of setting the two in the onCreate method.
salesAdapter = new SalesAdapter(this,ordersList);
salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
salesView.setAdapter(salesAdapter);
Then notified the adapter on data change
//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();
}
This issue is because you are not adding any LayoutManager for your RecyclerView.
Another reason is because you are calling this code in a NonUIThread. Make sure to call this call in the UIThread.
The solution is only you have to add a LayoutManager for the RecyclerView before you setAdapter in the UI Thread.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Solved by setting the initialized empty list and adapter at the bottom and calling notifyDataSetChanged when results are fetched.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
recyclerviewItems.setLayoutManager(linearLayoutManager);
someAdapter = new SomeAdapter(getContext(),feedList);
recyclerviewItems.setAdapter(someAdapter);
I lost 16 minutes of my life with this issue, so I'll just admit to this incredibly embarrassing mistake that I was making- I'm using Butterknife and I bind the view in onCreateView in this fragment.
It took a long time to figure out why I had no layoutmanager - but obviously the views are injected so they won't actually be null, so the the recycler will never be null .. 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));
}
If you are getting an issue like this trace your view and use something like uiautomatorviewer
In my case it happened cause i embedded a RecyclerView in a LinearLayout.
I previously had a layout file only containing one root RecyclerView as follows
<?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"/>
I believe the problem is within the 3 lines separated. Anyway, I think its a simple problem, ill be working on it tomorrow; thought i should write what i found before forgetting about this thread.
Adding yet another answer since I came across this thread googling the error. I was trying to initialize a PreferenceFragmentCompat but I forgot to inflate the preference XML in onCreatePreferences like this:
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)
}
}
The error was a mystery until I realized that PreferenceFragmentCompat must be using a RecyclerView internally.
// It happens when you are not setting the adapter during the creation phase: call notifyDataSetChanged() when api response is getting Its Working
#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();

No adapter attached; skipping layout error [duplicate]

Just implemented RecyclerView in my code, replacing ListView.
Everything works fine. The data is displayed.
But error messages are being logged:
15:25:53.476 E/RecyclerView: No adapter attached; skipping layout
15:25:53.655 E/RecyclerView: No adapter attached; skipping layout
for the following code:
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
As you can see I have attached an adapter for RecyclerView.
So why do I keep getting this error?
I have read other questions related to the same problem but none of them help.
Can you make sure that you are calling these statements from the "main" thread outside of a delayed asynchronous callback (for example inside the onCreate() method).
As soon as I call the same statements from a "delayed" method. In my case a ResultCallback, I get the same message.
In my Fragment, calling the code below from inside a ResultCallback method produces the same message. After moving the code to the onConnected() method within my app, the message was gone...
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
I was getting the same two error messages until I fixed two things in my code:
(1) By default, when you implement methods in the RecyclerView.Adapter it generates:
#Override
public int getItemCount() {
return 0;
}
Make sure you update your code so it says:
#Override
public int getItemCount() {
return artists.size();
}
Obviously if you have zero items in your items then you will get zero things displayed on the screen.
(2) I was not doing this as shown in the top answer: CardView layout_width="match_parent" does not match 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:
Also make sure you set up your RecyclerView like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
NOT like this:
<view
android:id="#+id/RecyclerView"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I have seen some tutorials using the latter method. While it works I think it generates this error too.
I have the same situation with you, display is ok, but error appear in the locat.
That's my solution:
(1) Initialize the RecyclerView & bind adapter ON CREATE()
RecyclerView mRecycler = (RecyclerView) this.findViewById(R.id.yourid);
mRecycler.setAdapter(adapter);
(2) call notifyDataStateChanged when you get the data
adapter.notifyDataStateChanged();
In the recyclerView's source code, there is other thread to check the state of data.
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();
}
}
}
};
In the dispatchLayout(), we can find there is the error in it:
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 {
i have this problem , a few time problem is recycleView put in ScrollView object
After checking implementation, the reason appears to be the following. If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and, as a result, gets equal to minimum height (as per implementation) which is apparently zero.
You have couple of options for fixing this:
Set a certain height to RecyclerView
Set ScrollView.fillViewport to true
Or keep RecyclerView outside of ScrollView. In my opinion, this is the best option by far. If RecyclerView height is not limited - which is the case when it's put into ScrollView - then all Adapter's views have enough place vertically and get created all at once. There is no view recycling anymore which kinda breaks the purpose of RecyclerView .
(Can be followed for android.support.v4.widget.NestedScrollView as well)
1) Create ViewHolder that does nothing :)
// SampleHolder.java
public class SampleHolder extends RecyclerView.ViewHolder {
public SampleHolder(View itemView) {
super(itemView);
}
}
2) Again create RecyclerView that does nothing :)
// 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) Now when your real recycler is not ready just use the sample one like below.
RecyclerView myRecycler = (RecyclerView) findViewById(R.id.recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
myRecycler.setAdapter(new SampleRecycler());
This is not best solution though but it works! Hope this is helpful.
It happens when you are not setting the adapter during the creation phase:
#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);
....
}
Just move setting the adapter into onCreate with an empty data and when you have the data call:
mAdapter.notifyDataSetChanged();
Check if you have missed to call this method in your adapter
#Override
public int getItemCount() {
return list.size();
}
In Kotlin we had this weird illogical issue.
This didn't work:
mBinding.serviceProviderCertificates.apply {
adapter = adapter
layoutManager = LinearLayoutManager(activity)
}
While this worked:
mBinding.serviceProviderCertificates.adapter = adapter
mBinding.serviceProviderCertificates.layoutManager = LinearLayoutManager(activity)
Once I get more after work hours, I will share more insights.
Make sure you set the layout manager for your RecyclerView by:
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
Instead of LinearLayoutManager, you can use other layout managers too.
ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
Just replace above code with this and it should work. What you did wrong is you called setAdapter(adapter) before calling layout manager.
I had the same error I fixed it doing this if you are waiting for data like me using retrofit or something like that
Put before Oncreate
private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;
Put them in your 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);
When you receive data put
adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);
Now go in your ArtistArrayAdapter class and do this what it will do is if your array is empty or is null it will make GetItemCount return 0 if not it will make it the size of artists array
#Override
public int getItemCount() {
int a ;
if(artists != null && !artists.isEmpty()) {
a = artists.size();
}
else {
a = 0;
}
return a;
}
For those who use the RecyclerView within a fragment and inflate it from other views: when inflating the whole fragment view, make sure that you bind the RecyclerView to its root view.
I was connecting and doing everything for the adapter correctly, but I never did the binding.
This answer by #Prateek Agarwal has it all for me, but here is more elaboration.
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);
return rootView;
}
These Lines must be in OnCreate:
mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);
This happens because the actual inflated layout is different from that which is being referred by you while finding the recyclerView. By default when you create the fragment, the onCreateView method appears as follows:
return inflater.inflate(R.layout.<related layout>,container.false);
Instead of that, separately create the view and use that to refer to recyclerView
View view= inflater.inflate(R.layout.<related layout>,container.false);
recyclerview=view.findViewById(R.id.<recyclerView ID>);
return view;
In my layout xml file, the bottom line with layoutManager was missing. The error disappeared after I added it.
<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"/>
First initialize the adapter
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);
}
When ever there is a change in the dataset set, just call the updateComments method.
I had this error, and I tried to fix for a while until I found the solution.
I made a private method buildRecyclerView, and I called it twice, first on onCreateView and then after my callback (in which I fetch data from an API). This is my method buildRecyclerView in my Fragment:
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);
}
Besides, I have to modify the method get-Item-Count in my adapter, because On on-Create-View the list is null and it through an error. So, my get-Item-Count is the following:
#Override
public int getItemCount() {
try {
return mLoanList.size();
} catch (Exception ex){return 0;}
}
This is really a simple error you are getting, there in no need of doing any codes in this.
This error occurs due to the wrong layout file used by the activity. By IDE i automatically created a layout v21 of a layout which became a default layout of the activity.
all codes I did in the old layout file and new one was only having few xml codes, which led to that error.
Solution: Copy all codes of old layout and paste in layout v 21
In my case, I was setting the adapter inside onLocationChanged() callback AND debugging in the emulator. Since it didn't detected a location change it never fired. When I set them manually in the Extended controls of the emulator it worked as expected.
I have solved this error. You just need to add layout manager
and add the empty adapter.
Like this 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
//}
Just add the following to RecyclerView
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
Example:
<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>
In case you're getting still error while using ViewBinding, make sure you're using the binding to return the inflated view ie
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return fragmentBinding.getRoot();
}
In my situation it was a forgotten component which locates in ViewHolder class but it wasn't located in layout file
I had the same problem and realized I was setting both the LayoutManager and adapter after retrieving the data from my source instead of setting the two in the onCreate method.
salesAdapter = new SalesAdapter(this,ordersList);
salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
salesView.setAdapter(salesAdapter);
Then notified the adapter on data change
//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();
}
This issue is because you are not adding any LayoutManager for your RecyclerView.
Another reason is because you are calling this code in a NonUIThread. Make sure to call this call in the UIThread.
The solution is only you have to add a LayoutManager for the RecyclerView before you setAdapter in the UI Thread.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Solved by setting the initialized empty list and adapter at the bottom and calling notifyDataSetChanged when results are fetched.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
recyclerviewItems.setLayoutManager(linearLayoutManager);
someAdapter = new SomeAdapter(getContext(),feedList);
recyclerviewItems.setAdapter(someAdapter);
I lost 16 minutes of my life with this issue, so I'll just admit to this incredibly embarrassing mistake that I was making- I'm using Butterknife and I bind the view in onCreateView in this fragment.
It took a long time to figure out why I had no layoutmanager - but obviously the views are injected so they won't actually be null, so the the recycler will never be null .. 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));
}
If you are getting an issue like this trace your view and use something like uiautomatorviewer
In my case it happened cause i embedded a RecyclerView in a LinearLayout.
I previously had a layout file only containing one root RecyclerView as follows
<?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"/>
I believe the problem is within the 3 lines separated. Anyway, I think its a simple problem, ill be working on it tomorrow; thought i should write what i found before forgetting about this thread.
Adding yet another answer since I came across this thread googling the error. I was trying to initialize a PreferenceFragmentCompat but I forgot to inflate the preference XML in onCreatePreferences like this:
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)
}
}
The error was a mystery until I realized that PreferenceFragmentCompat must be using a RecyclerView internally.
// It happens when you are not setting the adapter during the creation phase: call notifyDataSetChanged() when api response is getting Its Working
#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();

Categories

Resources