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

RecyclerView优化:首图加载完成后逐张加载至填满屏幕的实现方案

解决RecyclerView渐进式图片加载问题

这问题我做图片相册类功能时也踩过坑,一次性批量加载12张图不仅拖慢初始加载速度,还容易让用户在等待时失去耐心。咱们来调整成先加载首张图,依次填充至屏幕满,滚动到空白区域再按需加载的模式,分这几步来改:

1. 初始加载:计算屏幕容纳量,替代固定12张加载

别一上来就硬加载12张,先算出当前屏幕能放下多少张图片,只加载这个数量,剩下的等首张加载完成后再逐步补充。

实现屏幕可容纳Item数量计算

private int CalculateInitialLoadCount()
{
    // 获取RecyclerView的可见高度
    int recyclerViewHeight = mRecyclerView.Height;
    // 这里替换成你的图片Item实际高度(可提前测量或从Adapter中获取)
    int itemHeight = 200; 
    // 计算能容纳的行数,再乘以每行数量得到初始加载数
    int rows = (int)Math.Ceiling((double)recyclerViewHeight / itemHeight);
    int initialCount = rows * picturesinarow;
    // 兜底至少加载1张,防止计算异常
    return Math.Max(initialCount, 1);
}

修改初始化代码中的加载逻辑

private void InitRecView() {
 mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
 // 替换固定12张为计算出的初始加载量
 int initialLoadCount = CalculateInitialLoadCount();
 loadPhotos.LoadMoreItems(initialLoadCount);

 mLayoutManager = new GridLayoutManager (this, this.picturesinarow, GridLayoutManager.Vertical, false);
 mRecyclerView.SetLayoutManager(mLayoutManager);
 mAdapter = new PhotoAlbumAdapter (loadPhotos, this.picturesinarow, (RecyclerLayout)this.recyclerLayout, this.hasHeader, this.thumbnails, this);
 mRecyclerView.SetAdapter(mAdapter);
 mLayoutManager.SetSpanSizeLookup(new GridViewSpansizeLookup(mAdapter, mLayoutManager));
 
 // 滚动监听逻辑后面再修改,先保留原有结构
}

2. 监听图片加载完成,依次填充屏幕

要实现“首张加载完再加载下一张”,需要在Adapter里给图片加载添加完成回调,用Glide/Picasso这类库都能实现:

改造Adapter的图片加载逻辑

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    PhotoViewHolder photoHolder = holder as PhotoViewHolder;
    PictureItem currentItem = loadPhotos.pictures[position];
    
    // 以Glide为例,添加加载完成监听
    Glide.With(context)
         .Load(currentItem.ThumbnailUrl)
         .Placeholder(Resource.Drawable.default_placeholder) // 占位图避免空白
         .Into(photoHolder.ImageView)
         .AddListener(new RequestListener<Drawable>()
         {
             public bool OnLoadFailed(Exception e, object model, Target<Drawable> target, bool isFirstResource)
             {
                 // 加载失败也继续加载下一张
                 LoadNextItemIfNeeded(position);
                 return false;
             }

             public bool OnResourceReady(Drawable resource, object model, Target<Drawable> target, DataSource dataSource, bool isFirstResource)
             {
                 // 当前图片加载完成,检查是否需要补全屏幕
                 LoadNextItemIfNeeded(position);
                 return false;
             }
         });
}

// 判断是否需要加载下一张来填满屏幕
private void LoadNextItemIfNeeded(int currentLoadedPos)
{
    int lastVisiblePos = mLayoutManager.FindLastVisibleItemPosition();
    // 如果当前加载的位置接近最后可见项,且还有未加载的图片,就加载1张
    if (currentLoadedPos >= lastVisiblePos - 1 && loadPhotos.HasMoreItems())
    {
        int oldCount = loadPhotos.pictures.Count;
        loadPhotos.LoadMoreItems(1);
        mAdapter.NotifyItemInserted(oldCount);
    }
}

这里的HasMoreItems()需要你在loadPhotos类中实现,用来判断是否还有未加载的图片资源。

3. 滚动监听:仅在空白区域触发少量加载

把原来一次性加载12张的逻辑,改成只加载能填满剩余空白的少量图片(比如3-6张):

修改滚动监听代码

var onScrollListener = new XamarinRecyclerViewOnScrollListener(mLayoutManager);
onScrollListener.LoadMoreEvent += (object sender, EventArgs e) => {
    if (!loadPhotos.HasMoreItems()) return; // 没有更多资源直接返回
    
    // 每次最多加载6张,避免批量加载压力
    int loadCount = Math.Min(6, loadPhotos.GetRemainingItemCount());
    if (loadCount <= 0) return;
    
    int oldCount = loadPhotos.pictures.Count;
    loadPhotos.LoadMoreItems(loadCount);
    if (!mRecyclerView.IsComputingLayout)
        mAdapter.NotifyItemRangeInserted(oldCount, loadCount);
};
mRecyclerView.AddOnScrollListener(onScrollListener);

GetRemainingItemCount()需要你实现,用来返回还剩多少未加载的图片数量。

4. 额外优化:开启图片缓存提升体验

给图片加载库开启内存和磁盘缓存,避免重复加载已显示过的图片:

Glide.With(context)
     .Load(currentItem.ThumbnailUrl)
     .Placeholder(Resource.Drawable.default_placeholder)
     .DiskCacheStrategy(DiskCacheStrategy.All) // 开启磁盘缓存
     .Into(photoHolder.ImageView);

这样调整后,初始加载只会填充屏幕所需的最少图片,每张加载完成后自动补全剩余屏幕空间,滚动到空白区域时再少量加载,用户体验会顺畅很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:54:36