This question already has answers here:
recyclerview No adapter attached; skipping layout
(38 answers)
Closed 3 years ago.
My recyclerView turns out to be blank when i try to load data from JSON.
In logcat, it says, "No adapter attached; skipping layout"
This is my activity
public class MainActivity extends AppCompatActivity {
private RecyclerView news;
private RecyclerView.Adapter news_adapter;
private List<News_Item> listItems;
private static final String news_data = "Url to Json file";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
news = (RecyclerView) findViewById(R.id.news);
news.setHasFixedSize(true);
news.setLayoutManager(new LinearLayoutManager(this));
listItems = new ArrayList<>();
loadRecyclerViewData();
}
private void loadRecyclerViewData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading News...");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET,
news_data,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("articles");
for(int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
News_Item item = new News_Item(
o.getString("title"),
o.getString("description"),
o.getString("author"),
o.getString("urlToImage"),
o.getString("URL")
);
listItems.add(item);
}
news_adapter = new News_Adapter(listItems,getApplicationContext());
news.setAdapter(news_adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
But it works fine when i load dummy data in it as follow
listItems = new ArrayList<>();
for(int i= 0; i<=10 ; i++){
News_Item news_item = new News_Item(
"Heading" + (i+1),
"Lorem Ipsum",
"Lorem Ipusm",
"Lorem Ipsum",
"Lorem Ipsum"
);
listItems.add(news_item);
}
news_adapter = new News_Adapter(listItems,this);
news.setAdapter(news_adapter);
I tried to read some other questions on here on stackoverflow, but most of them did't helped question 1,
question 2,
question 3
Here is my News_adapter
public class News_Adapter extends RecyclerView.Adapter<News_Adapter.ViewHolder> {
private List<News_Item> listItems;
private Context context;
public News_Adapter(List<News_Item> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final News_Item item = listItems.get(position);
holder.news_title.setText(item.getTitle());
holder.news_desc.setText(item.getSubtitle());
holder.news_author.setText(item.getAuthor());
Picasso.with(context)
.load(item.getImg_url())
.into(holder.news_img);
holder.card_body.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "item clicked "+item.getTitle() , Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView news_title,news_desc,news_author;
public ImageView news_img;
public RelativeLayout card_body;
public ViewHolder(View itemView) {
super(itemView);
news_author = (TextView) itemView.findViewById(R.id.news_author);
news_desc = (TextView) itemView.findViewById(R.id.news_desc);
news_title = (TextView) itemView.findViewById(R.id.news_title);
news_img = (ImageView) itemView.findViewById(R.id.news_img);
card_body = (RelativeLayout) itemView.findViewById(R.id.card_body);
}
}
}
Put the lines -
news_adapter = new News_Adapter(listItems,getApplicationContext());
news.setAdapter(news_adapter);
in your onCreate() method just before your loadRecyclerViewData() call
So onCreate() is like -
listItems = new ArrayList<>();
news_adapter = new News_Adapter(listItems,getApplicationContext());
news.setAdapter(news_adapter);
loadRecyclerViewData();
Then in your onResponse() method do news_adapter.notifyDataSetChanged(); instead of the above 2 lines.
UPDATE 1
Replace your line o.getString("URL") with o.getString("url"). Also instead of using getString always use optString so that if some info is not coming from JSON, your code doesn't break.
Related
when I send new data or update the info, how can to change my recycle view?
I have used a dapter.notifyDataSetChanged(); , but it's not working...
I tried more method, but it all cannot change my recycler view
in my code
recyclerView = view.findViewById(R.id.recyclerCoin);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
listCoinDiamondModel = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity());
getData();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
private void sendGift(String postUserID) {
final String postUserIDD = postUserID;
final String GiftAmount = this.GiftAmount.getText().toString().trim();
final String flag = "1";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_GIFTCOIN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
if (success.equals("1")){
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),"Error" + error.toString(), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Log.d("FID", fid);
params.put("fid", fid);
params.put("GiftAmount", GiftAmount);
params.put("flag", flag);
params.put("postUserID", postUserIDD);
params.put("uid", getID);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Load...");
progressDialog.dismiss();
final String GROUP_LIST = "https://example.com/aaa.php?flag=1&fid="+ getActivity().getIntent().getStringExtra("fid") +"&page="+requestCount;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(GROUP_LIST,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), "No More gift Available", Toast.LENGTH_SHORT).show();
}
});
//Returning the request
return jsonArrayRequest;
}
//This method will get data from the web api
private void getData() {
requestQueue.add(getDataFromServer(requestCount));
requestCount++;
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the newFeedModel object
final CoinDiamondModel coinDiamondModel = new CoinDiamondModel();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
String TAG_Coin = "Coin";
String TAG_Diamond = "Diamond";
String TAG_UserName = "UserName";
String TAG_UserPhoto = "UserPhoto";
String TAG_UserID = "UserID";
//Log.d("NAME111", json.getString(json.getString(TAG_UserName)));
coinDiamondModel.setCoin(json.getString(TAG_Coin));
coinDiamondModel.setDiamond(json.getString(TAG_Diamond));
coinDiamondModel.setGiftFromUserName(json.getString(TAG_UserName));
coinDiamondModel.setGiftFromUserPhoto(json.getString(TAG_UserPhoto));
coinDiamondModel.setGiftFromUserID(json.getString(TAG_UserID));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the newFeedModel object to the list
listCoinDiamondModel.add(coinDiamondModel);
//adapter.addTheCoinData(coinDiamondModel);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
who knows what's happen and how can solve this?
could you told me how can I do, please?
adapter all code
public class CoinAdapter extends RecyclerView.Adapter<CoinAdapter.ViewHolder> {
private ImageLoader imageLoader;
private List<CoinDiamondModel> newcoinDiamondLists;
private RequestManager glide;
private Context context;
SessionManager sessionManager;
private String getID,memail;
public CoinAdapter(List<CoinDiamondModel> newcoinDiamondLists, Context context) {
this.newcoinDiamondLists = newcoinDiamondLists;
this.glide = Glide.with(context);
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.coinlist, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
sessionManager = new SessionManager(getApplicationContext());
sessionManager.checkLogin();
HashMap<String, String> user = sessionManager.getUserDetail();
getID = user.get(sessionManager.USERID);
memail = user.get(sessionManager.EMAIL);
//String gid = getIntent.getStringExtra("xxx");
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
CoinDiamondModel newCoinDiamondModel = newcoinDiamondLists.get(position);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
holder.userName.setText(newCoinDiamondModel.getGiftFromUserName());
holder.userID.setText(newCoinDiamondModel.getGiftFromUserID());
holder.coinCount.setText(" x "+newCoinDiamondModel.getCoin());
glide.load(newCoinDiamondModel.getGiftFromUserPhoto()).into(holder.userPhoto);
}
#Override
public int getItemCount() {
return newcoinDiamondLists.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
CircleImageView userPhoto;
TextView userName,userID,coinCount;
ImageView coinImg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
userPhoto = (CircleImageView) itemView.findViewById(R.id.userPhoto);
userName = (TextView) itemView.findViewById(R.id.userName);
coinCount = (TextView) itemView.findViewById(R.id.coinCount);
userID = (TextView) itemView.findViewById(R.id.userID);
coinImg = (ImageView) itemView.findViewById(R.id.coinImg);
}
}
public void addTheCoinData(CoinDiamondModel coinDiamondModel){
if(coinDiamondModel!=null){
newcoinDiamondLists.add(coinDiamondModel);
notifyDataSetChanged();
}else {
throw new IllegalArgumentException("無資料!");
}
}
}
you can again set the adapter to recycler view after the response of the server
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
}
solution 2:
in your adapter write a function to update you list
and call function in activity
add this function to the adapter
public void updateList(List<CoinDiamondModel> list){
newcoinDiamondLists = list;
notifyDataSetChanged();
}
and call a function updateList of when you need an update recyclerview
The RecyclerView initialization and notifyDataSetChanged() is used properly. As your question is not clear enough about the Adapter implementation of the RecyclerView, I can give you several suggestions to check.
In RecyclerView.Adapter check if getItemCount() method is properly overriden with returning the list length (not 0) like below:
#Override
public int getItemCount() {
return listdata.length;
}
In RecyclerView.Adapter check if onCreateViewHolder method is properly overriden with proper xml layout like below:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.coin_xml_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
In RecyclerView.Adapter check if RecyclerView.ViewHolder class is properly extended
and linked the UI elements from the xml with the adapter like below:
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView coinTextView;
public ViewHolder(View itemView) {
super(itemView);
this.coinTextView = (TextView) itemView.findViewById(R.id.coinTextView);
}
}
In RecyclerView.Adapter check if onBindViewHolder method is properly overridden and updated the list component UI properly like below:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MyListData myListData = listdata[position];
holder.cointTextView.setText(listdata[position].getCoin());
}
Debug with a breakpoint and check if the listCoinDiamondModel.add(coinDiamondModel) is calling or not and coinDiamondModel object is not empty.
The RecyclerView is placed properly in the activity xml, like the RecyclerView is Visible, has a decent size to show list elements. As an example:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
you can update your adapter list manually like this:(write this function in your adapter)
public void updateCoinAdapterList(ArrayList<listCoinDiamondModel> recyclerItemsList) {
this.recyclerItemsList = recyclerItemsList;
this.notifyDataSetChanged();
}
you must set your adapter global variable and initialize it in OnCreate or OnResume, and call
adapter.updateCoinAdapterList(listCoinDiamondModel);
when your list changed
I want that when anyone click on the CardView with Status=undone there should run an API and the database is updated and the refreshed data is loaded in RecyclerView.
This is my UpdateStatus.class having the RecyclerView data:
TextView Cid,Tno,Tname,Cono,Work;
private static final String
URL_GETDATA="";
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_status);
Bundle bundle = getIntent().getExtras();
String cid = bundle.getString("checkID");
String tno = bundle.getString("trainno");
String tname = bundle.getString("trainname");
String cno = bundle.getString("coachno");
String works = bundle.getString("work");
Cid=(TextView)findViewById(R.id.idValue);
Cid.setText(cid);
Tno=(TextView)findViewById(R.id.tnoValue);
Tno.setText(tno);
Tname=(TextView)findViewById(R.id.tnameValue);
Tname.setText(tname);
Cono=(TextView)findViewById(R.id.cnoValue);
Cono.setText(cno);
Work=(TextView)findViewById(R.id.workValue);
Work.setText(works);
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listItems=new ArrayList<>();
loadRecyclerViewData();
}
private void loadRecyclerViewData(){
final AlertDialog dialog=new SpotsDialog(this, "Loading Data ...");
dialog.show();
StringRequest stringRequest=new StringRequest(Request.Method.POST, URL_GETDATA,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.dismiss();
Log.v("Response",response);
try {
JSONArray jsonArray=new JSONArray(response);
for (int i=0;i<jsonArray.length();i++){
ListItem item;
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.getString("status").equals("done")){
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.done
);
}else {
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.update
);
}
listItems.add(item);
}
adapter=new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() {
Bundle bundle = getIntent().getExtras();
// Posting params to login url
Map<String, String> params = new HashMap<String, String>();
params.put("checkID",bundle.getString("checkID"));
return params;
}
};
RequestQueue requestQueue= Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
This is my Adapter.class where the CardView data is loaded onClick on Card the Status is checked and An API will run using Volley and UpdateStatus activity must be refreshed with new data:
private List<ListItem> listItems;
private Context context;
private static final String
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final ListItem listItem=listItems.get(position);
holder.planned.setText(listItem.getPlanned());
holder.actual.setText(listItem.getActual());
holder.status.setImageResource(listItem.getmImageResourceid());
Intent i=new Intent(context,UpdateStatus.class);
holder.status.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(listItem.getStatus().equals("undone")){
//update code here
}
Toast.makeText(context,"You Clicked "+listItem.getStatus(),Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView planned,actual;
public ImageView status;
public LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
planned=(TextView)itemView.findViewById(R.id.planned_date);
actual=(TextView)itemView.findViewById(R.id.actual_date);
status=(ImageView)itemView.findViewById(R.id.status);
linearLayout=(LinearLayout)itemView.findViewById(R.id.linearLayout);
}
}
In OnResponse from volley when you adding a new data to your recyclerView just called a method recyclerView.notifyDataSetChanged() after recyclerView.setAdapter(adapter)
see the changes in you code below-:
#Override
public void onResponse(String response) {
dialog.dismiss();
Log.v("Response",response);
try {
JSONArray jsonArray=new JSONArray(response);
for (int i=0;i<jsonArray.length();i++){
ListItem item;
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.getString("status").equals("done")){
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.done
);
}else {
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.update
);
}
listItems.add(item);
}
adapter=new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(adapter);
recyclerView.notifyDataSetChanged()
} catch (JSONException e) {
e.printStackTrace();
}
}
},
Or for better user experience you can use recyclerView.notifyItemInserted(int position) instead of recyclerView.notifyDataSetChanged(). see documentation
I'm traying to get data from my mysql database and display them in a list view but the probleme is that the list view show only one attribut and for the others i have an error:RecyclerView: No adapter attached; skipping layout
this is my adapter :
public class DerpAdapter extends RecyclerView.Adapter<DerpAdapter.DerpHolder>{
private List<ListItem> ListData;
private LayoutInflater inflater;
private ItemClickCallback itemClickCallback;
public interface ItemClickCallback{
void onItemClick(int p);
void onSecondaryIconClick(int p);
}
public void setItemClickCallback(final ItemClickCallback itemClickCallback){
this.itemClickCallback = itemClickCallback;
}
public DerpAdapter(List<ListItem> listData, Context c){
this.inflater = LayoutInflater.from(c);
this.ListData = listData;
}
#Override
public DerpHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row,parent,false);
return new DerpHolder(view);
}
#Override
public void onBindViewHolder(DerpHolder holder, int position) {
ListItem item = ListData.get(position);
holder.title.setText(item.getTitle());
holder.subtitle.setText(item.getSubtitle());
holder.gaga.setText(item.getGaga());
}
#Override
public int getItemCount() {
return ListData.size();
}
class DerpHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView title;
private TextView subtitle;
private TextView gaga;
public DerpHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.lbl_item_text);
subtitle = (TextView) itemView.findViewById(R.id.lbl_item_sub_title);
gaga = (TextView) itemView.findViewById(R.id.gaga);
}
#Override
public void onClick(View view) {
/* if(view.getId() == R.id.cont_item_root){
}else{
}*/
}
}
this is my list item:
public class ListItem {
private String title;
private String subtitle;
private String gaga;
public String getGaga() {
return gaga;
}
public void setGaga(String gaga) {
this.gaga = gaga;
}
public ListItem(String title, String subtitle, String gaga) {
this.title = title;
this.subtitle = subtitle;
this.gaga = gaga;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getSubtitle() {
return subtitle;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
and finally this is my mainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DerpAdapter adapter;
private final String url_Data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
List<ListItem> data ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.drawarlist);
//Layout Manager: GridLayoutManager or StaggerdeGridLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
loadData();
}
public void loadData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading Data");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url_Data,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("soucat");
data = new ArrayList<>();
for (int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
ListItem item = new ListItem(o.getString("soucat"),"hello","fefe");
data.add(item);
}
adapter = new DerpAdapter(data,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
First, your initial setting of the adapter variable is commented out:
//adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
This will always set the adapter to null, you need to change it to this:
adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
Also, I don't see a call to start the Volley RequestQueue, make sure you are calling requestQueue.start(); before adding the stringRequest.
Then verify that that code for setting the adapter is being executed. You may always be hitting the ErrorListener which never sets the adapter.
You are trying to set null reference adapter to the RecyclerView, firstly you initialize adapter then set into the RecyclerView.
#Bobbake4 this is the code:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DerpAdapter adapter;
private final String url_Data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
List<ListItem> data ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.drawarlist);
//Layout Manager: GridLayoutManager or StaggerdeGridLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
loadData();
}
public void loadData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading Data");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url_Data,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("soucat");
data = new ArrayList<>();
for (int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
ListItem item = new ListItem(o.getString("soucat"),"hello","fefe");
data.add(item);
}
adapter = new DerpAdapter(data,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.start();
requestQueue.add(stringRequest);
}
I am trying to display news received from a json data source. But, I am getting an error when I try to parse the data.
The json data looks something like this:
click here to view
Here is the class I wrote for parsing :
public class FragmentUniversityNews extends Fragment {
private String TAG = FragmentUniversityNews.class.getSimpleName();
private static final String endpoint = "https://api.myjson.com/bins/18smd";
private static final String endpoint_final = "http://srm-news-bot.herokuapp.com";
private SwipeRefreshLayout swipeRefreshLayout;
private SimpleStringRecyclerViewAdapter mAdapter;
private JsonObjectRequest req;
String[] titles = new String[15];
String[] snips = new String[15];
String[] links = new String[15];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RecyclerView recyclerView;
View rootView = inflater.inflate(R.layout.fragment_university_news, container, false);
//((ActivityMain) getActivity()).showFloatingActionButton();
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view_university);
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setColorSchemeResources(R.color.red500, R.color.black, R.color.google_blue_900);
mAdapter = new SimpleStringRecyclerViewAdapter(getContext(), titles, snips, links);
// Calling another function which has the details
setupRecyclerView(recyclerView);
// Make it look like something is happening
swipeRefreshLayout.setRefreshing(true);
// Make the request!
makeJSONRequest();
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// onRefresh action here
swipeRefreshLayout.setRefreshing(true);
makeJSONRequest();
}
});
return rootView;
}
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
}
public void makeJSONRequest() {
req = new JsonObjectRequest(endpoint_final,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
// Getting JSON Array node
JSONArray newsItems = response.getJSONArray("newsItems");
// UI
try {
for (int j = 0; j < newsItems.length(); j++) {
JSONObject newsItem = newsItems.getJSONObject(j);
titles[j] = newsItem.getString("title");
snips[j] = newsItem.getString("snip");
links[j] = newsItem.getString("link");
}
swipeRefreshLayout.setRefreshing(false);
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
Toast.makeText(getContext(), "JSON Parsing error", Toast.LENGTH_LONG).show();
} mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
Toast.makeText(getContext(), "Error Receiving News", Toast.LENGTH_LONG).show();
}
});
// Adding request to request queue
InitializeVolley.getInstance().addToRequestQueue(req);
}
public static class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
private String[] mTitles, mSnips, mLinks;
private Context mContext;
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mTextViewTitle, mTextViewSnip;
public ViewHolder(View view) {
super(view);
mView = view;
mTextViewTitle = (TextView) view.findViewById(R.id.univ_news_title);
mTextViewSnip = (TextView) view.findViewById(R.id.univ_news_snip);
}
}
// Constructor
public SimpleStringRecyclerViewAdapter(Context context, String[] Titles, String[] Snips, String[] Links) {
mContext = context;
mTitles = Titles;
mSnips = Snips;
mLinks = Links;
}
public String getTitleAt(int position) {
return mTitles[position];
}
public String getSnipAt(int position) {
return mSnips[position];
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_view_univ, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mTextViewTitle.setText(getTitleAt(position));
holder.mTextViewSnip.setText(getSnipAt(position));
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//startScan();
Context context = v.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mLinks[holder.getAdapterPosition()]));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mTitles.length;
}
}
}
The error I am getting in Android Studio is at the line "JSONArray newsItems = response.getJSONArray("newsItems");",
It's saying
Unhandled exception:org.json.JSONException
When I move JSONArray newsItems = response.getJSONArray("newsItems"); in "try" block, it says
`Cannot resolve constructor 'JsonObjectRequest(java.lang.String, anonymous com.android.volley.Response.Listener<org.json.JSONObject>, anonymous com.android.volley.Response.ErrorListener)'`
Isolating just the parsing part out of your code I couldn't reproduce the error, here is my code:
String jsonStr = "";//TODO insert JSON sample from link
JSONObject jsonObj = null;
try {
jsonObj = new JSONObject(jsonStr);
JSONArray newsItems = jsonObj.getJSONArray("newsItems");
for (int j = 0; j < newsItems.length(); j++) {
JSONObject newsItem = newsItems.getJSONObject(j);
Log.d(TAG,
"Title: " +newsItem.getString("title") +
"\nSnip: " + newsItem.getString("snip") +
"\nLink: " +newsItem.getString("link")
);
}
} catch (JSONException e) {
e.printStackTrace();
}
There is either an error while retrieving the content directly as a JSONObject, or anything unrelated to the JSON parsing.
To help you out further it would be great to have an errorlog, as mentioned by Kris Roofe already.
I solved my problem by adding "null" in the JSONObjectRequest function. I didn't understand why.
public void makeJSONRequest() {
req = new JsonObjectRequest(endpoint_final, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
I am creating an app where there are 2 RecyclerView in one layout. I set one for category and second for text based on category. when i am debug my code that give me recyclerview display null value on this line recyclerView.setAdapter(adapter); in adapter see in image
I want to select category item then give the text that contain that category.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private List<TextJson> listtext;
private List<CategoryJson> horizentallylist;
private RecyclerView recyclerView , horizantalrcview;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
String textUrl = "http:www.extample.com/texturl.php";
String categoryUrl ="http:www.extample.com/categoryurl.php";
private static final String TAG = MainActivity.class.getSimpleName();
private JSONArray result;
ArrayAdapter<String> adapterSpin;
CategoryJson categoryJson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView_text);
horizantalrcview = (RecyclerView)findViewById(R.id.recyclerView_cate);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
listtext = new ArrayList<>();
horizentallylist = new ArrayList<>();
getData();
verticalData();
}
private void getData() {
final ProgressDialog loading = ProgressDialog.show(this, "Loading Data", "Please wait...", false, false);
loading.setCancelable(true);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(textUrl,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("text", "resopnce is =>" + response);
loading.dismiss();
verticalParse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
private void verticalParse(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
TextJson jsonitem = new TextJson();
JSONObject json = null;
try {
json = array.getJSONObject(i);
String text = json.getString("txt");
String txtcate = json.getString("category");
jsonitem.setText_status(text);
jsonitem.setCategory(txtcate);
Log.e("text", "is==> " + text);
Log.e("cate", "is==> " + txtcate);
} catch (JSONException e) {
e.printStackTrace();
}
listtext.add(jsonitem);
}
//Finally initializing our adapter
adapter = new VerticalAdapter(listtext, this);
adapter.notifyDataSetChanged();
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
private void verticalData() {
final ProgressDialog loading = ProgressDialog.show(this, "Loading Data", "Please wait...", false, false);
loading.setCancelable(true);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(categoryUrl,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("Response is", "first==>" + response);
loading.dismiss();
parseData(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof NoConnectionError) {
Log.e("NoConnectionError>>", "NoConnectionError....");
} else if (error instanceof AuthFailureError) {
Log.e("AuthFailureError>>>", "AuthFailureError...");
} else if (error instanceof ServerError) {
Log.e("ServerError>>>>>>>>>", "ServerError.......");
} else if (error instanceof NetworkError) {
Log.e("NetworkError>>>>>>>>>", "NetworkError.......");
} else if (error instanceof ParseError) {
Log.e("ParseError>>>>>>>>>", "ParseError.......");
} else if (error instanceof TimeoutError) {
Log.d("TimeoutError>>>>>>>>>", "TimeoutError.......");
}
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
CategoryJson model1 = new CategoryJson();
JSONObject json = null;
try {
json = array.getJSONObject(i);
String imgurl = json.getString("cat_img");
String imgname = json.getString("category");
Log.e("value in","link=>"+imgurl);
Log.e("value in","imagename=>"+imgname);
model1.setImageUrl(imgurl);
model1.setName(imgname);
} catch (JSONException e) {
e.printStackTrace();
}
horizentallylist.add(model1);
}
//Finally initializing our adapter
adapter = new HorizantalAdapter(horizentallylist, this);
adapter.notifyDataSetChanged();
//Adding adapter to recyclerview
horizantalrcview.setAdapter(adapter);
}
private void selectData() {
NewModel newModel = new NewModel();
final ProgressDialog loading = ProgressDialog.show(this, "Loading Data", "Please wait...", false, false);
loading.setCancelable(true);
String txtselect =newModel.getItem().toString();
String select_cate ="http:www.extample.com/filter.php"+selectitem;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(select_cate ,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("text", "resopnce is =>" + response);
loading.dismiss();
selectParse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
private void selectParse(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
TextJson jsonitem = new TextJson();
JSONObject json = null;
try {
json = array.getJSONObject(i);
String text = json.getString("txt");
String txtcate = json.getString("category");
jsonitem.setText_status(text);
jsonitem.setCategory(txtcate);
Log.e("text", "is==> " + text);
Log.e("cate", "is==> " + txtcate);
} catch (JSONException e) {
e.printStackTrace();
}
listtext.add(jsonitem);
}
//Finally initializing our adapter
adapter = new VerticalAdapter(listtext, this);
adapter.notifyDataSetChanged();
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
}
HorizantalAdapter
public class HorizantalAdapter extends RecyclerView.Adapter<HorizantalAdapter.ViewHolder> {
private ImageLoader imageLoader;
private Context context;
List<CategoryJson> listmodel;
NewModel newModel = new NewModel();
String link;
public HorizantalAdapter(List<CategoryJson> listmodel, Context context) {
super();
this.listmodel = listmodel;
this.context = context;
setHasStableIds(false);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.text_horigentally, parent, false);
HorizantalAdapter.ViewHolder viewHolder = new HorizantalAdapter.ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(final HorizantalAdapter.ViewHolder holder, final int position) {
CategoryJson imgModel = listmodel.get(position);
imageLoader =CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(imgModel.getImageUrl(),imageLoader.getImageListener(holder.imageView,R.drawable.placeholder,android.R.drawable.ic_dialog_alert));
holder.imageView.setImageUrl(imgModel.getImageUrl(),imageLoader);
holder.textViewName.setText(imgModel.getName());
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
link = listmodel.get(position).getName();
newModel.setItem(link);
Toast.makeText(context, "select item select" +link, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return listmodel.size();
}
public long getItemId(int position) {
return position;
}
class ViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView imageView;
public TextView textViewName;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageView_img);
imageView.setScaleType(NetworkImageView.ScaleType.FIT_CENTER);
textViewName = (TextView) itemView.findViewById(R.id.text_cate);
}
}
}
VerticalAdapter
public class VerticalAdapter extends RecyclerView.Adapter<VerticalAdapter.ViewHolder> {
private Context context;
String link;
List<TextJson> listmodel;
private Activity parentActivity;
public VerticalAdapter(List<TextJson> listmodel, Context context) {
super();
this.listmodel = listmodel;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.text_virtically, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
TextJson model = listmodel.get(position);
holder.textViewName.setText(model.getText_status());
holder.textViewName.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
link = listmodel.get(position).getText_status();
return true;
}
});
}
#Override
public int getItemCount() {
return listmodel.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.texting_status);
}
}
}
Log
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/text: is==> Stinging Jellyfish Come to Jersey, But Beaches Sti
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/cate: is==> speech
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/text: is==> Koala Facts for Kids | Australian Animals
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/cate: is==> motivational
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/text: is==> Antarctic penguins ielts reading passage
08-01 18:28:14.021 11378-11378/com.vm.recyclervirtical E/cate: is==> dance
08-01 18:28:14.061 11378-11378/com.vm.recyclervirtical E/Cache is: 0_0==>com.android.volley.toolbox.DiskBasedCache#41812ce8
08-01 18:28:24.861 11378-11378/com.vm.recyclervirtical E/text: resopnce is =>http://www.example.com/filtered/evideo/json/jsoncategory.php?category=motivational
08-01 18:28:25.331 11378-11378/com.vm.recyclervirtical E/text: resopnce is =>[{"txt":"Koala Facts for Kids | Australian Animals"}]
08-01 18:28:25.351 11378-11378/com.vm.recyclervirtical E/text: is==> Koala Facts for Kids | Australian Animals
Image
After debug
This is a broad problem, so I can suggest some basic approach, which is to pass the click listener into the constructor of the adapter.
public class HorizantalAdapter extends RecyclerView.Adapter<HorizantalAdapter.ViewHolder>
/*** Store a reference ***/
private View.OnClickListener clickListener;
/*** Add that reference ***/
public HorizantalAdapter(List<CategoryJson> listmodel, Context context, View.OnClickListener clickListener) {
super();
this.listmodel = listmodel;
this.context = context;
setHasStableIds(false);
/*** Set the reference ***/
this.clickListener = clickListener;
}
.......
#Override
public void onBindViewHolder(final HorizantalAdapter.ViewHolder holder, final int position) {
.........
/*** Use the reference ***/
holder.imageView.setOnClickListener(clickListener);
}
Then in the Activity, where you set the horizontal adapter
private void parseData(JSONArray array) {
.........
/*** Define the listener ***/
final View.OnClickListener horizontalClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
link = listmodel.get(position).getName();
newModel.setItem(link);
Toast.makeText(context, "select item select" +link, Toast.LENGTH_SHORT).show();
// TODO: Make Volley request for Categories here...
// Should be able to set other adapter in onResponse there
}
};
/*** Pass in the listener reference ***/
adapter = new HorizantalAdapter(horizentallylist, this, horizontalClickListener);
}
In response to the edit, the messages are coming from these lines
Log.e("text", "is==> " + text);
Log.e("cate", "is==> " + txtcate);