ListView setonscrollistener продолжает возвращаться в верхнюю часть представления

#android #android-studio #android-listview #simpleadapter

Вопрос:

У меня есть ListView с setOnScrollListener для загрузки дополнительных данных из JSON, я использую Asynctask для получения JSON. и JSON разбит на 10 страниц на страницу. Проблема в том, что при прокрутке до самого низа прокрутка всегда возвращается наверх после отображения (загрузки) большего количества данных, например, при перезапуске действия.

Итак, как заставить свиток оставаться на месте и не возвращаться наверх ?

Код

     listView.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
    
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    if (firstVisibleItem visibleItemCount == totalItemCount amp;amp; totalItemCount!=0){
                        nextpage = nextpage   1;
                        new getJSON().execute();
                    }
                }
            });

private class getJSON extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            footer.setVisibility(View.VISIBLE);
            pDialog = new ProgressDialog(PoActivity.this);
            pDialog.setMessage("Please Wait...");
            pDialog.setCancelable(false);
            pDialog.show();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            Handler handler = new Handler();

            String po = handler.makeServiceCall(url   "?page="   nextpage);

            if (po != null){
                try {
                    JSONObject obj = new JSONObject(po);
                    JSONArray objArray = obj.getJSONArray("data");
                    for (int i = 0; i < objArray.length(); i  ){
                        JSONObject data = objArray.getJSONObject(i);
                        String employee = data.getString("name");
                        String status = data.getString("status");


                        HashMap<String, String> datarow = new HashMap<>();

                        datarow.put("emp", employee);
                        datarow.put("status", status);

                        polist.add(datarow);

                    }
                }catch (final JSONException e){
                    Log.e(TAG, "Json parsing error: "   e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "Json parsing error: "   e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }else {
                Log.e(TAG,"Couldn't get json from server");
                endpage = 0;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "Couldn't get json from server. check logcat", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            pDialog.dismiss();
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            pDialog.dismiss();
            footer.setVisibility(View.GONE);

            listAdapter = new SimpleAdapter(PoActivity.this, polist,
                    R.layout.po_row, new String[]{"emp", "status"},
                    new int[]{R.id.name, R.id.status});

            listView.setAdapter(listAdapter);    
        }
    }
 

Комментарии:

1. Я предлагаю вам использовать Recyclerview. Вы можете достичь того, что вам было нужно, оттуда.

2. в чем разница между Recyclerview и ListView?

3. Вы можете сказать, что Recyclerview-это обновленный виджет Listview. У него больше функций, чем у Listview.

Ответ №1:

Ошибка вызвана повторной инициализацией адаптера и сбросом его для представления списка. Вам нужно инициализировать адаптер только один раз, и каждый раз, когда вы добавляете данные, вам нужно добавлять их в данные списка в адаптере. Затем вызовите notifyDataSetChanged()

 @Override
protected void onPostExecute(Void aVoid) {
   //should be
   listAdapter.add(dataNew);
   listAdapter.notifyDataSetChanged()
}
 

Комментарии:

1. это работает, но теперь отображаются только одни и те же(дубликаты) данных

2. Если вы уже добавляете данные в «polist.add(datarow)» в «doInBackground», вам не нужно вызывать ListAdapter.add(dataNew);

3. нет никакой разницы, даже добавлено notifydatasetchanged()