Reputation: 243
I have a recyclerView which is loading and showing the items that I want perfectly, but there is a delay (when the app is getting the xml news from the web and parsing them) and I want to have a progressBar showing up to indicate the user. The Progressbar is there but it never shows up.
Here is my code:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, SearchView.OnQueryTextListener {
private ArrayList<NewsItem> newsItems;
private ProgressBar updateProgressBar;
private RecyclerView newsItemsRecyclerView;
private NewsAdapter newsAdapter;
private SearchView searchView;
private NewsAddressProvider newsAddressProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hookUpScreenViews();
//making the list ready
newsItems = new ArrayList<>();
//getting the news
newsAddressProvider = new NewsAddressProvider();
getTheNews(newsAddressProvider.getGeneral());
//setting up the search view
searchView.setOnQueryTextListener(this);
}
private void getTheNews(ArrayList<String> addresses) {
for (String address : addresses) {
StringRequest stringRequest = new StringRequest(address, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
NewsXMLParser newsXMLParser = new NewsXMLParser(response);
newsXMLParser.parseNewsXml();
newsItems.addAll(newsXMLParser.getNewsItems());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(this).add(stringRequest);
}
updateRecyclerView(newsItems);
}
private void hookUpScreenViews() {
//setting the progressBar
updateProgressBar = findViewById(R.id.updateProgressBar);
newsItemsRecyclerView = findViewById(R.id.newsItemsRecyclerView);
searchView = findViewById(R.id.main_news_search_view);
}
private void updateRecyclerView(ArrayList<NewsItem> newsList) {
if (newsList != null) {
updateProgressBar.setVisibility(View.INVISIBLE);
}
newsAdapter = new NewsAdapter(newsList, this);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
newsItemsRecyclerView.setLayoutManager(layoutManager);
newsItemsRecyclerView.setAdapter(newsAdapter);
newsAdapter.notifyDataSetChanged();
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newsAdapter != null) {
newsAdapter.getFilter().filter(newText);
}
return true;
}
}
I also tried
if (newsList != null) {
updateProgressBar.setVisibility(View.GONE);
}
and this code as well:
if (newsList != null && newsList.size()>0) {
updateProgressBar.setVisibility(View.INVISIBLE);
}
I also used .GONE
with the second approach as well, But this time the ProgreesBar never goes, It just stays there and spinning all over , and when I try the Log.d, it says the newsList is empty!, while clearly there are values in it, and the recyclerView is showing them.
instead of .size()
I also checked with .isEmpty()
, but the result is still the same!
and here is the xml for the progressbar :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.MainActivity">
<android.support.v7.widget.RecyclerView
android:background="@color/transparent"
android:padding="5dp"
android:id="@+id/newsItemsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/mobileBanner"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:divider="@color/transparent"/>
<ProgressBar
android:id="@+id/updateProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:layout_gravity="top|center_horizontal"/>
</RelativeLayout>
Upvotes: 0
Views: 70
Reputation: 4848
The problem is you are basically calling updateProgressBar.setVisibility(View.INVISIBLE);
indirectly from onCreate()
The Volley
request is asynchronous so onResponse()
is called after the query is completed.
Basically your code runs like this: first from onCreate()
you are calling getTheNews()
which runs through the for
loop pretty much instantaneously (Volley is asyncronous). Then updateRecyclerView()
then updateProgressBar.setVisibility(View.INVISIBLE);
Since this goes really quickly you never see the ProggessBar
EDIT:
Add a class variable for the counter:
private int addressCounter = 0;
Now change your getTheNews()
method like this:
private void getTheNews(ArrayList<String> addresses) {
for (String address : addresses) {
StringRequest stringRequest = new StringRequest(address, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
NewsXMLParser newsXMLParser = new NewsXMLParser(response);
newsXMLParser.parseNewsXml();
newsItems.addAll(newsXMLParser.getNewsItems());
newsAdapter.notifyDataSetChanged();
if(addessCounter >= address.size()){
updateProgressBar.setVisibility(View.INVISIBLE);
}
//Increment the counter
addressCounter++;
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(addessCounter >= address.size()){
updateProgressBar.setVisibility(View.INVISIBLE);
}
//increment the counter here, too!
addressCounter++;
}
});
Volley.newRequestQueue(this).add(stringRequest);
}
}
You might also want to consider:
If you are going to use hookUpScreenViews()
to initialize your views why not go ahead and add searchView.setOnQueryTextListener(this);
? You can also add the code for setting up the RecyclerView
because it only needs to be called once.
private void hookUpScreenViews() {
//setting the progressBar
updateProgressBar = findViewById(R.id.updateProgressBar);
newsItemsRecyclerView = findViewById(R.id.newsItemsRecyclerView);
searchView = findViewById(R.id.main_news_search_view);
searchView.setOnQueryTextListener(this);
newsAdapter = new NewsAdapter(newsList, this);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
newsItemsRecyclerView.setLayoutManager(layoutManager);
newsItemsRecyclerView.setAdapter(newsAdapter);
}
DISCLAIMER: I have not tried this code so you may need to tweak it a bit.
EDIT: this is the working code:
public void onResponse(String response) {
addressCounter++;
NewsXMLParser newsXMLParser = new NewsXMLParser(response);
newsXMLParser.parseNewsXml();
newsItems.addAll(newsXMLParser.getNewsItems());
if (addressCounter>=addresses.size()){
updateRecyclerView(newsItems);
}
}
Upvotes: 1
Reputation: 923
Your updateRecyclerView
method was called in the MainThead that it was executed right away.
Put your updateRecyclerView
method inside the onResponse
and onErrorResponse
Upvotes: 1