TabLayout搭配ViewPager2无法加载对应Fragment且应用出现无响应问题
问题根源
- 双向联动逻辑冲突:
TabLayoutMediator本身已经实现了TabLayout和ViewPager2的双向同步能力,你额外添加的OnTabSelectedListener和OnPageChangeCallback会形成触发死循环:选中标签→切换ViewPager页面→触发页面选中回调→再次选中标签→再次触发标签选中回调,主线程被无限占用直接导致应用无响应。 - 不必要的全量刷新:每次标签选中时调用
newsPagerAdapter.notifyDataSetChanged()会触发所有Fragment的销毁重建,每个Fragment重建时都会重新发起网络请求,进一步加重主线程负载,加剧卡顿。 - Fragment列表更新逻辑错误:网络请求成功后直接给
homeNews重新赋值,Adapter绑定的仍是初始的空列表对象,所以即使请求成功也无法刷新列表。
修复步骤
1. 修复MainActivity逻辑
删除你手动添加的OnTabSelectedListener和OnPageChangeCallback代码块,TabLayoutMediator.attach()执行后会自动处理标签和ViewPager的联动,不需要额外实现。
修改后的MainActivity onCreate核心代码如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = findViewById(R.id.tbCustom); tabLayout = findViewById(R.id.tlCategories); setSupportActionBar(toolbar); viewPager2 = findViewById(R.id.vpNews); newsPagerAdapter = new NewsPagerAdapter(getSupportFragmentManager(),getLifecycle()); viewPager2.setAdapter(newsPagerAdapter); tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> tab.setText(tabTitles[position])); tabLayoutMediator.attach(); }
2. 修复Fragment列表更新逻辑
修改HomeFragment(以及其他同结构Fragment)的网络请求成功回调逻辑,不要直接替换列表对象,而是在原有列表基础上更新内容:
@Override public void onResponse(@NonNull Call<NewsArticles> call, @NonNull Response<NewsArticles> response) { if(response.isSuccessful() && response.body() != null) { homeNews.clear(); homeNews.addAll(response.body().getArticles()); newsAdapter.notifyDataSetChanged(); } }
3. 可选优化项
- 把每页请求数量
pageSize从50调整为10-20,减少首次加载的渲染压力 - 给Glide加载图片添加占位图和错误图,避免图片加载失败导致的体验问题
- 可以给ViewPager2设置
setOffscreenPageLimit(2),预加载相邻的2个Fragment,提升滑动流畅度
内容的提问来源于stack exchange,提问作者Kumar Sravan
相关产品推荐
相关产品推荐

