Почему мой Android ProgressBar никогда не отображается?

У меня есть recyclerView, который загружает и показывает элементы, которые мне нужны, но есть задержка (когда приложение получает новости xml из Интернета и анализирует их), и я хочу, чтобы появился индикатор progressBar, чтобы указать пользователя . Индикатор выполнения есть, но он никогда не появляется.

Вот мой код:

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

Я тоже пробовал

 if (newsList != null) {
            updateProgressBar.setVisibility(View.GONE);
        }

и этот код:

if (newsList != null && newsList.size()>0) {
        updateProgressBar.setVisibility(View.INVISIBLE);
    }

Я также использовал .GONE со вторым подходом, но на этот раз ProgreesBar никогда не работает, он просто остается там и вращается повсюду, и когда я пробую Log.d, он говорит, что список новостей пуст !, хотя явно есть значения в нем, и recyclerView их показывает. вместо .size() я тоже проверял с .isEmpty(), но результат все тот же!

и вот xml для индикатора выполнения:

   <?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>

вы можете опубликовать свой xml для индикатора выполнения?

Kamarudeen Ayankunbi 06.07.2018 18:39
0
1
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш метод updateRecyclerView был вызван в MainThead и сразу же был выполнен. Поместите свой метод updateRecyclerView в onResponse и onErrorResponse

но onResponse находится внутри цикла for.

Reza Hamzehei 06.07.2018 19:03

Простой глобальный счетчик проверяет, все ли ваши адреса проанализированы.

glagarto 06.07.2018 19:10
Ответ принят как подходящий

Проблема в том, что вы в основном вызываете updateProgressBar.setVisibility(View.INVISIBLE); косвенно из onCreate().

Запрос Volley является асинхронным, поэтому onResponse() вызывается после завершения запроса.

В основном ваш код работает следующим образом: сначала из onCreate() вы вызываете getTheNews(), который почти мгновенно проходит цикл for (Volley асинхронный). Затем updateRecyclerView(), затем updateProgressBar.setVisibility(View.INVISIBLE);

Поскольку это происходит очень быстро, вы никогда не увидите ProggessBar.

Обновлено:

Добавьте переменную класса для счетчика:

private int addressCounter = 0;

Теперь измените свой метод getTheNews() следующим образом:

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

Вы также можете рассмотреть: Если вы собираетесь использовать hookUpScreenViews() для инициализации ваших представлений, почему бы не добавить searchView.setOnQueryTextListener(this);? Вы также можете добавить код для настройки RecyclerView, потому что его нужно вызвать только один раз.

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

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я не пробовал этот код, поэтому вам может потребоваться его немного подправить.

Обновлено: это рабочий код:

public void onResponse(String response) {
                addressCounter++;
                NewsXMLParser newsXMLParser = new NewsXMLParser(response);
                newsXMLParser.parseNewsXml();
                newsItems.addAll(newsXMLParser.getNewsItems());

                if (addressCounter>=addresses.size()){
                    updateRecyclerView(newsItems);
                }
            }

ну, точный код не работает, но после небольшой настройки, как вы сказали, он начинает работать! Спасибо

Reza Hamzehei 07.07.2018 08:08

Другие вопросы по теме