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

React Native中如何在返回页面或切换首页时展示InterstitialAd

解决方案

一、核心思路

要实现离开TestAds页面(点击默认返回按钮)和切换底部Tab页面时展示插屏广告,需要分两步处理:

  1. 在TestAds页面监听导航返回事件,页面卸载前触发广告。
  2. 在底部Tab导航中监听Tab切换事件,切换前触发广告。
  3. 预加载广告并管理加载状态,确保广告可用时才显示,避免报错。

二、代码修改

1. 优化TestAds页面(处理返回按钮事件)

import React, { useState, useEffect, useRef } from "react";
import { View, Text, ScrollView } from 'react-native';
import { InterstitialAd, TestIds, AdEventType } from 'react-native-google-mobile-ads';

const TestAds = ({ navigation }) => {
  // 保存广告实例,避免重复创建
  const interstitialRef = useRef(null);
  // 标记广告是否加载完成
  const [adLoaded, setAdLoaded] = useState(false);

  useEffect(() => {
    // 创建插屏广告实例
    const interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL, {
      requestNonPersonalizedAdsOnly: true,
      keywords: ['fashion', 'clothing'],
    });
    interstitialRef.current = interstitial;

    // 监听广告加载成功
    const loadedListener = interstitial.addAdEventListener(AdEventType.LOADED, () => {
      setAdLoaded(true);
    });

    // 监听广告加载失败
    const failedListener = interstitial.addAdEventListener(AdEventType.FAILED_TO_LOAD, (error) => {
      console.log('插屏广告加载失败:', error);
      setAdLoaded(false);
    });

    // 初始化加载广告
    interstitial.load();

    // 监听页面离开事件(默认返回按钮触发)
    const unsubscribe = navigation.addListener('beforeRemove', (e) => {
      if (adLoaded) {
        // 先阻止默认导航行为
        e.preventDefault();
        // 显示广告,完成后再执行导航
        interstitialRef.current.show().then(() => {
          navigation.dispatch(e.data.action);
          // 广告显示后重新加载,以备下次使用
          interstitialRef.current.load();
          setAdLoaded(false);
        }).catch((error) => {
          console.log('广告显示失败:', error);
          // 显示失败时直接执行导航
          navigation.dispatch(e.data.action);
        });
      }
    });

    // 清理监听器和广告实例,防止内存泄漏
    return () => {
      unsubscribe();
      loadedListener?.remove();
      failedListener?.remove();
      interstitialRef.current = null;
    };
  }, [navigation, adLoaded]);

  return (
    <ScrollView>
      <View style={{ marginTop: 20, padding: 16 }}>
        <Text>
          Lorem Ipsum is simply dummy text of the printing and typesetting industry.
          Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
        </Text>
      </View>
    </ScrollView>
  );
};

export default TestAds;

2. 优化HomeTabs组件(处理Tab切换事件)

import * as React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Contact from './Contact';
import Test from './Test';
import { InterstitialAd, TestIds, AdEventType } from 'react-native-google-mobile-ads';

const Tab = createBottomTabNavigator();

const HomeTabs = () => {
  const interstitialRef = React.useRef(null);
  const [adLoaded, setAdLoaded] = React.useState(false);

  React.useEffect(() => {
    // 创建并预加载广告
    const interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL, {
      requestNonPersonalizedAdsOnly: true,
      keywords: ['fashion', 'clothing'],
    });
    interstitialRef.current = interstitial;

    const loadedListener = interstitial.addAdEventListener(AdEventType.LOADED, () => {
      setAdLoaded(true);
    });

    const failedListener = interstitial.addAdEventListener(AdEventType.FAILED_TO_LOAD, (error) => {
      console.log('插屏广告加载失败:', error);
      setAdLoaded(false);
    });

    interstitial.load();

    return () => {
      loadedListener?.remove();
      failedListener?.remove();
      interstitialRef.current = null;
    };
  }, []);

  return (
    <Tab.Navigator screenOptions={{ headerShown: false }}>
      <Tab.Screen 
        name="Contact" 
        component={Contact}
        listeners={{
          tabPress: (e) => {
            if (adLoaded) {
              e.preventDefault();
              interstitialRef.current.show().then(() => {
                e.target.navigate('Contact');
                // 重新加载广告
                interstitialRef.current.load();
                setAdLoaded(false);
              }).catch((error) => {
                console.log('广告显示失败:', error);
                e.target.navigate('Contact');
              });
            }
          }
        }}
      />
      <Tab.Screen 
        name="Test" 
        component={Test}
        listeners={{
          tabPress: (e) => {
            if (adLoaded) {
              e.preventDefault();
              interstitialRef.current.show().then(() => {
                e.target.navigate('Test');
                interstitialRef.current.load();
                setAdLoaded(false);
              }).catch((error) => {
                console.log('广告显示失败:', error);
                e.target.navigate('Test');
              });
            }
          }
        }}
      />
    </Tab.Navigator>
  );
};

export default HomeTabs;

3. 修复App.js的导航错误

原代码中TestAds页面错误使用了<Tab.Screen>,改为<Stack.Screen>:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import TestAds from './TestAds';
import HomeTabs from './HomeTabs';

const Stack = createNativeStackNavigator();

export default function App () {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeTabs} />
        <Stack.Screen name="TestAds" component={TestAds} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

三、关键说明

  • 广告预加载:在组件挂载时提前加载广告,确保触发时机有可用广告。
  • 事件监听:使用beforeRemove监听页面返回,tabPress监听Tab切换,拦截默认行为后显示广告。
  • 错误处理:广告加载/显示失败时,保证导航流程正常执行,不阻塞用户操作。
  • 内存管理:及时清理事件监听器和广告实例,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:06:27