开屏V+广告
基本信息
开屏V+广告: 5s-30s的视频广告,在5s开屏呈现的过程中用户点击右上角的“进入首页”或5s曝光结束后视频将收缩到APP内右下角的小视窗继续播放。
权限等级:需要申请
适用场景:开屏V+广告会在您的应用开启时加载,广告曝光过程中用户点击右上角的“进入首页”或5s曝光结束后将收缩到APP首页右下角的小视窗继续播放。
分类:开屏V+广告分为半屏和全屏,其中半屏开屏V+广告支持开发者自定义设置开屏底部的界面,用以展示应用Logo等。具体种类可以在开发者平台进行选择:
半屏 | 全屏 | 悬浮状态 | 落地页 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
视频示例 |
---|
![]() |
接入代码示例
(关键代码展示,详细请参考压缩包的代码)
public class SplashADActivity extends Activity implements View.OnClickListener,
AdapterView.OnItemSelectedListener, SplashADZoomOutListener {
private View splashView;
private SplashAD splashAD;
private ViewGroup zoomOutView;
private boolean isZoomOuted;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_ad);
findViewById(R.id.splashShowInView).setOnClickListener(this);
}
private String getPosID() {
String posId = ((EditText) findViewById(R.id.posId)).getText().toString();
return TextUtils.isEmpty(posId) ? PositionId.SPLASH_POS_ID : posId;
}
private boolean needLogo() {
return ((CheckBox) findViewById(R.id.checkBox)).isChecked();
}
private boolean customSkipBtn(){
return ((CheckBox)findViewById(R.id.checkCustomSkp)).isChecked();
}
@Override
public void onClick(View v) {
cleanZoomOut();
switch (v.getId()) {
case R.id.splashShowInView:
showSplashInThisActivity();
break;
}
}
private void showSplashInThisActivity() {
Log.d(TAG, "showSplashInThisActivity");
DemoUtil.hideSoftInput(this);
if (splashView == null) {
ViewGroup contentView = findViewById(android.R.id.content);
LayoutInflater inflater = getLayoutInflater();
splashView = inflater.inflate(R.layout.activity_splash, null);
splashView.setClickable(true);//显示出来的时候阻止点击事件传递到后面的按钮
contentView.addView(splashView);
Log.d(TAG, "contentView child count:" + contentView.getChildCount());
} else if (splashView.getVisibility() == View.VISIBLE) {
Toast.makeText(SplashADActivity.this.getApplicationContext(), "有开屏正在展示,忽略本次拉取",
Toast.LENGTH_SHORT).show();
Log.d(TAG, "有开屏正在展示,忽略本次拉取");
return;
} else {
splashView.setVisibility(View.VISIBLE);
}
if (!needLogo()) {
splashView.findViewById(R.id.app_logo).setVisibility(View.GONE);
} else {
splashView.findViewById(R.id.app_logo).setVisibility(View.VISIBLE);
}
TextView skipView = null;
if (customSkipBtn()) {
skipView = splashView.findViewById(R.id.skip_view);
skipView.setVisibility(View.VISIBLE);
} else {
splashView.findViewById(R.id.skip_view).setVisibility(View.GONE);
}
ViewGroup container = splashView.findViewById(R.id.splash_container);
container.removeAllViews();
//因为SplashAD是和广告位绑定的,在广告位变化时需要重新创建
splashAD = new SplashAD(this, skipView, getPosID(), this, 0);
Log.d(TAG, "fetchAndShowIn");
isZoomOuted = false;
splashAD.fetchAndShowIn(container);
}
private void cleanZoomOut() {
if (zoomOutView != null) {
ViewUtils.removeFromParent(zoomOutView);
zoomOutView = null;
}
}
@Override
public void onADDismissed() {
splashView.setVisibility(View.GONE);
if (isZoomOuted && zoomOutView != null) {
ViewUtils.removeFromParent(zoomOutView);
}
Log.d(TAG, "onADDismissed");
}
@Override
public void onNoAD(AdError error) {
splashView.setVisibility(View.GONE);
String str = String.format("LoadSplashADFail, eCode=%d, errorMsg=%s", error.getErrorCode(),
error.getErrorMsg());
Log.i("AD_DEMO", str);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(SplashADActivity.this.getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onADPresent() {
Log.d(TAG, "onADPresent");
}
@Override
public void onADClicked() {
Log.d(TAG, "onADClicked");
}
@Override
public void onADTick(long millisUntilFinished) {
Log.d(TAG, "onADTick");
if (splashView != null) {
TextView skipView = splashView.findViewById(R.id.skip_view);
if (skipView != null && skipView.getVisibility() == View.VISIBLE)
skipView.setText(String.format(SKIP_TEXT, Math.round(millisUntilFinished / 1000f)));
}
}
@Override
public void onADExposure() {
Log.d(TAG, "onADExposure");
}
@Override
public void onADLoaded(long expireTimestamp) {
Log.d(TAG, "onADLoaded");
}
@Override
public void onZoomOut() {
Log.d(TAG, "onZoomOut");
isZoomOuted = true;
SplashZoomOutManager splashZoomOutManager = SplashZoomOutManager.getInstance();
View splash = ((ViewGroup) splashView.findViewById(R.id.splash_container)).getChildAt(0);
if (splash == null) {
Log.e(TAG, "在开屏展示的过程中进行了新的拉取,导致广告View被清空了");
return;
}
splash.setVisibility(View.VISIBLE);
ViewGroup content = findViewById(android.R.id.content);
zoomOutView = splashZoomOutManager.startZoomOut(splash, content, content,
new SplashZoomOutManager.AnimationCallBack() {
@Override
public void animationStart(int animationTime) {
Log.d(TAG, "animationStart:" + animationTime);
}
@Override
public void animationEnd() {
Log.d(TAG, "animationEnd");
splashAD.zoomOutAnimationFinish();
}
});
splashView.setVisibility(View.GONE);
}
@Override
public void onZoomOutPlayFinish() {
Log.d(TAG, "onPlayFinish");
}
@Override
public boolean isSupportZoomOut() {
return true;
}
}
主要 API
代码中*zoomOut*
命名即为开屏V+相关逻辑。
SplashAD
- com.qq.e.ads.splash.SplashAD:
和开屏广告使用同样的方法,开屏V+新增的方法如下
方法名 | 方法介绍 |
---|---|
zoomOutAnimationFinish() | 开屏V+使用该接口(4.310.1180)版本之后,使用该接口,通知sdk,开屏V+的窗口已经动画结束,sdk会处理内部状态和显示关闭按钮,在显示开屏V+广告时必须回调该函数 |
Bitmap getZoomOutBitmap() | 开屏V+使用该接口(4.310.1180)版本之后,执行动画时移动view前可以通过该接口获取当前视频的截图,放在被移除的地方,减少动画闪烁 |
SplashADZoomOutListener
- com.qq.e.ads.splash.SplashADZoomOutListener:
开屏V+广告回调接口,开屏V使用(4.310.1180)版本之后,该接口继承自SplashADListener(参见开屏广告),同时支持开屏V+广告和非V+广告,只有开屏V+类型的广告会回调下面新增的方法。
方法名 | 方法介绍 |
---|---|
onZoomOut() | 开屏V+广告开始进入小窗悬挂状态,收到该回调时可以进行动画缩小广告的播放界面,动画完成后要调用zoomOutAnimationFinish |
onZoomOutPlayFinish() | 开屏V+的视频播放结束 |
isSupportZoomOut() | 在使用SplashADZoomOutListener接口时不支持开屏V+广告可以在这里返回false |
开屏V+ demo辅助函数
demo的动画提供了开屏V+辅助函数供开发者参考,详细细节可以参见demo代码,悬浮窗的尺寸,应尽量使用推荐的尺寸,必须宽高比为 16:9。
- com.qq.e.union.demo.util.SplashZoomOutManager:
方法名 | 方法介绍 |
---|---|
startZoomOut | 开屏V+动画实现参考,内部有定义推荐的悬浮窗的尺寸,应尽量使用推荐的尺寸,否则可能导致显示异常 |
setSplashInfo() | 开屏V+动画实现参考,开屏使用单独的activity时,使用该方法在不同activty间传递数据 |
- com.qq.e.union.demo.util.SplashZoomOutLayout:
开屏V+在悬浮时的示例布局,实现了拖动和点击传递的功能。
接入注意事项
- 同开屏广告