Android Listview при перестройке не показывает новые элементы до прокрутки вниз

Итак, у меня есть список, который заполняется путем извлечения данных JSON из Интернета. Я завернул элемент в SwypeRefreshLayout. Что происходит, когда я тяну вниз, он извлекает данные, очищает Arraylist, перестраивает его, а затем уведомляет адаптер об изменении набора данных. Однако я не сразу вижу новые данные. Чтобы увидеть новые элементы вверху, мне нужно прокрутить вниз, чтобы они не отображались, а затем вернуться обратно.

Вот код, который я использую для обновления списка.

 swipelists.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() {

                @Override public void onRefresh() {
                    if(getArguments().getInt(ARG_SECTION_NUMBER) == 3 ) {

                        recentArrayList.clear();
                        long totalSize = 0;
                        recadapter = new ArrayAdapter(ctx,android.R.layout.simple_list_item_1, recentArrayList);

                        new updatetheRecent().execute(ctx);

                    }

                    else {
                        swipelists.setRefreshing(false);
                    }



                }});

Вот функция, которая вызывается для перестроения списка

 private class updatetheRecent extends AsyncTask<Context, Integer, Long> {
        protected Long doInBackground(Context... urls) {
            int count = urls.length;


            long totalSize = 0;
            try {



                HttpClient httpclient = new DefaultHttpClient(); // Create HTTP Client
                HttpGet httpget = new HttpGet("http://test.net/pltxtrec.php"); 
                HttpResponse response = httpclient.execute(httpget); // Executeit
                HttpEntity entity = response.getEntity();
                InputStream is = entity.getContent(); // Create an InputStream with the response
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) // Read line by line
                    sb.append(line + "\n");


                String resString = sb.toString(); // Result is here
                JSONArray json = new JSONArray(resString);
                for (int i = 0; i < json.length(); i++) {
                    JSONObject json_data = json.getJSONObject(i);
                    String jsonvalues = json_data.getString("title");
                    if (!jsonvalues.equals("")) {
                        recentArrayList.add(json_data.getString("artist") + " - " + json_data.getString("title"));
                        // .. get all value here
                    }




                }
                if (recentArrayList.isEmpty()) {
                    recentArrayList.add("No items currently in queue");
                }


                is.close(); // Close the stream

                getActivity().runOnUiThread(new Runnable() {
                    public void run() {

                        recadapter.notifyDataSetChanged();


                        swipelists.setRefreshing(false);


                    }
                });

            }
            catch (Exception e) {

            }

            return totalSize;
        }

        protected void onProgressUpdate(Integer... progress) {

        }

        protected void onPostExecute(Long result) {
            if (recentlist != null) {
                // Tried adding this is but its never called
                recentlist.smoothScrollToPosition(0);
            }

        }
    }

person Dandrews    schedule 01.08.2014    source источник


Ответы (3)


Вместо использования getActivity().runOnUiThread() вызовите

recadapter.notifyDataSetChanged();
swipelists.setRefreshing(false);

в методе onPostExecute() (который выполняется в потоке пользовательского интерфейса).

Если это не сработает, попробуйте вызвать invalidate() в SwypeRefreshLayout. .

person caioyassoyama    schedule 04.08.2014

Пожалуйста, попробуйте этот код.

runOnUiThread(run);

OnCreate() вы устанавливаете исполняемый поток:

run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};
person Trần Thị Diệu My    schedule 15.01.2019

Ваш HTTP-запрос является асинхронной задачей, то есть он вернется, когда вернется, вы не можете нарисовать содержимое чего-то, что еще не поступило.

Я не тестировал его, но похоже, что вы ищете метод isRefreshing() из SwipeRefreshLayout. https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html#isRefreshing()

person art20    schedule 01.08.2014
comment
SwipeRefreshLayout — это своего рода загрузчик. Вы говорите о чем-то помимо этого? Кроме того, даже с загрузчиком мне нужно было бы скрыть весь вид списка, показать загрузчик, а затем снова показать список вместо его обновления, как обычно. - person Dandrews; 01.08.2014
comment
Ваш класс updatetheRecent расширяет AsyncTask, что означает, что он вернет свое значение, когда оно будет возвращено ему. Вы просите свое представление рисовать контент, как если бы новый updatetheRecent().execute(ctx); функция вернется немедленно, и это не так. надеюсь, это поможет - person art20; 01.08.2014