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

ViewPager中3个Fragment数据加载逻辑异常问题求助

问题根源分析
  1. ViewPager预加载机制:ViewPager默认会预加载当前页面左右各1个Fragment,所以初始化时会创建位置0(Scheduled)和1(InProcess)的Fragment,触发它们的onCreateView方法,进而执行loadData,这就是初始化时加载两组数据的原因。
  2. Adapter的错误配置:你的TabAdapter重写了getItemPosition并返回POSITION_NONE,这会强制ViewPager每次页面切换时销毁并重建所有Fragment,而非复用已有实例。比如滑动到InProcess时,会触发预加载位置2(Finished)的Fragment;滑回InProcess时,又会重建位置0的Fragment,导致循环加载。
  3. 加载时机不合理:loadData放在onCreateView中,每次Fragment重建都会执行加载,进一步放大了上述问题。

修复方案

第一步:修复Adapter的Fragment复用逻辑

删掉TabAdapter中重写的getItemPosition方法,让ViewPager正常复用已创建的Fragment:

private class TabAdapter extends FragmentPagerAdapter {

    public TabAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentList.get(position).getArguments().getString(ARG_TAB_NAME);
    }

    // 移除下面这个强制重建的方法
    /*@Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }*/
}

第二步:控制数据加载时机,仅在Fragment真正可见时加载

将loadData从onCreateView中移除,改为在Fragment可见时执行,避免预加载触发。在TabFragment中添加如下代码:

private boolean isViewCreated = false; // 标记视图是否初始化完成
private boolean isDataLoaded = false; // 标记当前Fragment数据是否已加载

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    // 仅当视图创建完成、Fragment可见、且未加载过数据时,执行加载
    if (isVisibleToUser && isViewCreated && !isDataLoaded) {
        loadData();
        isDataLoaded = true;
    }
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view;
    int tabPosition = getArguments() != null ? getArguments().getInt(ARG_TAB_POSITION) : -1;

    // 保留原有的视图初始化逻辑,但移除每个case里的loadData()
    switch (tabPosition) {
        case 0:
            view = inflater.inflate(R.layout.fragment_tab_scheduled, container, false);
            recyclerView = view.findViewById(R.id.recyclerView);
            LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
            recyclerView.setLayoutManager(layoutManager);
            recyclerViewAdapter = new MeetingListAdapter(context);
            recyclerView.setAdapter(recyclerViewAdapter);
            noDataAnimationView=view.findViewById(R.id.noDataAnimationView);
            // 删掉这里的loadData();
            break;
        case 1:
            view = inflater.inflate(R.layout.fragment_tab_inprocess, container, false);
            // 同理,初始化视图,删掉loadData()
            break;
        case 2:
            view = inflater.inflate(R.layout.fragment_tab_finished, container, false);
            // 同理,初始化视图,删掉loadData()
            break;
        default:
            return new View(context);
    }

    isViewCreated = true;
    // 如果当前Fragment已经可见且未加载数据,手动触发一次加载
    if (getUserVisibleHint() && !isDataLoaded) {
        loadData();
        isDataLoaded = true;
    }
    return view;
}

可选:支持手动刷新数据

如果需要下拉刷新或主动重新加载数据,可以添加一个刷新方法:

public void refreshData() {
    isDataLoaded = false;
    if (isViewCreated && getUserVisibleHint()) {
        loadData();
        isDataLoaded = true;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:14:56