问题
Hi i've found some code on the internet and i'm trying to test it but i get this No adapter attached , skipping layout Error .I've searched for solutions in vain .
Here is my MainActivity class :
private ArrayList<Employee> employeeList;
private ProgressDialog pDialog;
private RecyclerView recyclerView;
private EmployeesAdapter eAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading Data.. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
//Creating an object of our api interface
ApiService api = RetroClient.getApiService();
/**
* Calling JSON
*/
Call<EmployeeList> call = api.getMyJSON();
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<EmployeeList>() {
@Override
public void onResponse(Call<EmployeeList> call, Response<EmployeeList> response) {
//Dismiss Dialog
pDialog.dismiss();
if (response.isSuccessful()) {
/**
* Got Successfully
*/
employeeList = response.body().getEmployee();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
eAdapter = new EmployeesAdapter(employeeList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(eAdapter);
}
}
@Override
public void onFailure(Call<EmployeeList> call, Throwable t) {
pDialog.dismiss();
}
});
}
I'm getting this error : E/RecyclerView: No adapter attached; skipping layout Any recommendations ?
回答1:
The error msg is clear .
you did't set adapter for your recyclerView when Activity is created. May you think that you have set adapter for recyclerView in the onCreate method , But there are two thread running, one is main thread ,another thread is the thread you set adapter for your recylerView. Which means the thread you set adapter for recylerView may block to get datas from network when recylerView need adapter be attached .
you can fix this problems as following codes !
private final ArrayList<Employee> employeeList = new ArrayList<>();
private ProgressDialog pDialog;
private RecyclerView recyclerView;
private EmployeesAdapter eAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
eAdapter = new EmployeesAdapter(employeeList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(eAdapter);
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading Data.. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
//Creating an object of our api interface
ApiService api = RetroClient.getApiService();
/**
* Calling JSON
*/
Call<EmployeeList> call = api.getMyJSON();
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<EmployeeList>() {
@Override
public void onResponse(Call<EmployeeList> call, Response<EmployeeList> response) {
//Dismiss Dialog
pDialog.dismiss();
if (response.isSuccessful()) {
/**
* Got Successfully
*/
employeeList.clear();
employeeList.addAll(response.body().getEmployee());
eAdapter.notifyDataSetChanged();
}
}
@Override
public void onFailure(Call<EmployeeList> call, Throwable t) {
pDialog.dismiss();
}
});
}
回答2:
Error is because of initializing recycerlview and adapter from a "delayed" method. so to solve this do as below:
First init your arraylist as below:
private ArrayList<Employee> employeeList = new ArrayList<>();
Initialize your recyclerview before api calling, means in main thread:
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
eAdapter = new EmployeesAdapter(employeeList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(eAdapter);
Then in your api response you should only update adapter if list found:
if(response != null && response.body() != null && response.body().getEmployee() != null){
employeeList.clear();
employeeList.addAll(response.body().getEmployee());
if(eAdapter != null){
eAdapter.notifyDataSetChanged();
}
}
回答3:
Always try to initialize objects, required classes, adapters like LinearLayoutManager first before calling background task. maybe that is creating a problem in your case.
I have made some changes in your code:
private ArrayList<Employee> employeeList;
private ProgressDialog pDialog;
private RecyclerView recyclerView;
private EmployeesAdapter eAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
employeeList = new ArrayList<>;
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
eAdapter = new EmployeesAdapter(employeeList);
RecyclerView.LayoutManager eLayoutManager = new
LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(eAdapter);
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading Data.. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
//Creating an object of our api interface
ApiService api = RetroClient.getApiService();
/**
* Calling JSON
*/
Call<EmployeeList> call = api.getMyJSON();
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<EmployeeList>() {
@Override
public void onResponse(Call<EmployeeList> call, Response<EmployeeList> response) {
//Dismiss Dialog
pDialog.dismiss();
if (response.isSuccessful()) {
/**
* Got Successfully
*/
if(!employeeList.isEmpty())employeeList.clear();
employeeList.addAll(response.body().getEmployee());
eAdapter.notifyDataSetChanged();
}
}
@Override
public void onFailure(Call<EmployeeList> call, Throwable t) {
pDialog.dismiss();
}
});
}
来源:https://stackoverflow.com/questions/55539865/no-adapter-attached-skipping-layout-error