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

Fragment切换时因Recycler Adapter加载出现延迟,如何优化?

优化Fragment过渡流畅度的方案

1. 延迟RecyclerView初始化,避开动画执行阶段

Fragment过渡动画运行时,UI线程若被RecyclerView初始化、布局计算占用,会直接导致卡顿。可以监听Fragment进入动画完成事件,等动画结束后再绑定Adapter:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    viewModel = new ViewModelProvider(this).get(MainViewModel.class);
    
    recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
    recyclerView.setHasFixedSize(true); // 固定列表大小,减少重复布局测量
    
    // 等待Fragment进入动画完成后再初始化Adapter
    getView().postOnAnimation(() -> {
        adapter = new BackpackAdapter(viewModel.getListItems());
        recyclerView.setAdapter(adapter);
    });
}

2. 异步准备列表数据,避免UI线程阻塞

如果viewModel.getListItems()是同步执行的耗时操作(比如本地数据库读取、数据解析),会直接阻塞UI线程。改成在ViewModel中异步加载数据,通过LiveData通知Fragment更新:
ViewModel代码:

private MutableLiveData<List<Item>> itemListLiveData = new MutableLiveData<>();

public MainViewModel() {
    // 用IO线程执行耗时数据加载
    Executors.newSingleThreadExecutor().execute(() -> {
        List<Item> items = loadItemsFromLocal(); // 耗时操作,比如读数据库
        itemListLiveData.postValue(items);
    });
}

public LiveData<List<Item>> getItemListLiveData() {
    return itemListLiveData;
}

Fragment代码:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    viewModel = new ViewModelProvider(this).get(MainViewModel.class);
    
    recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
    recyclerView.setHasFixedSize(true);
    adapter = new BackpackAdapter(new ArrayList<>()); // 先绑定空列表
    recyclerView.setAdapter(adapter);
    
    // 观察数据变化,异步更新Adapter
    viewModel.getItemListLiveData().observe(getViewLifecycleOwner(), items -> {
        adapter.updateItems(items);
    });
}

Adapter新增更新方法:

public void updateItems(List<Item> newItems) {
    // 用DiffUtil优化列表更新,减少不必要的视图刷新
    DiffUtil.DiffResult result = DiffUtil.calculateDiff(new ItemDiffCallback(this.list, newItems));
    this.list.clear();
    this.list.addAll(newItems);
    result.dispatchUpdatesTo(this);
}

// DiffCallback实现
private static class ItemDiffCallback extends DiffUtil.Callback {
    private final List<Item> oldList;
    private final List<Item> newList;

    public ItemDiffCallback(List<Item> oldList, List<Item> newList) {
        this.oldList = oldList;
        this.newList = newList;
    }

    @Override
    public int getOldListSize() { return oldList.size(); }
    @Override
    public int getNewListSize() { return newList.size(); }
    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId();
    }
    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
    }
}

3. 优化RecyclerView的ViewHolder创建效率

  • 用ViewBinding替代findViewById,减少视图查找耗时:
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    ItemBinding binding = ItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
    return new ViewHolder(binding);
}

class ViewHolder extends RecyclerView.ViewHolder {
    private final ItemBinding binding;
    
    ViewHolder(ItemBinding binding) {
        super(binding.getRoot());
        this.binding = binding;
    }
}
  • 增加View缓存数量,减少ViewHolder重复创建:
recyclerView.setItemViewCacheSize(10); // 根据列表项数量调整缓存大小

4. 提前预加载Glide图片

首次加载时的图片解码可能占用CPU资源,可在数据准备完成后提前预加载:

// 在Fragment中数据回调后执行预加载
viewModel.getItemListLiveData().observe(getViewLifecycleOwner(), items -> {
    for (Item item : items) {
        Glide.with(requireContext())
             .load(item.getImage())
             .preload();
    }
    adapter.updateItems(items);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:21:00