ViewPager2中Glide加载网络图片延迟及Circular Indicator不显示求助
解决ViewPager2加载网络图片延迟及CircleIndicator3不显示问题
一、初始加载5-7秒延迟的问题
问题根源
- 数据加载逻辑错误:
getListPhoto方法先返回空列表,ViewPager2的Adapter已绑定空数据,网络请求异步完成后才向列表添加数据,但未通知Adapter更新,导致ViewPager2直到数据全部添加完成后才开始渲染图片,造成延迟。 - Glide缓存策略不当:禁用磁盘缓存(
DiskCacheStrategy.NONE),每次启动都需重新下载图片,即使图片体积小也会增加额外网络请求耗时。 - 上下文使用不规范:Glide使用Fragment的
getContext(),在Fragment生命周期中可能存在上下文不稳定的情况,影响加载效率。
修复方案
- 调整数据加载流程:网络请求成功后更新列表并通知Adapter刷新,而非先返回空列表。
- 恢复Glide缓存策略:使用默认的
DiskCacheStrategy.AUTOMATIC或DiskCacheStrategy.ALL,利用缓存减少重复下载。 - 优化Glide配置:使用ViewHolder的
itemView.getContext()作为上下文,添加占位图提升用户体验,移除disallowHardwareConfig()开启硬件加速。
修改后的关键代码:
- HomeFragment.java:持有Adapter引用,数据加载完成后通知刷新
// 声明全局Adapter private PhotoViewPager2Adapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentHomeBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); // ... 其他初始化代码 // ViewPager2初始化修改 mViewPager2 = view.findViewById(R.id.viewPager2_1); mListPhoto = new ArrayList<>(); adapter = new PhotoViewPager2Adapter(mListPhoto, requireContext()); mViewPager2.setAdapter(adapter); // 初始化Indicator CircleIndicator3 indicator = view.findViewById(R.id.circleIndicator3_1); indicator.setViewPager(mViewPager2); adapter.registerAdapterDataObserver(indicator.getAdapterDataObserver()); mViewPager2.setOffscreenPageLimit(2); // 调用数据加载方法 getListPhoto(pin_code); // ... 其他代码 return view; } // 修改getListPhoto为无返回值,直接更新全局列表 private void getListPhoto(String pin_code) { Call<List<Photo>> call = apicontroller.getInstance() .getApi() .fetchSliderImages(pin_code); call.enqueue(new Callback<List<Photo>>() { @Override public void onResponse(Call<List<Photo>> call, Response<List<Photo>> response) { if (response.isSuccessful() && response.body() != null) { List<Photo> obj = response.body(); mListPhoto.clear(); for (Photo photo : obj) { String fullUrl = "http://74.225.131.20/localshop/localad/localadhomesliderimages/" + photo.getImg_url(); mListPhoto.add(new Photo(fullUrl, photo.getImg_txt())); } // 通知Adapter数据更新 adapter.notifyDataSetChanged(); } } @Override public void onFailure(Call<List<Photo>> call, Throwable t) { Log.e("HomeFragment", "加载图片失败: " + t.getMessage()); } }); }
- PhotoViewPager2Adapter.java:优化Glide配置
@Override public void onBindViewHolder(@NonNull PhotoViewHolder holder, int position) { Glide.with(holder.itemView.getContext()) .load(mListPhoto.get(position).getImg_url()) .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) .fitCenter() .placeholder(R.drawable.your_placeholder) // 替换为你的占位图资源 .into(holder.img_photo); holder.img_text.setText(mListPhoto.get(position).getImg_txt()); // 点击事件代码不变 }
二、CircleIndicator3加载网络图片时消失的问题
问题根源
初始状态下mListPhoto为空列表,Adapter的getItemCount()返回0,CircleIndicator3检测到无页面数据自动隐藏;网络请求完成后添加数据但未通知Adapter更新,Indicator无法感知数据变化,始终处于隐藏状态。
修复方案
在网络请求成功后调用adapter.notifyDataSetChanged(),通知RecyclerView更新数据。CircleIndicator3通过已注册的AdapterDataObserver会感知页面数量变化,自动显示并更新指示器数量。
原Indicator初始化代码已正确注册观察者,无需额外修改:
CircleIndicator3 indicator = view.findViewById(R.id.circleIndicator3_1); indicator.setViewPager(mViewPager2); adapter.registerAdapterDataObserver(indicator.getAdapterDataObserver());
额外优化建议
- 增加预加载数量:将
mViewPager2.setOffscreenPageLimit(2)改为mViewPager2.setOffscreenPageLimit(mListPhoto.size()),提前加载所有图片,减少滑动时的加载延迟。 - 预加载图片:在数据加载完成后,用Glide预加载所有图片:
// 在getListPhoto的onResponse中添加 for (Photo photo : mListPhoto) { Glide.with(requireContext()) .load(photo.getImg_url()) .preload(); }
- 优化图片格式:建议服务器返回WebP格式图片,进一步压缩体积提升加载速度。
内容的提问来源于stack exchange,提问作者Naresh Pradhan
相关产品推荐
相关产品推荐

