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

如何在启动页完成3个JSON数据拉取后再显示主页面Fragment?

嘿,这个问题我太熟了!你现在碰到的就是异步请求和页面渲染的时序冲突——Volley请求还在后台跑呢,MainActivity就已经跳过来加载Fragment了,自然会显示空白。给你几个实用的解决思路,挑适合你的来:

方案一:在启动页等所有请求完成再跳转

这是最直接的思路,就是让启动页(你当前调用fetch_current_raffles的页面)先把3个JSON请求都处理完、ArrayList填充好,再跳转到MainActivity。

你可以用计数器来跟踪所有请求的完成状态:

  1. 先在启动页定义一个计数器,对应你要拉取的3个请求:
private int pendingRequests = 3;
  1. 每个Volley请求的onResponse回调里,完成数据填充后就把计数器减1,然后判断是否所有请求都完成:
// 示例:其中一个请求的回调逻辑
@Override
public void onResponse(JSONObject response) {
    // 这里写填充ArrayList的逻辑
    raffle_controller.fillRaffleData(response);
    pendingRequests--;
    checkIfReadyToJump();
}

private void checkIfReadyToJump() {
    if (pendingRequests == 0) {
        // 所有数据都准备好了!现在跳转
        startActivity(new Intent(this, MainActivity.class));
        finish();
    }
}

⚠️ 别忘了处理请求失败的情况!比如给用户弹个网络错误提示,或者提供重试选项,不然用户可能会一直卡在启动页。

方案二:在MainActivity里控制Fragment的显示时机

如果不想让启动页等待太久,也可以把请求逻辑移到MainActivity里,先给用户看加载动画,等数据全回来再显示Fragment:

  1. 在MainActivity的布局里,放一个ProgressBar(默认显示)和用来承载Fragment的FrameLayout(默认隐藏)
  2. 同样用计数器跟踪请求完成状态,等所有数据加载完:
private void onAllDataLoaded() {
    // 隐藏加载动画,显示Fragment
    progressBar.setVisibility(View.GONE);
    fragmentContainer.setVisibility(View.VISIBLE);
    
    // 初始化Fragment并传递数据
    RaffleListFragment fragment = RaffleListFragment.newInstance(raffle_controller.getRaffleList());
    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fragment_container, fragment)
        .commit();
}

方案三:用ViewModel+LiveData做数据驱动(推荐)

这是更符合现代Android开发规范的做法,把数据逻辑和UI解耦,让Fragment自动在数据准备好时更新:

  1. 创建一个RaffleViewModel,里面处理Volley请求,并用LiveData暴露数据:
public class RaffleViewModel extends ViewModel {
    private final MutableLiveData<List<Raffle>> raffleList = new MutableLiveData<>();
    private int pendingRequests = 3;

    public LiveData<List<Raffle>> getRaffleList() {
        return raffleList;
    }

    public void fetchRaffles(Context context) {
        // 发起第一个请求
        StringRequest request1 = new StringRequest(Request.Method.GET, FIRST_JSON_URL,
            response -> {
                // 解析数据并填充临时列表
                pendingRequests--;
                checkAndPostData();
            },
            error -> handleRequestError(error));
        
        // 重复上述逻辑发起第二、第三个请求
        // ...
        
        Volley.newRequestQueue(context).add(request1);
        // 添加另外两个请求到队列
    }

    private void checkAndPostData() {
        if (pendingRequests == 0) {
            // 把填充好的ArrayList通过LiveData发送出去
            raffleList.postValue(yourFilledArrayList);
        }
    }

    private void handleRequestError(VolleyError error) {
        // 处理请求失败,比如给用户提示
    }
}
  1. 在MainActivity或Fragment里观察LiveData,数据就绪时自动更新UI:
// 在Fragment的onViewCreated里
RaffleViewModel viewModel = new ViewModelProvider(this).get(RaffleViewModel.class);
viewModel.getRaffleList().observe(getViewLifecycleOwner(), raffles -> {
    if (raffles != null && !raffles.isEmpty()) {
        // 这里更新RecyclerView的Adapter,或者显示内容
        yourRecyclerView.setAdapter(new RaffleAdapter(raffles));
    }
});

// 发起请求
viewModel.fetchRaffles(requireContext());

这种方式的好处是,即使页面旋转,数据也不会丢失,而且不用手动管理复杂的时序逻辑。

最后提醒下:不管用哪种方案,都要给用户明确的加载反馈(比如启动页的加载动画),避免用户以为App卡住了;同时一定要处理网络异常的情况,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:41:04