E/RecyclerView: No adapter attached; skipping layout Error 17 - java

Keep getting the following error:
E/RecyclerView: No adapter attached; skipping layout.
As you can see below I have the adapter set but in the OnDataChange() Method I think this may be the issue as it needs to be in the OnCreate() method but I cannot seem to fix it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_judge);
RecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
RecyclerView.setHasFixedSize(true);
RecyclerView.setLayoutManager(new LinearLayoutManager(this));
ProgressCircle = findViewById(R.id.progress_circle);
mUploads = new ArrayList<>();
DatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
DatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
UploadClass upload =
postSnapshot.getValue(UploadClass.class);
mUploads.add(upload);
}
Adapter = new ImageAdapter(JudgeActivity.this, mUploads);
ProgressCircle.setVisibility(View.INVISIBLE);
RecyclerView.setAdapter(Adapter);
}

You set the adapter but did so too late. The view is loaded with no adapter because you're waiting for Firebase.
Ideally you should set your adapter initially, so remove the mUploads paramater in the constructor.
#Override
protected void onCreate(Bundle savedInstanceState) {
recyclerView = (RecyclerView) find...
recyclerView.setAdapter(new ImageAdapter(this));
...
}
Initially the adapter will have no data - but the RecyclerView will have an adapter solving your problem.
You can set the data later, if you store an instance of your adapter you can simply:
adapter.setUploads(mUploads)
in your Firebase call.

Related

No Adapter Attached Skipping layout error with RecyclerView Adapter

These are steps I am doing in this project:
First I am creating a user profile on Firebase
Once the profile is created, I am redirecting the user to another activity, where the user is creating a journal with Image
Then saving the journal with image on Firestore
Once the data is created on the user profile, I am trying to fetch the values from Firestore using RecyclerView Adapter
Then on a listing page I am trying to fetch all the values in an ArrayList--> here I am getting the error of No Adapter Attached
The ArrayList Activity file:
Initializing the recyclerView in OnCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_journal_list);
firebaseAuth= FirebaseAuth.getInstance();
user= firebaseAuth.getCurrentUser();
noJournalEntry= findViewById(R.id.list_no_thoughts);
journalList= new ArrayList<>();
recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
}
Invoking the RecyclerView in onStart:
#Override
protected void onStart() {
super.onStart();
//we are getting the user Id of the person who is logged in
collectionReference.whereEqualTo("userId", JournalApi.getInstance()
.getUserId())
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if(!queryDocumentSnapshots.isEmpty()) {
for(QueryDocumentSnapshot journals: queryDocumentSnapshots){
Journal journal = journals.toObject(Journal.class);
journalList.add(journal);
Toast.makeText(JournalListActivity.this,"UserId found", Toast.LENGTH_LONG).show();
}
// Invoke Recyclerview
journalRecyclerAdapter= new JournalRecyclerAdapter(JournalListActivity.this, journalList);
recyclerView.setAdapter(journalRecyclerAdapter);
journalRecyclerAdapter.notifyDataSetChanged();
} else {
noJournalEntry.setVisibility(View.VISIBLE);
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(JournalListActivity.this,"UserId NOT found", Toast.LENGTH_LONG).show();
}
});
}
}
As you can see that the RecyclerView is called fine, but the ArrayList is not loading.
The Error: E/RecyclerView: No adapter attached; skipping layout
I referred to various posts in Stackoverflow and followed the steps, not sure where I am going wrong.
I am adding screenshots here of the Arraylist file:
The RecyclerView adapter:
You are getting the following warning, not an error:
E/RecyclerView: No adapter attached; skipping layout
Because you are setting the adapter in a background thread. To solve this, you have to set the adapter outside the callback and inside it, just notify it about the changes. So please move the following lines of code:
journalRecyclerAdapter= new JournalRecyclerAdapter(JournalListActivity.this, journalist);
recyclerView.setAdapter(journalRecyclerAdapter);
Right after:
super.onStart();
And leave the following line as it is inside the callback:
journalRecyclerAdapter.notifyDataSetChanged();
And the warning will disapear.

I get the following error in my logcat "E/RecyclerView: No adapter attached; skipping layout" for my firebase recyclerview adapter [duplicate]

By the title of this question, its easily understandable that, the adapter of recyclerview is not set inside a UI thread. But in my case to avoid that I have tried doing it even on UI thread but still no luck.
I am using FirebaseUI for my app. Below is the code snippet:
public static void getUserFromUserId(#NonNull DatabaseReference dbRef, #NonNull String userId) {
dbRef.child(USERS).child(userId)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
FriendsActivity.this.runOnUiThread(new Handler() {
#Override
public void run() {
loadFriends(user);
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
FirebaseCrash.report(databaseError.toException());
}
});
}
private void loadFriends(User user) {
Query friendsRef = ; // your firebase DatabseReference path
FirebaseRecyclerAdapter<Friend, FriendViewHolder> adapter =
new FirebaseRecyclerAdapter<Friend, FriendViewHolder>(Friend.class,
R.layout.item_challenge, FriendViewHolder.class, friendsRef) {
#Override
protected void populateViewHolder(FriendViewHolder viewHolder, Friend model, int position) {
viewHolder.setFriendName(model.getName());
viewHolder.setFriendPic(FriendActivity.this, model.getProfilePic());
}
};
mRecyclerView.setAdapter(adapter);
}
My Activity's onCreate() method has below code related to RecyclerView:
mRecyclerView = (RecyclerView) findViewById(R.id.challenge_recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
I dont understand why even after calling loadFriends inside runOnUiThread, why the error still persists.
Any help is appreciated.
You need to attach your adapter when you initialize your RecyclerView and attach LayoutManager, etc.
loadFriends method should fetch data and add data to the adapter and then you should call notifyDataSetChanged or equivalent.
What you're doing here is incorrect. A recyclerview should always have an adapter attached. You just need to update the data in the adapter.
And that's what the error says E/RecyclerView﹕ No adapter attached; skipping layout. Because you have not attached adapter after attaching LayoutManager and you're attaching adapter at a later stage.
Did you try adding LayoutManager in your recyclerView?
Make sure you call setLayoutManager, like below.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
before setting adapter into recyclerView, otherwise it is not gonna work.
Source : - recyclerview-not-call-any-adapter-method

error: no suitable method found for setQuery(com.google.firebase.firestore.Query,Class<Note>)

I am trying to get data from the FirebaseFirestore and implement it in a cardview.
This is my code
public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference notebookRef = db.collection("Notebook");
//notebookref is my collection name in firebase.
private NoteAdapter adapter;
TextView tv_id;
TextView tv_attend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_id=findViewById(R.id.tv_id);
tv_attend=findViewById(R.id.tv_attend);
setUpRecyclerView();
}
private void setUpRecyclerView() {
Query query = notebookRef.orderBy("attend", Query.Direction.DESCENDING);
FirebaseRecyclerOptions<Note> options = new FirebaseRecyclerOptions.Builder<Note>()
.setQuery(query, Note.class)
.build();
adapter = new NoteAdapter(options);
RecyclerView recyclerView = findViewById(R.id.rv_one);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
I get this following error:
error: no suitable method found for setQuery(com.google.firebase.firestore.Query,Class<Note>)
Seems like I am issue with: FirebaseRecyclerOptions.Builder().setQuery(query, Note.class).build();
Any pointers about how to deal with this issue?
Check you import for Query. You should import
import com.google.firebase.firestore.Query;
More details
orderBy(String field, Query.Direction direction)
Creates and returns a new Query that's additionally sorted by the specified field, optionally in descending order instead of ascending.
Ref. https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/Query
Confirm your dependencies accordingly
dependencies {
// FirebaseUI for Firebase Realtime Database
implementation 'com.firebaseui:firebase-ui-database:6.2.0'
// FirebaseUI for Cloud Firestore
implementation 'com.firebaseui:firebase-ui-firestore:6.2.0'
// FirebaseUI for Firebase Auth
implementation 'com.firebaseui:firebase-ui-auth:6.2.0'
// FirebaseUI for Cloud Storage
implementation 'com.firebaseui:firebase-ui-storage:6.2.0'
}
Ref. https://github.com/firebase/FirebaseUI-Android
I had to change :
FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder()
to :
FirestoreRecyclerOptions options = new FirestoreRecyclerOptions.Builder()

How to make RecyclerView not scroll to the bottom each time an item is added to the list

I want my RecyclerView to be scrolled to the bottom when my chat loads up but when the user manually scrolls up the list to read previous messages it should not scroll back down again upon the addition of new item in the list unless the message(new item) is sent/added by the user himself.
I have tried using both layoutManager.setStackFromEnd(true) and recyclerView.scrollToPosition(list.size() - 1). Both of these methods automatically scroll down the list upon receiving a new message if I have scrolled up manually it should not scroll down to the bottom again unless im the one sending the message.
mref.child(RoomName).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1 :dataSnapshot.getChildren()) {
ChatMessage value = dataSnapshot1.getValue(ChatMessage.class);
ChatMessage fire = new ChatMessage();
String msgtxt = value.getMessageText();
String user=value.getMessageUser();
long msgtime=value.getMessageTime();
String prothumb=value.getProfuri();
String sentimguri=value.getSentimguri();
String type=value.getType();
fire.setMessageUser(user);
fire.setMessageText(msgtxt);
fire.setMessageTime(msgtime);
fire.setProfuri(prothumb);
fire.setSentimguri(sentimguri);
fire.setType(type);
list.add(fire);
}
adapter = new RecyclerViewAdapter(ChatRoom.this, list);
recyclerView.setAdapter(adapter);
//layoutManager.setStackFromEnd(true);
}
//Initializing RecyclerView
private void initRecyclerView() {
//Log.d(TAG, "initRecyclerView: init recyclerview.");
recyclerView =(RecyclerView) findViewById(R.id.list_of_messages);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//recyclerView.scrollToPosition(list.size() - 1);
}
}
Upon getting the chat list , you need not have to create the new instance of adapter everytime .Instead just notify the adapter about the change .
mref.child(RoomName).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list.clear();
for(DataSnapshot dataSnapshot1 :dataSnapshot.getChildren()) {
ChatMessage value = dataSnapshot1.getValue(ChatMessage.class);
ChatMessage fire = new ChatMessage();
String msgtxt = value.getMessageText();
String user=value.getMessageUser();
long msgtime=value.getMessageTime();
String prothumb=value.getProfuri();
String sentimguri=value.getSentimguri();
String type=value.getType();
fire.setMessageUser(user);
fire.setMessageText(msgtxt);
fire.setMessageTime(msgtime);
fire.setProfuri(prothumb);
fire.setSentimguri(sentimguri);
fire.setType(type);
list.add(fire);
}
if(!(recyclerView.canScrollVertically(1)))
{
recyclerView.smoothScrollToPosition(adapter.getItemCount());
}
adapter.notifyDataSetChanged();
//layoutManager.setStackFromEnd(true);
}
//Initializing RecyclerView
private void initRecyclerView() {
//Log.d(TAG, "initRecyclerView: init recyclerview.");
recyclerView =(RecyclerView) findViewById(R.id.list_of_messages);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//initialse your adapter only once
adapter = new RecyclerViewAdapter(ChatRoom.this, list);
recyclerView.setAdapter(adapter);
layoutManager.setStackFromEnd(true);
//recyclerView.scrollToPosition(list.size() - 1);
}
}
This might will solve your issue .
The issue I can see is that you are creating a new instance of adapter everytime when data changes. Which explains why it always scroll down to bottom. And it's not a proper way of using a recyclerView.
What you need to do is to create just one instance of adapter during initRecyclerView using an empty list. Then whenever data changes, update the existing list and then call adapter.notifyDataSetChanged(). This will give you the behaviour that you wanted.

RecyclerView: No adapter attached; skipping layout - recycleView error [duplicate]

This question already has answers here:
recyclerview No adapter attached; skipping layout
(38 answers)
No adapter attached; skipping layout [duplicate]
(2 answers)
Closed 3 years ago.
Its giving me "RecyclerView: No adapter attached; skipping layout" error but in my opinion adapter is correctly attached. Please help.
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private RecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
requestJsonObject();
}
private void requestJsonObject(){
RequestQueue queue = Volley.newRequestQueue(this);
String url ="https://api.myjson.com/bins/2t4j3";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Response " + response);
GsonBuilder builder = new GsonBuilder();
Gson mGson = builder.create();
List<ItemObject> posts = new ArrayList<ItemObject>();
posts = Arrays.asList(mGson.fromJson(response, ItemObject[].class));
adapter = new RecyclerViewAdapter(MainActivity.this, posts);
recyclerView.setAdapter(adapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error " + error.getMessage());
}
});
queue.add(stringRequest);
}
}
I was moving my methods, but its not working. I was looking here for answer but there was only problems with wrong implemented adapters. I dont't know whats wrong here.
Try to put this line:
adapter = new RecyclerViewAdapter(MainActivity.this, posts);
After adding a LayoutManager to the RecyclerView. Of course the list will be empty, but just init RecyclerAdapter and assign it to the RecyclerView
Then, when Volley completes it's request, use:
recyclerView.getAdapter().addAll(posts);
recyclerView.getAdapter().notifyDataSetChaged();
The last commands add elements to the RecyclerView's adapter and notify LayoutManager of the change.
You are calling setAdapter in a delay thread. When the view is created in the main thread, the Recyclerview do not have an adapter.
Put this two lines before setLayoutManager
List<ItemObject> posts = new ArrayList<ItemObject>();
adapter = new RecyclerViewAdapter(MainActivity.this, posts);
In onResponse, you can ethier set a new adpater or update the data in the adapter which depends on your implementation.

Categories