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

如何解决SwipeRefreshLayout刷新RecyclerView时API新数据追加到末尾的问题

问题根因

下拉刷新时新数据追加在旧数据末尾的核心原因是:每次拉取新数据前没有清空存储旧数据的全局列表,新数据直接追加到了原有列表末尾,同时每次接口请求成功后重复初始化RecyclerView相关实例也属于不必要的冗余操作,会带来额外性能损耗。

修改方案

步骤1:将RecyclerView的初始化逻辑移动到onCreate方法中,全局只执行一次

步骤2:每次接口返回新数据前先清空原有数据,添加新数据后通知适配器刷新列表

步骤3:修正SwipeRefreshLayout的刷新状态控制逻辑,请求完成后再关闭刷新动画

完整修改后的代码片段如下:

首先修改onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_state_report);
    View mainLayout = findViewById(R.id.mainLayout);
    Drawable drawable = mainLayout.getBackground();
    drawable.setAlpha(20);

    refreshLayout = findViewById(R.id.mainLayout);
    // 初始化RecyclerView 全局仅执行一次
    recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    itemArrayList = new ArrayList<>();
    adapter = new CustomAdapter(this, itemArrayList);
    recyclerView.setAdapter(adapter);

    refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            // 不要立刻关闭刷新状态,等待接口请求完成后再关闭
            loadStateReport();
        }
    });

    loadStateReport();
}

修改loadStateReport方法:

public void loadStateReport () {
    Log.d ("debugging", "entered the loadSateReport() Fn.");
    RequestQueue requestQueue = Volley.newRequestQueue(StateReportActivity.this);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, REPORT_URL, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        // 先清空旧数据
                        itemArrayList.clear();
                        JSONArray array = response.getJSONArray("regionData");

                        for (int i = 0; i < array.length(); i++) {
                            JSONObject object = array.getJSONObject(i);

                            String region = object.getString("region");
                            Long activeCases = object.getLong("activeCases");
                            Long newInfected = object.getLong("newInfected");
                            Long recovered = object.getLong("recovered");
                            Long newRecovered = object.getLong("newRecovered");
                            Long deceased = object.getLong("deceased");
                            Long newDeceased = object.getLong("newDeceased");
                            Long total = object.getLong("totalInfected");

                            itemArrayList.add(new Item(region, activeCases, newInfected, recovered, newRecovered, deceased,
                                    newDeceased, total));
                        }
                        // 通知适配器数据已变更,刷新列表
                        adapter.notifyDataSetChanged();
                        // 关闭刷新状态
                        refreshLayout.setRefreshing(false);

                    } catch (JSONException e) {
                        e.printStackTrace();
                        refreshLayout.setRefreshing(false);
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(StateReportActivity.this, "网络请求失败,请检查网络设置", Toast.LENGTH_SHORT).show();
            // 接口请求失败也要关闭刷新状态
            refreshLayout.setRefreshing(false);
        }
    });
    requestQueue.add(jsonObjectRequest);
    Log.d("debugging", "ObjectRequest added to the queue.");
}

改动说明

  1. RecyclerView的初始化逻辑挪到onCreate中仅执行一次,避免重复创建实例带来的性能损耗
  2. 每次接口返回数据前先调用itemArrayList.clear()清空原有旧数据,再添加新拉取的数据,就不会出现数据追加的问题
  3. 修正了SwipeRefreshLayout的状态控制逻辑,只有在接口请求完成(无论成功失败)才关闭刷新动画,交互体验更符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:42:03