0

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);

    }
}

}
Ishan hrx
  • 403
  • 8
  • 19

1 Answers1

0

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.

Kapil G
  • 4,081
  • 2
  • 20
  • 32
  • I got same result, but now the logcat says [this](https://drive.google.com/open?id=0B3bWuLhai5b_MmlCUzVLQTl5RG8) thanks for answer btw. – Ishan hrx Aug 07 '17 at 07:54
  • Are there any more error above and below it. This doesn't seem to be an issue. I am assuming you already have internet permission in your code – Kapil G Aug 07 '17 at 09:05
  • no, that is it.. this is the only errors i am getting in the logcat. `!!! FAILED BINDER TRANSACTION !!! (parcel size = 60)` seems to be the issue. I don't know what that is – Ishan hrx Aug 07 '17 at 09:07
  • So no adapter attached error is gone? but there is no data in RecyclerView – Kapil G Aug 07 '17 at 09:13
  • [this](https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey=89d429bd6563492ca780e6997cd96165) is the link i am using to get the JSON file. – Ishan hrx Aug 07 '17 at 09:28
  • Can you add the code of news adapter in your question – Kapil G Aug 07 '17 at 09:32
  • I just added the `News_adapter` code – Ishan hrx Aug 07 '17 at 09:50
  • i have updated the question with the `News_adapter` and here is my full [logcat](https://drive.google.com/open?id=0B3bWuLhai5b_TkU3eUdnaV9zNE0) – Ishan hrx Aug 07 '17 at 11:42
  • Your Log clearly states the error now. ITs in line org.json.JSONException: No value for URL. – Kapil G Aug 07 '17 at 11:49
  • @Ishanhrx 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 desosn't break. – Kapil G Aug 07 '17 at 11:50
  • @Ishanhrx Let me know if it works fine now but ideally should. And then please accept my answer :) – Kapil G Aug 07 '17 at 11:51