I am using a loader and a OkHttp client to get data from a news API and populate the data in a recycler view. I used a progress bar to show until the the loader is finished loading the data . But all I see is the progress bar, the recycler view is not showing up. Please help me
MainActivity.java
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<News>> {
private static final int LOADER_ID = 1 ;
private String url = "https://newsapi.org/v1/articles?source=the-times-of-india&sortBy=latest&apiKey=<API KEY>";
private ProgressBar progressBar;
private NewsAdapter mAdapter;
private RecyclerView recList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
recList = (RecyclerView) findViewById(R.id.cardList);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
recList.setHasFixedSize(true);
getSupportLoaderManager().initLoader(LOADER_ID , null , this);
}
@Override
public Loader<ArrayList<News>> onCreateLoader(int id, Bundle args) {
return new AsyncTaskLoader<ArrayList<News>>(this) {
@Override
public ArrayList<News> loadInBackground() {
return makeConnectionAndParseData(url);
}
};
}
@Override
public void onLoadFinished(Loader<ArrayList<News>> loader, ArrayList<News> data) {
progressBar.setVisibility(View.INVISIBLE);
mAdapter = new NewsAdapter(data);
recList.setAdapter(mAdapter);
// The data is brought back here after the network call is executed in the variable data.
// Update the recycler view here to show the list of news
// Take care of exception cases like no network connection , invalid url and other extreme cases
}
@Override
public void onLoaderReset(Loader<ArrayList<News>> loader) {
// Reset the recycler view . The UI should not show recycler view when the loader is reset
// Update the UI with a text view to let the user know about the error
}
private String makeNetworkConnection(String url)
{
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private ArrayList<News> parseJsonIntoArrayList(String json)
{
final ArrayList<News> newsArrayList;
try {
newsArrayList = null;
JSONObject object = new JSONObject(json);
JSONArray articles = object.getJSONArray("articles");
for (int i=0 ; i<articles.length() ; i++)
{
JSONObject articleObjects = articles.getJSONObject(i);
String author = articleObjects.getString("author");
String title = articleObjects.getString("title");
String desc = articleObjects.getString("description");
String imageUrl = articleObjects.getString("imageUrl");
String clickableUrl = articleObjects.getString("url");
newsArrayList.add(new News(title,desc,imageUrl,clickableUrl,author));
}
return newsArrayList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
private ArrayList<News> makeConnectionAndParseData(String url)
{
String jsonResponse = makeNetworkConnection(url);
return parseJsonIntoArrayList(jsonResponse);
}}
NewsAdapter.java
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
ArrayList<News> mNewsData;
public NewsAdapter(ArrayList<News> newsData)
{
mNewsData = newsData;
}
public class NewsHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView titleTv , descTv ;
private ImageView newsImageView;
public NewsHolder(View itemView) {
super(itemView);
titleTv = (TextView) itemView.findViewById(R.id.newsTitle);
descTv = (TextView) itemView.findViewById(R.id.newsDesc);
newsImageView = (ImageView) itemView.findViewById(R.id.newsImage);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// Handle the click item here.
}
}
@Override
public NewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflatedView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item , parent , false);
return new NewsHolder(inflatedView);
}
@Override
public void onBindViewHolder(NewsHolder holder, int position) {
News news = mNewsData.get(position);
holder.titleTv.setText(news.getNewsTitle());
holder.descTv.setText(news.getNewsSubtitle());
String imageUrl = news.getImageUrl();
Picasso.with(holder.newsImageView.getContext())
.load(imageUrl)
.into(holder.newsImageView);
}
@Override
public int getItemCount() {
return mNewsData.size();
}}
In android monitor , there was
01-10 14:55:59.319 10318-10318/com.sriram.news E/RecyclerView: No adapter attached; skipping layout
Please tell me where I have gone wrong And is my implementation of the recycler view correct? I'm still confused about recycler view.
Thanks in advance
Place
above
and fix NewsAdapter.java
MainActivity.java