You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ListView设置setOnScrollListener加载分页数据后返回顶部如何解决

问题解决方法

问题根源

你每次分页加载完新数据后,都重新创建SimpleAdapter实例并重新给ListView绑定适配器,这会让ListView判定为全新数据源,直接重置滚动位置回到顶部,是问题的核心原因。
另外你当前代码还有两个隐含问题:

  • 滚动监听没有加加载状态判断,滚动到底部时会重复触发多次加载请求
  • 在子线程(doInBackground)中操作UI控件pDialog.dismiss(),会抛出异常导致崩溃

修复步骤

  1. 初始化阶段一次性设置适配器,不要每次加载都重建
    在Activity的onCreate方法中完成适配器初始化和绑定:
// 全局变量声明
private boolean isLoading = false; // 新增加载状态标记,防止重复加载

// onCreate里的逻辑
polist = new ArrayList<>();
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. 修改滚动监听,新增加载状态判断
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) {
        // 新增isLoading判断,避免同一时间触发多个加载请求
        if (!isLoading && firstVisibleItem+visibleItemCount == totalItemCount && totalItemCount!=0){
            nextpage = nextpage + 1;
            new getJSON().execute();
        }
    }
});
  1. 改造AsyncTask逻辑,删除重建适配器的代码,仅更新数据源后通知适配器刷新即可
private class getJSON extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        isLoading = true; // 开始加载,标记状态为加载中
        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(),子线程不允许操作UI控件
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        pDialog.dismiss();
        footer.setVisibility(View.GONE);
        isLoading = false; // 加载完成,标记状态为非加载中
        // 删除原有重新创建适配器、重新setAdapter的代码,仅保留下面这行通知刷新即可
        listAdapter.notifyDataSetChanged();
    }
}

修改后加载新数据时只会在原有列表末尾追加内容,不会重置滚动位置,也不会出现重复加载、子线程操作UI的异常问题。

内容的提问来源于stack exchange,提问作者PieceofShid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:06:03