Reza Hamzehei
Reza Hamzehei

Reputation: 243

Why my android progressBar never shows up?

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

Answers (2)

Barns
Barns

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

glagarto
glagarto

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

Related Questions