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

SwipeRefreshLayout下拉刷新返回重复数据问题求助

SwipeRefreshLayout下拉刷新数据重复问题解决

问题根源

  1. 全局集合moviesList每次刷新时未清空,直接调用addAll追加新数据,导致旧数据残留重复。
  2. 下拉刷新时重复调用initViews(),该方法会重复初始化布局管理器、创建新Adapter,还会重复发起数据请求并注册观察者,多次触发数据添加逻辑。
  3. 每次数据返回后都重新创建Adapter并设置给RecyclerView,不仅没必要,还可能引发额外问题。

解决方案

1. 拆分初始化逻辑,分离一次性操作和刷新操作

将RecyclerView布局管理器、Adapter初始化这些只需要执行一次的代码单独抽离,避免刷新时重复执行。

2. 刷新前清空数据集合

发起新请求前先清空moviesList,确保新数据是从头添加,不会和旧数据叠加。

3. 复用Adapter,避免重复创建

初始化时创建一次Adapter并绑定到RecyclerView,后续仅需更新数据集合后通知Adapter刷新即可。

4. 优化数据请求与观察者逻辑

确保数据请求和观察者注册只执行必要的次数,避免重复监听导致多次添加数据。

修改后的完整代码

public class HomeActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private ProgressDialog pd;
    private SwipeRefreshLayout swipeRefreshLayout;
    private List<MovieModel> moviesList;
    private HomeMovieAdapter adapter;
    private MovieListViewModel movieListViewModel;
    private FavouriteDbHelper favouriteDbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        recyclerView = findViewById(R.id.recyclerview_home);
        swipeRefreshLayout = findViewById(R.id.main_content_home);
        Toolbar toolbar = findViewById(R.id.toolBar_home);
        favouriteDbHelper = new FavouriteDbHelper(this);
        moviesList = new ArrayList<>();
        movieListViewModel = new ViewModelProvider(this).get(MovieListViewModel.class);
        setSupportActionBar(toolbar);
        
        // 仅初始化一次RecyclerView相关配置
        initRecyclerView();
        // 设置下拉刷新监听
        setupSwipeRefresh();
        // 首次加载数据
        loadPopularMovies();
    }

    // 初始化RecyclerView,只执行一次
    private void initRecyclerView(){
        pd = new ProgressDialog(this);
        pd.setMessage("Fetching Movies...");
        pd.setCancelable(false);
        pd.show();
        
        adapter = new HomeMovieAdapter(this,moviesList);
        // 根据屏幕方向设置列数
        int spanCount = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? 2 : 4;
        recyclerView.setLayoutManager(new GridLayoutManager(this, spanCount));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(adapter);
    }

    // 配置下拉刷新逻辑
    private void setupSwipeRefresh(){
        swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_orange_dark);
        swipeRefreshLayout.setOnRefreshListener(() -> {
            loadPopularMovies();
            Toast.makeText(HomeActivity.this, "Movies Refreshed", Toast.LENGTH_SHORT).show();
        });
    }

    // 加载电影数据的核心逻辑
    private void loadPopularMovies(){
        // 清空旧数据,避免重复
        moviesList.clear();
        // 请求第一页数据
        movieListViewModel.searchMoviesPage(1);
        
        movieListViewModel.getPopularMovies().observe(this, movieModels -> {
            try {
                if (movieModels != null){
                    moviesList.addAll(movieModels);
                    // 通知Adapter数据更新
                    adapter.notifyDataSetChanged();
                    recyclerView.smoothScrollToPosition(0);
                }
                // 关闭刷新状态
                if (swipeRefreshLayout.isRefreshing()){
                    swipeRefreshLayout.setRefreshing(false);
                }
                pd.dismiss();
            }catch (Exception e){
                e.printStackTrace();
                // 异常时也要关闭加载状态
                if (swipeRefreshLayout.isRefreshing()){
                    swipeRefreshLayout.setRefreshing(false);
                }
                pd.dismiss();
            }
        });
    }
}

关键优化点说明

  • 把初始化RecyclerView的逻辑抽离到initRecyclerView(),仅在Activity创建时执行一次,避免重复创建布局管理器和Adapter。
  • 每次刷新调用loadPopularMovies()时,先执行moviesList.clear()清空旧数据,从根源解决重复问题。
  • 复用同一个Adapter,数据更新后调用adapter.notifyDataSetChanged(),既保证界面刷新,又提升性能。
  • 下拉刷新仅触发数据重新加载,不再执行冗余的初始化操作,逻辑更简洁清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:17:48