主题
横幅 —— NovvyBannerAd
常驻的横幅广告位,按定时器轮播素材:只要组件挂载,SDK 就一支接一支地填充,直到宿主 destroy()。
与其他类型有三处根本不同,对接前务必确认:
- 没有
load()—— 原生横幅在构造函数里就要拿到容器,而容器只有在 Fabric 原生视图创建后才存在,所以嵌入<NovvyBannerAdView>就是第一次请求。调用load()会通过onAdFailedToLoad报错并销毁实例(此后该实例不可再用)。 - 回调按「轮」触发,不是按「广告实例」触发 —— 每隔
refreshIntervalSeconds就会再来一次onAdLoaded/onAdShowed。onAdLoaded因此不是一次性的「就绪」转换。 onAdFailedToLoad不是终态 —— SDK 会退避重试,且屏幕上已有的素材保持不动。实例不会被销毁、isReady不被清掉,之后仍会照常收到onAdShowed。请把它当作警告而非结束,不要在这个回调里destroy()。
此外,横幅是唯一会把点击回传给宿主的类型(onAdClicked)。
对接流程
NovvyAds.setContentContext(...)
↓
嵌入 <NovvyBannerAdView>(视图就绪时自动 attach,即发起首次请求)
↓
onAdLoaded → onAdShowed // 第 1 轮
↓
(用户点击)→ onAdClicked // SDK 已完成跳转与上报
↓
onAdHidden → onAdLoaded → onAdShowed // 第 2 轮,refreshIntervalSeconds 后
↓
(某轮无货)→ onAdFailedToLoad // 非终态:退避重试,当前素材不动
↓
组件卸载 → 自动 detach;destroy() // 需宿主主动释放1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
尺寸档位
5 档尺寸沿用 IAB 规格,单位为逻辑像素(Android dp / iOS pt)。各档长宽比互不相同,这是硬约束而非巧合:后端是按长宽比给素材的,档位选错会没有填充,而不是把素材拉伸。
NovvyBannerSize | 尺寸(逻辑像素) | 宽高比 | 说明 |
|---|---|---|---|
Standard | 320 × 50 | 6.40 | 经典手机横幅(默认值) |
Large | 320 × 100 | 3.20 | 加高横幅 |
MediumRectangle | 300 × 250 | 1.20 | 中矩形 |
FullBanner | 468 × 60 | 7.80 | 全尺寸横幅 |
Leaderboard | 728 × 90 | 8.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 取值见错误类型 |
size | NovvyBannerSize,构造时传入,之后不可变(原生构造函数即固定尺寸;换档位需重建实例,见下方示例) |
refreshIntervalSeconds | 轮播间隔秒数,默认 60。原样传给原生,由原生钳制到 [30, 120];<= 0 表示关闭轮播,位上只留一支素材 |
width / height | number,当前档位的逻辑像素宽高 |
attach() | 发起请求并启动轮播。通常不用自己调用 —— <NovvyBannerAdView> 的原生视图就绪时会调一次。原生侧对重复调用幂等;实例已 destroy() 后调用则直接返回 |
detach() | 停止轮播(通常由组件卸载时自动调用)。终态 —— 原生侧只有 destroy() 一种拆卸,没有可重新 attach 的中间状态 |
destroy() | 释放原生实例并退订事件。需宿主自己调用:组件卸载只做 detach() |
NovvyBannerAd.sizesInDp | Record<NovvyBannerSize, { width, height }>,上表的档位尺寸表 |
NovvyBannerAd.defaultRefreshIntervalSeconds | 60(与两侧原生默认值一致) |
示例
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} />;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
换档位必须让组件重新挂载
<NovvyBannerAdView> 只在挂载时绑定它拿到的那个实例:把新实例塞给同一个已挂载的组件,结果是旧轮播继续跑、新实例永不 attach() —— 界面上看不出错,只是档位不对。做法是给组件一个随实例变化的 key:
tsx
const ad = useMemo(() => new NovvyBannerAd(AD_UNIT, size), [size]);
return <NovvyBannerAdView key={ad.adObjectId} ad={ad} />;1
2
2
<NovvyBannerAdView>的尺寸固定为档位尺寸,style只用来定位,写width/height不会生效。