Skip to content

横幅 —— NovvyBannerAd ​

常驻的横幅广告位,按定时器轮播素材:只要组件挂载,SDK 就一支接一支地填充,直到宿主 destroy()。

与其他类型有三处根本不同,对接前务必确认:

  1. 没有 load() —— 原生横幅在构造函数里就要拿到容器,而容器只有在 Fabric 原生视图创建后才存在,所以嵌入 <NovvyBannerAdView> 就是第一次请求。调用 load() 会通过 onAdFailedToLoad 报错并销毁实例(此后该实例不可再用)。
  2. 回调按「轮」触发,不是按「广告实例」触发 —— 每隔 refreshIntervalSeconds 就会再来一次 onAdLoaded / onAdShowed。onAdLoaded 因此不是一次性的「就绪」转换。
  3. onAdFailedToLoad 不是终态 —— SDK 会退避重试,且屏幕上已有的素材保持不动。实例不会被销毁、isReady 不被清掉,之后仍会照常收到 onAdShowed。请把它当作警告而非结束,不要在这个回调里 destroy()。

此外,横幅是唯一会把点击回传给宿主的类型(onAdClicked)。

对接流程 ​

NovvyAds.setContentContext(...)
        ↓
嵌入 <NovvyBannerAdView>(视图就绪时自动 attach,即发起首次请求)
        ↓
onAdLoaded  →  onAdShowed                   // 第 1 轮
        ↓
(用户点击)→ onAdClicked                    // SDK 已完成跳转与上报
        ↓
onAdHidden  →  onAdLoaded  →  onAdShowed    // 第 2 轮,refreshIntervalSeconds 后
        ↓
(某轮无货)→ onAdFailedToLoad               // 非终态:退避重试,当前素材不动
        ↓
组件卸载 → 自动 detach;destroy()            // 需宿主主动释放

尺寸档位 ​

5 档尺寸沿用 IAB 规格,单位为逻辑像素(Android dp / iOS pt)。各档长宽比互不相同,这是硬约束而非巧合:后端是按长宽比给素材的,档位选错会没有填充,而不是把素材拉伸。

NovvyBannerSize尺寸(逻辑像素)宽高比说明
Standard320 × 506.40经典手机横幅(默认值)
Large320 × 1003.20加高横幅
MediumRectangle300 × 2501.20中矩形
FullBanner468 × 607.80全尺寸横幅
Leaderboard728 × 908.09通栏

枚举值就是过桥字符串,请用枚举成员

NovvyBannerSize.MediumRectangle === 'mediumRectangle',两侧原生映射都按这个字符串匹配,认不出的值会静默回落到 standard 并打一条 warning —— 不会报错。所以请用枚举成员而不要手写字符串。

Leaderboard 宽 728 逻辑像素、FullBanner 宽 468,都比竖屏手机宽,放进布局会溢出并被裁掉。<NovvyBannerAdView> 刻意不缩放:档位是发给后端的形状请求,缩放会让素材以错误比例显示。要么改用窄档位,要么把它放进横向可滚动容器。

构造函数与类成员 ​

构造函数:new NovvyBannerAd(adUnitId: string, size?: NovvyBannerSize, refreshIntervalSeconds?: number)

成员说明
onAdLoaded() => void,一支素材已就绪(每轮触发一次)
onAdShowed() => void,素材出现在位上(每轮触发一次)
onAdClicked() => void,用户点击了素材。触发时 SDK 已完成点击上报与跳转,此回调仅供宿主自己埋点
onAdHidden() => void,位上素材被清空(两轮之间)
onAdFailedToLoad(error: string) => void,请求失败,非终态(见上文第 3 点),error 取值见错误类型
sizeNovvyBannerSize,构造时传入,之后不可变(原生构造函数即固定尺寸;换档位需重建实例,见下方示例)
refreshIntervalSeconds轮播间隔秒数,默认 60。原样传给原生,由原生钳制到 [30, 120];<= 0 表示关闭轮播,位上只留一支素材
width / heightnumber,当前档位的逻辑像素宽高
attach()发起请求并启动轮播。通常不用自己调用 —— <NovvyBannerAdView> 的原生视图就绪时会调一次。原生侧对重复调用幂等;实例已 destroy() 后调用则直接返回
detach()停止轮播(通常由组件卸载时自动调用)。终态 —— 原生侧只有 destroy() 一种拆卸,没有可重新 attach 的中间状态
destroy()释放原生实例并退订事件。需宿主自己调用:组件卸载只做 detach()
NovvyBannerAd.sizesInDpRecord<NovvyBannerSize, { width, height }>,上表的档位尺寸表
NovvyBannerAd.defaultRefreshIntervalSeconds60(与两侧原生默认值一致)

示例 ​

tsx
function BannerSlot(): React.ReactElement {
  const ad = useMemo(
    () => new NovvyBannerAd(AD_UNIT, NovvyBannerSize.Standard, 60),
    []
  );

  useEffect(() => {
    ad.onAdShowed = () => { /* 本轮素材已展示 */ };
    ad.onAdClicked = () => { /* 自行埋点;跳转已由 SDK 完成 */ };
    // 非终态:不要在这里 destroy(),SDK 会退避重试
    ad.onAdFailedToLoad = (e) => console.log('banner:', e);
    // 组件卸载只 detach(),释放原生实例仍要宿主自己来
    return () => ad.destroy();
  }, [ad]);

  return <NovvyBannerAdView ad={ad} />;
}

换档位必须让组件重新挂载

<NovvyBannerAdView> 只在挂载时绑定它拿到的那个实例:把新实例塞给同一个已挂载的组件,结果是旧轮播继续跑、新实例永不 attach() —— 界面上看不出错,只是档位不对。做法是给组件一个随实例变化的 key:

tsx
const ad = useMemo(() => new NovvyBannerAd(AD_UNIT, size), [size]);
return <NovvyBannerAdView key={ad.adObjectId} ad={ad} />;

<NovvyBannerAdView> 的尺寸固定为档位尺寸,style 只用来定位,写 width / height 不会生效。

本文档仅供技术对接使用,请勿外传。