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

RecyclerView点击打开插屏广告时无法显示ProgressDialog的问题

解决插屏广告加载时ProgressDialog不显示的问题

嘿,我一眼就看出你代码里的问题了——你把progress.dismiss()放在了onClick的最后,而loadInterstitialAd里的广告加载是异步操作,代码会跳过加载逻辑直接执行dismiss(),导致加载器刚弹出来就被关掉了,用户自然看不到。

咱们来一步步修正这个问题,完美实现你想要的“点击显示加载器→加载广告→展示广告→关闭广告打开新页面”的流程:

1. 核心问题分析

广告加载是异步任务,不会阻塞主线程,所以你原来的代码里,progress.show()调用后,马上就执行了progress.dismiss(),加载器根本来不及显示就被关闭了。我们需要把关闭加载器的操作放到广告加载完成、失败,或者直接打开页面的时机。

2. 完整修改方案

第一步:添加成员变量

在你的Fragment类里添加两个成员变量,用于管理加载器和防止重复点击:

private ProgressDialog mProgressDialog;
private boolean isProcessingClick = false; // 避免用户多次点击触发重复操作

第二步:修改RecyclerView点击监听逻辑

//region Item touch listener
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity().getApplicationContext(), listView, new itemsFragment.ClickListener() {
    @Override
    public void onClick(View view, int position) {
        // 防止重复点击
        if (isProcessingClick) {
            return;
        }
        isProcessingClick = true;

        Item item = itemList.get(position);
        String itemId = item.getId();

        // 初始化加载器,注意用Activity上下文
        mProgressDialog = new ProgressDialog(getActivity());
        mProgressDialog.setTitle("Loading");
        mProgressDialog.setCancelable(false);
        mProgressDialog.show();

        if ((counter % 2) == 0) {
            loadInterstitialAd(itemId);
        } else {
            // 直接打开页面,完成后关闭加载器并恢复点击状态
            fetchItem(itemId);
            dismissProgressDialog();
            isProcessingClick = false;
        }
    }
}));
//endregion

第三步:优化插屏广告加载回调

//region Interstitial ad
private void loadInterstitialAd(String itemId) {
    mInterstitialAd = new InterstitialAd(getActivity());
    mInterstitialAd.setAdUnitId(SAMPLE_INTERSTITIAL_ID);
    mInterstitialAd.setAdListener(new AdListener() {
        @Override
        public void onAdLoaded() {
            super.onAdLoaded();
            Log.e(TAG, "Loaded interstitial ad");
            // 广告加载完成,先关闭加载器再展示广告
            dismissProgressDialog();
            if (mInterstitialAd.isLoaded()) {
                mInterstitialAd.show();
            }
        }

        @Override
        public void onAdFailedToLoad(int errorCode) {
            super.onAdFailedToLoad(errorCode);
            Log.e(TAG, "Failed to load interstitial ad: " + errorCode);
            // 加载失败,关闭加载器并直接打开页面
            dismissProgressDialog();
            fetchItem(itemId);
            isProcessingClick = false;
        }

        @Override
        public void onAdClosed() {
            super.onAdClosed();
            // 广告关闭后打开页面,恢复点击状态
            fetchItem(itemId);
            isProcessingClick = false;
        }

        @Override
        public void onAdOpened() {
            super.onAdOpened();
            // 保险起见,广告打开时再次确认关闭加载器
            dismissProgressDialog();
        }
    });
    AdRequest adRequest = new AdRequest.Builder().build();
    mInterstitialAd.loadAd(adRequest);
}
//endregion

第四步:添加加载器关闭工具方法

private void dismissProgressDialog() {
    if (mProgressDialog != null && mProgressDialog.isShowing()) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}

第五步:处理内存泄漏

在Fragment生命周期中清理加载器,避免内存泄漏:

@Override
public void onDestroyView() {
    super.onDestroyView();
    dismissProgressDialog();
}

关键优化点说明

  • 异步操作适配:把加载器的关闭逻辑放到广告加载的回调方法中,确保加载器在广告准备好(或加载失败)后才消失。
  • 防止重复点击:用isProcessingClick标志位拦截重复请求,避免用户因等待多次点击导致的异常。
  • 上下文修正:使用Activity上下文创建ProgressDialog,解决原来用ClickListener上下文可能导致的显示异常问题。

这样修改后,用户点击RecyclerView项时会立刻看到加载器,直到广告加载完成(或失败)才会关闭加载器,完全符合你的理想体验~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:17:42