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

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.

Related

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

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

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.

How to show json data in Listview with Retrofit2

I'm a newbie about Android programming :(
I have no idea to set Listview for show data
How to Show data in Listview.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "fong";
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UdacityService.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
UdacityService service = retrofit.create(UdacityService.class);
Call<UdacityCatalog> requestCatalog = service.listCatalog();
requestCatalog.enqueue(new Callback<UdacityCatalog>() {
#Override
public void onResponse(Call<UdacityCatalog> call, Response<UdacityCatalog> response) {
if (!response.isSuccessful()) {
Log.i(TAG,"Errorr: " +response.code());
}else{
UdacityCatalog catalog =response.body();
for (Course c : catalog.courses){
Log.i(TAG,c.title);
Log.i(TAG,"--------------");
}
}
}
#Override
public void onFailure(Call<UdacityCatalog> call, Throwable t) {
Log.e(TAG,"Errorr: " + t.getMessage());
}
});
}
}
I want to show data c.title in ListView
Log.i(TAG,c.title) show
I/fong: Richard Kalehoff
I/fong: Firebase Analytics: iOS
I/fong: Firebase Analytics: Android
Thanks for yor help :)
It`s easy, First you have to add a ListView component in your Layout:
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
And then, find it in your JAVA code and put it in a instance variable:
ListView listview;
//in your onCreate() after setContentView():
listview = (ListView) findViewById(R.id.list);
You have to create a list with all your titles:
List<String> courses = new ArrayList<>();
for (Course c : catalog.courses){
courses.add(c.title);
}
Now, you have to create a SimpleAdapter and pass your data to it:
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, android.r.layout.simple_list_item_1, courses);
And finally, add your adapter in your ListView:
listview.setAdapter(adapter);
Take a list of Course
List<Course> courseList = catalog.courses;
then make a custom list Adapter and from this list get the title and show it in textView of the list
textView.setText(courseList.get(position).title);

Android Java, null pointer exception on arraylist add() in onReceive broadcast receiver [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I'm trying to add a string to a listview, the string is being received via the broadcast receiver. whenever I try to do something on my arraylist or an adapter to my listview I get a null pointer exception.
public class DevScan extends AppCompatActivity {
MyReceiver rcvr;
String test;
ArrayList<String> devlist;
ArrayAdapter<String> Adapter;
ListView devLV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dev_scan);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
rcvr=new MyReceiver();
this.registerReceiver(rcvr, new IntentFilter("CUSTOM_INTENT"));
final UDP_service srv = new UDP_service(this);
srv.start();
final ArrayList<String> devlist = new ArrayList<>();
ListView devLV = (ListView) findViewById(R.id.devlistview);
devlist.add("elloooo");
final ArrayAdapter<String> Adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
devlist );
devLV.setAdapter(Adapter);
Button scanb1 = (Button) findViewById(R.id.scanbtn1);
scanb1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
devlist.clear();
Adapter.notifyDataSetChanged();
srv.Message="eloooo!";
srv.send();
}
});
}
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
test = intent.getExtras().getString("packet");
//it works fine when I put the Extra in a string variable
//these 3 cause NPE
// devlist.add(intent.getExtras().getString("packet"));
// devlist.add("foo");
// Adapter.notifyDataSetChanged();
Log.i("SOCK broadcast intent", test);
}
}
}
what I don't undsetand is why string variable 'test' is works fine with MyReceiver, but arraylist defined in the same way doesn't
soluton:
because of my lack of knowlage I redeclared my objects as local, by accident..
There are several possible errors in your code
1) The variables MyReceiver rcvr; String test; ArrayList<String> devlist;
ArrayAdapter<String> Adapter; and ListView devLV; are decleared but not initialize.
In your onCreate the above variable was initialize but with final constrains. You should initialize your variables on
before rcvr=new MyReceiver(); that is
final UDP_service srv = new UDP_service(this);
srv.start();
devlist = new ArrayList<>();
devLV = (ListView) findViewById(R.id.devlistview);
devlist.add("elloooo");
Adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
devlist );
devLV.setAdapter(Adapter);
new MyReceiver().onReceive(getApplicationContext(), new Intent().putExtra("packet", "expectedString"));
//it should work
2)Try 1 let see what happens

ProgressDialog shows before 2nd TabBar fragment is opened

I have 3 tabs in my main activity. In the 2nd tab I have a fragment that has a list and I am using Retrofit to get data from my server and display it in the list.
In my 2nd fragment I have:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_recents, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
getBooks();
}
private void getBooks(){
final ProgressDialog loading = ProgressDialog.show(getContext(), "Fetching Data", "Please wait...", false, false);
/* Retrofit code: */
//Creating a rest adapter
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ROOT_URL)
.build();
//Creating an object of our api interface
MyAPI api = adapter.create(MyAPI.class);
//Defining the method
api.getBooks(new Callback<List<MyPojo>>() {
#Override
public void success(List<MyPojo> list, Response response) {
//Dismissing the loading progressbar
loading.dismiss();
//Storing the data in our list
pojos = list;
mAdapter = new MyAdapter(getContext(), pojos);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void failure(RetrofitError error) {
//you can handle the errors here
loading.dismiss();
Log.v("Error: ", "" + error);
}
});
}
my problem is that the progress dialog is shown as soon as the app is launched in the 1st tab..I want it to fetch the data only when the 2nd tab is opened.
According to the developer guide for fragments, a fragment's lifecycle (see Figure 2 in the link) is only active (i.e. displayed and the user can interact with it) between the onResume() and onPause() android callbacks.
If you want something to only occur when the fragment is displayed, place the code for showing it in the onResume() callback. You can pre-fetch or do other setup in other callbacks if you like.
Put the network code in your second Fragment's onResume()
#Override
public void onResume() {
super.onResume();
final ProgressDialog loading = ProgressDialog.show(getContext(), "Fetching Data", "Please wait...", false, false);
(and the rest is the Retrofit code)
}

Categories