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

求助:RecyclerView调用notifyDataSetChanged后条目不显示问题

解决RecyclerView下拉刷新失效+notifyDataSetChanged后不显示的问题

Hey, let's break down your problem and fix it step by step— I've run into similar issues with Retrofit and RecyclerView before!

一、先解决下拉刷新不工作的问题

The swipe-to-refresh not responding usually boils down to two common mistakes:

  • Missing refresh listener setup
    You need to explicitly set a OnRefreshListener on your SwipeRefreshLayout in onCreate() (since you're using @BindView, I assume you're using ButterKnife). Without this, the layout won't know what to do when the user pulls down. Add this code:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    
        // Initialize RecyclerView first
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    
        // Set up swipe refresh listener
        swipeRefreshLayout.setOnRefreshListener(this::fetchLatestNews);
        // Trigger initial data load
        fetchLatestNews();
    }
    
    // Reusable method for fetching news (initial load + refresh)
    private void fetchLatestNews() {
        swipeRefreshLayout.setRefreshing(true);
        newsApi.getNews().enqueue(new Callback<NewsPojo>() {
            @Override
            public void onResponse(Call<NewsPojo> call, Response<NewsPojo> response) {
                // Handle success logic here (covered in next section)
                swipeRefreshLayout.setRefreshing(false);
            }
    
            @Override
            public void onFailure(Call<NewsPojo> call, Throwable t) {
                swipeRefreshLayout.setRefreshing(false);
                Toast.makeText(MainActivity.this, "Failed to load news", Toast.LENGTH_SHORT).show();
            }
        });
    }
    
  • Incorrect layout nesting
    Make sure your SwipeRefreshLayout directly wraps the RecyclerView in XML— no extra layouts in between that might block touch events:

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/activity_main_swipe_to_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
    

二、解决notifyDataSetChanged()后RecyclerView不显示的问题

This is almost always a data source reference issue. You're probably replacing the global fromRetrofit object but not updating the actual list your MainAdapter is holding. Here's how to fix it:

1. Add a safe data update method to your Adapter

Create a dedicated method in MainAdapter to update its dataset instead of modifying data directly from the Activity:

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
    private List<Article> articleList; // Assume your NewsPojo contains a list of Article objects

    // Constructor with null safety
    public MainAdapter(List<Article> articleList) {
        this.articleList = articleList != null ? articleList : new ArrayList<>();
    }

    // Method to update adapter data
    public void updateArticles(List<Article> newArticles) {
        this.articleList.clear();
        if (newArticles != null) {
            this.articleList.addAll(newArticles);
        }
        notifyDataSetChanged(); // Now this triggers a valid UI update
    }

    // Override required adapter methods
    @Override
    public int getItemCount() {
        return articleList.size();
    }

    // ... onCreateViewHolder, onBindViewHolder implementations
}

2. Update the adapter's data correctly in your Retrofit callback

When you get a successful response, use the adapter's updateArticles() method instead of just calling notifyDataSetChanged():

@Override
public void onResponse(Call<NewsPojo> call, Response<NewsPojo> response) {
    swipeRefreshLayout.setRefreshing(false);
    if (response.isSuccessful() && response.body() != null) {
        fromRetrofit = response.body();
        // Update adapter data directly
        postAdapter.updateArticles(fromRetrofit.getArticles());
    } else {
        // Handle empty/invalid response (show empty state if needed)
        postAdapter.updateArticles(null);
    }
}

3. Verify initial adapter setup

Make sure you initialize the adapter with a valid list on first load:

// After initial Retrofit call succeeds
fromRetrofit = response.body();
postAdapter = new MainAdapter(fromRetrofit.getArticles());
recyclerView.setAdapter(postAdapter);

三、Quick Additional Checks

  • Always stop the refresh indicator
    Forgetting swipeRefreshLayout.setRefreshing(false) can leave the spinner running and block UI interactions.
  • Handle empty data
    If your refresh returns an empty list, the RecyclerView will show nothing— add an empty state view to improve user experience.
  • Reuse the adapter instance
    Don't create a new MainAdapter every time you refresh— stick with the existing instance and update its data.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:35:42