信息流广告
简介
SDK为接入方提供了可自定义布局的信息流广告,包含大图、小图、组图和视频以及模板等五种基本样式类型(具体的布局摆放可自行定义),及电话拨打、应用下载、跳转到落地页、跳转到浏览器四种交互类型。
注意事项
①聚合SDK是通过广告位ID发起广告请求的,切记不要使用混淆。
②在广告接入前需要明确各ADN对应聚合SDK广告样式情况,以确保正确完成广告接入,避免由于广告类型不匹配导致接入报错等情况的发生。
③由于各广告平台对于包名校验规则不同,需确保在平台填写的包名符合各ADN平台规范,避免由于包名校验不匹配导致的无广告返回情况的产生。
④广告请求时机,建议在收到SDK初始化成功回调后发起广告请求,当SDK初始化回调一直失败时,建议首先明确应用ID及广告位ID是否赋值正确、是否有多余空格、是否是网络不稳定导致的超时等,当排查后无法定位问题时,建议通过抓包将config字段下的加密内容提供过来,我们协助定位。
⑤如若针对展示失败有重试机制,建议只重试一次即可,避免无限重试引发死循环场景。
⑥自渲染类型广告,在展示广告View时,广告元素如title,下载button等相关的控件,它们的父类必须使用NativeSelfRenderAdContainer布局 ,否则将会影响广告点击计费事件。视频类容器也需要使用必须使用NativeSelfRenderAdContainer布局,否则可能会影响展示或者展示计费事件;
接入信息流广告
一、创建NativeAd对象
NativeAd nativeAds = NativeAd(this, config)//需要传activity,切记!!!
二、创建广告请求AdRequestConfig
val config: AdRequestConfig = AdRequestConfig.Builder()
.slotId(SCENE_ID) //广告场景id
.widthDp(screenSizeDP[0]) //请求图片宽度dp值
.heightDp(0) //请求图片高度dp值
.requestCount(AD_COUNT_EACH_PAGE) //信息流广告请求条数
.isVideoVoiceOn(false)
/**
* 设置视频自动播放场景:
* ALWAYS - 所有网络环境均自动播放
* WIFI - WIFI网络环境自动播放
* NEVER - 所有网络环境均不会自动播放
*/
.videoAutoPlayPolicy(AdRequestConfig.VideoAutoPlayPolicy.ALWAYS) // .addSougouAdTemplate(AdTemplate.BIG_IMG_TPL_ID)
// .addSougouAdTemplate(AdTemplate.DOWNLOAD_BIG_TPL_ID)
.showDownloadConfirmDialog(true)
.isAdNeedRemoveDuplicates(true)
.build()
三、请求广告
nativeAds!!.setListener(object : NativeAdsListener {
override fun onAdReady(arrayList: List<NativeAdsResponse?>?) {
listener?.onDataLoadResult(arrayList)
}
override fun onAdFailed(s: String) {
listener?.onDataLoadResult(java.util.ArrayList<NativeAdsResponse?>())
Toast.makeText(this@NativeActivity, "广告请求失败: $s", Toast.LENGTH_SHORT).show()
Log.e("CLOOOUDAD", "NativeAd onAdFailed: $s")
}
})
四、展示广告
// 信息流穿插广告
val adsResponse: NativeAdsResponse = mDataList[position] as NativeAdsResponse
if (holder is LargeImageViewHolder) {
holder.initViewHolderHeader(context, adsResponse)
if (adsResponse.imageUrls != null && adsResponse.imageUrls.size !== 0
) {
val url: String = adsResponse.imageUrls[0]
GlideTool.load(context, url, holder.largeImage)
}
if (holder.closeBtn != null) {
holder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
holder.adContainer.visibility = View.GONE
// NativeActivity.closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
//判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (holder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
holder.download_item!!.visibility = View.VISIBLE
holder.AppName.text = adsResponse.downloadAppName
holder.AppVersion.text = adsResponse.appVersion
holder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
holder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
}
//权限说明点击
holder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
//权限弹框,需要客户端处理
val PermissionsMap: Map<String, String> = adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is SmallImageViewHolder) {
val smallImageHolder = holder
smallImageHolder.initViewHolderHeader(context, adsResponse)
if (!TextUtils.isEmpty(adsResponse.desc)) {
smallImageHolder.desc2.text = adsResponse.desc
}
val url: String = adsResponse.imageUrls[0]
GlideTool.load(context, url, smallImageHolder.smallImage)
if (smallImageHolder.closeBtn != null) {
smallImageHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
smallImageHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
//判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (smallImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
smallImageHolder.download_item!!.visibility = View.VISIBLE
smallImageHolder.AppName.text = adsResponse.downloadAppName
smallImageHolder.AppVersion.text = adsResponse.appVersion
smallImageHolder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
smallImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
}
//权限说明点击
smallImageHolder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框,需要客户端处理
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is GroupImageViewHolder) {
val groupImageHolder = holder
groupImageHolder.initViewHolderHeader(context, adsResponse)
val imageUrlList: List<String> = adsResponse.getImageUrls()
val imageNum = imageUrlList.size
if (imageNum > 0) {
groupImageHolder.adImage1.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[0], groupImageHolder.adImage1)
} else {
groupImageHolder.adImage1.visibility = View.GONE
}
if (imageNum > 1) {
groupImageHolder.adImage2.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[1], groupImageHolder.adImage2)
} else {
groupImageHolder.adImage2.visibility = View.GONE
}
if (imageNum > 2) {
groupImageHolder.adImage3.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[2], groupImageHolder.adImage3)
} else {
groupImageHolder.adImage3.visibility = View.GONE
}
if (groupImageHolder.closeBtn != null) {
groupImageHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
groupImageHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
// 判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (groupImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
groupImageHolder.download_item!!.visibility = View.VISIBLE
groupImageHolder.AppName.text = adsResponse.downloadAppName
groupImageHolder.AppVersion.text = adsResponse.appVersion
groupImageHolder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
groupImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.privacyUrl)
}
//权限说明点击
groupImageHolder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is VideoViewHolder) {
val viewHolder = holder
viewHolder.initViewHolderHeader(context, adsResponse)
if (viewHolder.container != null) {
val videoView: View? = adsResponse.getVideoView(context)
if (videoView != null && videoView.parent !== viewHolder.container) {
val viewGroup = videoView.parent as ViewGroup?
viewGroup?.removeView(videoView)
val lp = RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
)
viewHolder.container!!.addView(videoView, lp)
}
}
if (viewHolder.closeBtn != null) {
viewHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
viewHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (viewHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
viewHolder.download_item!!.visibility = View.VISIBLE
viewHolder.AppName.text = adsResponse.downloadAppName
viewHolder.AppVersion.text = adsResponse.appVersion
viewHolder.DeveloperName.text = adsResponse.developerName
viewHolder.PrivacyUrl.setOnClickListener { v: View? ->
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPrivacyUrl()
// )
}
viewHolder.Permissions.setOnClickListener { v: View? ->
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is ExpressNativeHolder) {
// 模板广告
val viewHolder = holder
adsResponse.setTTDefaultDislikeDialog(context as Activity?) //设置穿山甲SDK的dislike弹窗
viewHolder.mAdSource.text = adsResponse.adSource.getName()
if (viewHolder.container != null) {
//获取模板view
val video: View = adsResponse.expressAdView
if (video != null) {
if (video.parent != null) {
val viewGroup = video.parent as ViewGroup
viewGroup.removeView(video)
}
viewHolder.container!!.removeAllViews()
val lp = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
viewHolder.container!!.addView(video, lp)
}
}
}
// 注册原生信息流广告可点击区域视图,建议为客户端单个原生广告位所有区域,在广告展现时调用
adsResponse.registerNativeClickableView(
holder.itemView as ViewGroup,
context,
holder.itemView as ViewGroup
)
CAdInfo 说明
<table>
<tr>
<td><b>方法名</b></td>
<td><b>说明</b></td>
</tr>
<tr>
<td> int getNetworkFirmId() </td>
<td> 返回竞价成功广告网络ID </td>
</tr>
<tr>
<td> String getAdsourceId() </td>
<td> 返回竞价成功广告源ID </td>
</tr>
<tr>
<td> double getEcpm() </td>
<td> 返回竞价成功价格 </td>
</tr>
</table>
接口说明
AdRequestConfig.Builder说明
广告请求参数
方法名 | 说明 |
slotId(String slotId) | 聚合广告位ID |
requestCount(int adCount) | 请求广告数,最多不超过3个 |
widthDp(int width) | 自渲染设置宽,单位dp |
heightDp(int height) | 模板设置高,单位dp |
isVideoVoiceOn(boolean isVoiceOn) | 视频播放是否有声音 |
videoAutoPlayPolicy(VideoAutoPlayPolicy policy) | 置视频自动播放场景 |
NativeAdsResponse.NativeActionListener 说明
广告加载回调
方法名 | 说明 |
onAdClick() | 广告点击回调 |
onAdShow(CAdInfo cAdInfo) | 广告展示回调 |
onError(String error) | 错误回调 |
onAdClose(String s) | 广告关闭回调 |
onExpressRenderFail(String error) | 模板渲染失败 |
onExpressRenderSuccess(View var1, float var2, float var3) | 模板渲染成功 |
onExpressRenderTimeout() | 模板渲染超时 |
onDislikeDialogShow() | 取消反馈弹框回调 |
onDownloadConfirmDialogDismissed() | 下载确认弹框关闭 |
NativeAdsResponse 说明
信息流广告对象
方法名 | 说明 |
String getTitle() | 广告标题 |
String getDesc() | 广告描述 |
int getSelfRenderAdMediaType() | 自渲染广告媒体主类型 |
int getSelfRenderAdStyle() | 自渲染广告样式 |
String getDspLogoUrl() | 广告源角标 |
List getImageUrls() | 广告图片Image list,返回的list可能为0个 |
int getInteractionType() | 原生广告交互类型 |
String getLogoUrl() | 原生信息流自渲染广告素材 |
String getImageUrl() | 原生信息流自渲染广告素材 |
boolean isExpressAd() | 判断是否是模板 |
render() | 模板加载前调用 |
void registerNativeClickableView(ViewGroup viewGroup, Context context, View creativeViews) | 注册原生信息流广告可点击区域视图 |
View getExpressAdView() | 模板类型获取广告View |
View getVideoView(Context context) | 获取视频view |
String getDownloadAppName() | 下载App名称 |
int getInteractionType() | 获取交互类型 |
String getAppVersion() | 下载App版本 |
void onDestroy() | 资源释放 |
String getDeveloperName() | 下载应用开发者 |
String getPrivacyUrl() | 下载应用隐私 |
Map |
下载应用权限(需判空) |
String getPermissionInfoUrl() | 下载应用权限链接(需判空) |
class NativeActivity : AppCompatActivity() {
val TAG = "NativeAD"
// 每页信息流的数量
private val NEWS_COUNT_EACH_PAGE = 1
private val AD_COUNT_EACH_PAGE = 3
private var AD_COUNT = 0
private var mContext: Context? = null
private var nativeAds: NativeAd? = null
private var mNativeFeedList: RecyclerView? = null
private var mRefreshLayout: SmartRefreshLayout? = null
// 当前加载信息流位置
private var mCurFeedListIndex = 0
private var mCurPageIndex = 0
private var mAdapter: NativeFeedAdapter? = null
// 保存信息流列表数据
private val mDataList = ArrayList<Any>()
// 保存广告列表
private val mAdList = ArrayList<NativeAdsResponse>()
private var isShowDownloadConfirmDialog = false
private var SCENE_ID: String? = "2323537"
private var IS_FINISH = false
companion object {
private val mAppDownloadListenerMap: WeakHashMap<RecyclerView.ViewHolder, CAppDownloadListener> =
WeakHashMap<RecyclerView.ViewHolder, CAppDownloadListener>()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_native)
mContext = applicationContext
getIntentData()
isShowDownloadConfirmDialog =
SharedPreferencesUtils.getParam(this, "isShowDownloadConfirmDialog", true) as Boolean
mRefreshLayout = findViewById(R.id.refreshLayout)
mNativeFeedList = findViewById<View>(R.id.recycler_view) as RecyclerView
mNativeFeedList!!.layoutManager = LinearLayoutManager(this)
val itemDecoration = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(resources.getDrawable(R.drawable.drawable_recyclerview_divider))
mNativeFeedList!!.addItemDecoration(itemDecoration)
mAdapter = NativeFeedAdapter(this,mDataList)
mNativeFeedList!!.adapter = mAdapter
mRefreshLayout!!.setOnRefreshListener(OnRefreshListener {
mRefreshLayout!!.setEnableLoadMore(false)
AD_COUNT = 0
refreshData()
})
mRefreshLayout!!.setOnLoadMoreListener(OnLoadMoreListener {
mRefreshLayout!!.setEnableRefresh(false)
AD_COUNT = 0
loadMoreData()
})
// 自动刷新
mRefreshLayout!!.autoRefresh()
}
private fun getIntentData() {
SCENE_ID = intent.getStringExtra("SCENE_ID")
IS_FINISH = intent.getBooleanExtra("IS_FINISH", false)
}
/**
* 列表上拉加载更多列表
*/
private fun loadMoreData() {
// 限制加载更多
if (mCurPageIndex >= 10) {
mRefreshLayout!!.setNoMoreData(true)
mRefreshLayout!!.setEnableRefresh(true)
return
}
loadFeedList(object : onDataLoadListener {
override fun onDataLoadResult(dataList: List<NativeAdsResponse?>?) {
val isAdEmpty = dataList.isNullOrEmpty()
if (isAdEmpty) {
Toast.makeText(this@NativeActivity, "广告请求结果为空", Toast.LENGTH_SHORT)
.show()
}
// 填充数据
mCurPageIndex++
val tmpFeedList: MutableList<Any> = java.util.ArrayList()
for (i in 0 until NEWS_COUNT_EACH_PAGE) {
tmpFeedList.add(mCurFeedListIndex++.toString())
}
val random = Random()
if (!isAdEmpty) {
val tmpAdList: MutableList<NativeAdsResponse> =
java.util.ArrayList<NativeAdsResponse>()
for (i in dataList!!.indices) {
val nativeAdResponse: NativeAdsResponse? = dataList[i]
nativeAdResponse?.let {
tmpAdList.add(nativeAdResponse)
// TODO 打印自渲染素材
if (!nativeAdResponse.isExpressAd) {
Log.e("CLOOOUD_POLY", "title: " + nativeAdResponse.title)
Log.e("CLOOOUD_POLY", "desc: " + nativeAdResponse.desc)
Log.e(
"CLOOOUD_POLY",
"mainMediaType: " + nativeAdResponse.selfRenderAdMediaType
)
Log.e(
"CLOOOUD_POLY",
"subMediaType: " + nativeAdResponse.selfRenderAdStyle
)
Log.e("CLOOOUD_POLY", "dspLogoUrl: " + nativeAdResponse.dspLogoUrl)
Log.e("CLOOOUD_POLY", "LogoUrl: " + nativeAdResponse.logoUrl)
Log.e("CLOOOUD_POLY", "ImageUrl: " + nativeAdResponse.imageUrl)
val imageUrls: List<String> = nativeAdResponse.imageUrls
if (imageUrls != null && imageUrls.isNotEmpty()) {
for (index in imageUrls.indices) {
Log.e(
"CLOOOUD_POLY",
"imageUrls[" + index + "]: " + imageUrls[index]
)
}
} else {
Log.e("CLOOOUD_POLY", "imageUrls: empty")
}
Log.e("CLOOOUD_POLY", " ")
}
nativeAdResponse.setNativeActionListener(object :
NativeAdsResponse.NativeActionListener {
override fun onAdClick() {
Log.e("CLOOOUDAD", "NativeAd onAdClick")
}
override fun onAdShow(cAdInfo: CAdInfo?) {
Log.e("CLOOOUDAD", "NativeAd onAdShow")
}
override fun onError(s: String) {
Log.e("CLOOOUDAD", "NativeAd onError: $s")
}
override fun onAdClose(s: String) {
Log.e("CLOOOUD", "NativeAd onAdClose: $s")
onAdClosed(nativeAdResponse)
}
override fun onExpressRenderFail(s: String) {
//渲染失败
Toast.makeText(
this@NativeActivity,
"广告渲染失败: $s", Toast.LENGTH_SHORT
).show()
}
override fun onExpressRenderSuccess(view: View?, v: Float, v1: Float) {
// 渲染成功
}
override fun onExpressRenderTimeout() {
// 渲染超时
}
override fun onDislikeDialogShow() {}
override fun onDownloadConfirmDialogDismissed() {}
})
if (nativeAdResponse.isExpressAd) {
// 模板广告开始渲染
nativeAdResponse.render()
} else if (nativeAdResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
// 自渲染下载类广告,可设置下载回调,刷新自渲染下载按钮 (针对应用自渲染下载按钮的场景)
nativeAdResponse.appDownloadListener = NativeAppDownloadListener(nativeAdResponse)
}
// 随机插入广告
tmpFeedList.add(
random.nextInt(NEWS_COUNT_EACH_PAGE),
nativeAdResponse!!
)
}
}
mAdList.addAll(tmpAdList)
mDataList.addAll(tmpFeedList)
mAdapter!!.notifyDataSetChanged()
}
mRefreshLayout!!.finishLoadMore()
mRefreshLayout!!.setEnableRefresh(true)
mRefreshLayout!!.setEnableLoadMore(true)
Handler(Looper.getMainLooper()).postDelayed({
AD_COUNT++
if (AD_COUNT < NEWS_COUNT_EACH_PAGE) {
loadMoreData()
}
}, 500)
}
})
}
/**
* 列表下拉刷新更多数据
*/
private fun refreshData() {
loadFeedList(object : onDataLoadListener {
override fun onDataLoadResult(dataList: List<NativeAdsResponse?>?) {
val isAdEmpty = dataList.isNullOrEmpty()
if (isAdEmpty) {
Toast.makeText(this@NativeActivity, "广告请求结果为空", Toast.LENGTH_SHORT)
.show()
} else {
mCurPageIndex = 1
mCurFeedListIndex = 0
// 填充数据
val tmpFeedList: MutableList<Any> = java.util.ArrayList()
for (i in 0 until NEWS_COUNT_EACH_PAGE) {
tmpFeedList.add(mCurFeedListIndex++.toString())
}
val random = Random()
if (!isAdEmpty) {
val tmpAdList: MutableList<NativeAdsResponse> =
java.util.ArrayList<NativeAdsResponse>()
for (i in dataList!!.indices) {
val nativeAdResponse: NativeAdsResponse? = dataList[i]
nativeAdResponse?.let {
tmpAdList.add(nativeAdResponse)
// TODO 打印自渲染素材
if (!nativeAdResponse.isExpressAd) {
Log.e("CLOOOUD_POLY", "title: " + nativeAdResponse.title)
Log.e("CLOOOUD_POLY", "desc: " + nativeAdResponse.desc)
Log.e(
"CLOOOUD_POLY",
"mainMediaType: " + nativeAdResponse.selfRenderAdMediaType
)
Log.e(
"CLOOOUD_POLY",
"subMediaType: " + nativeAdResponse.selfRenderAdStyle
)
Log.e(
"CLOOOUD_POLY",
"dspLogoUrl: " + nativeAdResponse.dspLogoUrl
)
Log.e("CLOOOUD_POLY", "LogoUrl: " + nativeAdResponse.logoUrl)
val imageUrls: List<String> = nativeAdResponse.imageUrls
if (imageUrls != null && imageUrls.isNotEmpty()) {
for (index in imageUrls.indices) {
Log.e(
"CLOOOUD_POLY",
"imageUrls[" + index + "]: " + imageUrls[index]
)
}
} else {
Log.e("CLOOOUD_POLY", "imageUrls: empty")
}
Log.e("CLOOOUD_POLY", " ")
}
nativeAdResponse.setNativeActionListener(object :
NativeAdsResponse.NativeActionListener {
override fun onAdClick() {
Log.e("CLOOOUDAD", "NativeAd onAdClick")
}
override fun onAdShow(cAdInfo: CAdInfo) {
Log.e("CLOOOUD_POLY", "ecpm: " + cAdInfo.ecpm)
Log.e("CLOOOUDAD", "NativeAd onAdShow")
}
override fun onError(s: String) {
Log.e("CLOOOUDAD", "NativeAd onError: $s")
}
override fun onAdClose(s: String) {
Log.e("CLOOOUDpoly", "NativeAd onAdClose: $s")
onAdClosed(nativeAdResponse)
}
override fun onExpressRenderFail(s: String) {
//渲染失败
Toast.makeText(
this@NativeActivity,
"广告渲染失败: $s", Toast.LENGTH_SHORT
).show()
}
override fun onExpressRenderSuccess(view: View?, v: Float, v1: Float) {
// 渲染成功
}
override fun onExpressRenderTimeout() {
// 渲染超时
}
override fun onDislikeDialogShow() {}
override fun onDownloadConfirmDialogDismissed() {}
})
// 设置下载回调,目前仅支持快手、穿山甲和广点通自渲染广告
if (nativeAdResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
nativeAdResponse.appDownloadListener = NativeAppDownloadListener(
nativeAdResponse
)
}
if (nativeAdResponse.isExpressAd) {
nativeAdResponse.render()
}
// 随机插入广告
tmpFeedList.add(
random.nextInt(NEWS_COUNT_EACH_PAGE),
nativeAdResponse
)
}
}
// 回收旧广告
for (response in mAdList) {
response.onDestroy()
}
mAdList.clear()
mAdList.addAll(tmpAdList)
mDataList.clear()
mDataList.addAll(tmpFeedList)
mAdapter?.notifyDataSetChanged()
}
}
mRefreshLayout!!.finishRefresh()
mRefreshLayout!!.setEnableRefresh(true)
mRefreshLayout!!.setEnableLoadMore(true)
Handler(Looper.getMainLooper()).postDelayed({
AD_COUNT++
if (AD_COUNT < NEWS_COUNT_EACH_PAGE) {
loadMoreData()
}
}, 500)
}
})
if (!IS_FINISH) {
return
}
Handler(Looper.getMainLooper()).postDelayed({
finish()
if (nativeAds != null) {
nativeAds!!.onDestroy()
}
// 回收广告资源
if (mAdList != null) {
for (ad in mAdList) {
ad.onDestroy()
}
}
}, 65)
}
private fun loadFeedList(listener: onDataLoadListener?): NativeAd? {
val screenSizeDP: IntArray = Util.getScreenSizeInDP(applicationContext)
val dm = applicationContext.resources.displayMetrics
val config: AdRequestConfig = AdRequestConfig.Builder()
.slotId(SCENE_ID) //广告场景id
.widthDp(screenSizeDP[0]) //请求图片宽度dp值
.heightDp(0) //请求图片高度dp值
.requestCount(AD_COUNT_EACH_PAGE) //信息流广告请求条数
.isVideoVoiceOn(false)//视频播放是否有声音
/**
* 设置视频自动播放场景:
* ALWAYS - 所有网络环境均自动播放
* WIFI - WIFI网络环境自动播放
* NEVER - 所有网络环境均不会自动播放
*/
.videoAutoPlayPolicy(AdRequestConfig.VideoAutoPlayPolicy.ALWAYS) // .addSougouAdTemplate(AdTemplate.BIG_IMG_TPL_ID)
// .addSougouAdTemplate(AdTemplate.DOWNLOAD_BIG_TPL_ID)
.showDownloadConfirmDialog(true)
.build()
nativeAds = NativeAd(this, config)
nativeAds!!.setListener(object : NativeAdsListener {
override fun onAdReady(arrayList: List<NativeAdsResponse?>?) {
listener?.onDataLoadResult(arrayList)
}
override fun onAdFailed(s: String) {
listener?.onDataLoadResult(java.util.ArrayList<NativeAdsResponse?>())
Toast.makeText(this@NativeActivity, "广告请求失败: $s", Toast.LENGTH_SHORT).show()
Log.e("CLOOOUDAD", "NativeAd onAdFailed: $s")
}
})
return nativeAds
}
interface onDataLoadListener {
fun onDataLoadResult(dataList: List<NativeAdsResponse?>?)
}
/**
* 点击关闭广告按钮,触发此方法刷新信息流列表
*
* @param response
*/
private fun onAdClosed(response: NativeAdsResponse?) {
if (response != null) {
mDataList.remove(response)
mAdapter?.notifyDataSetChanged()
}
}
override fun onResume() {
super.onResume()
if (mAdList != null) {
for (response in mAdList) {
response.onResume()
}
}
}
class NativeFeedAdapter(c: Context?,mDataList: ArrayList<Any>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val layoutInflater: LayoutInflater
// 保存信息流列表数据
private var mDataList = ArrayList<Any>()
// 信息流列表正文 - 非广告
private val LIST_DATA_FEED_CONTENT = 1
// 信息流原生广告 - 自渲染大图广告
private val LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE = 2
// 信息流原生广告 - 自渲染小图广告
private val LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE = 3
// 信息流原生广告 - 自渲染三图广告
private val LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE = 4
// 信息流原生广告 - 自渲染视频广告
private val LIST_DATA_SELF_RENDER_AD_VIDEO = 5
// 信息流原生广告 - 原生模板
private val LIST_DATA_AD_EXPRESS = 6
private var context: Context? = null
init {
layoutInflater = LayoutInflater.from(c)
this.mDataList = mDataList
this.context = c
}
override fun getItemCount(): Int {
return mDataList?.size ?: 0
}
override fun getItemViewType(position: Int): Int {
val obj: Any = mDataList[position]
return if (obj is String) {
LIST_DATA_FEED_CONTENT
} else {
val response: NativeAdsResponse = obj as NativeAdsResponse
if (response.isExpressAd) {
LIST_DATA_AD_EXPRESS
} else {
when (response.selfRenderAdMediaType) {
NativeAdsResponse.NATIVE_AD_MEDIA_TYPE_IMAGE -> return when (response.selfRenderAdStyle) {
NativeAdsResponse.NATIVE_AD_STYLE_LARGE_IMAGE -> LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
NativeAdsResponse.NATIVE_AD_STYLE_SMALL_IMAGE -> LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE
NativeAdsResponse.NATIVE_AD_STYLE_GROUP_IMAGE -> LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE
else -> {
val imageNum: Int = response.imageUrls.size
if (imageNum < 3) {
LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
} else {
LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE
}
}
}
NativeAdsResponse.NATIVE_AD_MEDIA_TYPE_VIDEO -> return LIST_DATA_SELF_RENDER_AD_VIDEO
}
LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
LIST_DATA_FEED_CONTENT -> // 信息流正文
FeedViewHolder(
layoutInflater.inflate(
R.layout.layout_feed_list_item,
parent,
false
)
)
LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE -> LargeImageViewHolder(
layoutInflater.inflate(
R.layout.layout_native_self_render_ad_large_image,
parent,
false
)
)
LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE -> SmallImageViewHolder(
layoutInflater.inflate(
R.layout.layout_native_self_render_ad_small_image,
parent,
false
)
)
LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE -> GroupImageViewHolder(
layoutInflater.inflate(
R.layout.layout_native_self_render_ad_group_image,
parent,
false
)
)
LIST_DATA_SELF_RENDER_AD_VIDEO -> // 自渲染视频广告
VideoViewHolder(
layoutInflater.inflate(
R.layout.layout_self_render_video_native_ad,
parent,
false
)
)
LIST_DATA_AD_EXPRESS -> // 原生模板广告
ExpressNativeHolder(
layoutInflater.inflate(
R.layout.listitem_ad_native_express,
parent,
false
)
)
else -> ExpressNativeHolder(
layoutInflater.inflate(
R.layout.listitem_ad_native_express,
parent,
false
)
)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is FeedViewHolder) {
// 信息流正文
holder.bindData(mDataList[position] as String)
} else {
// 信息流穿插广告
val adsResponse: NativeAdsResponse = mDataList[position] as NativeAdsResponse
if (holder is LargeImageViewHolder) {
holder.initViewHolderHeader(context, adsResponse)
if (adsResponse.imageUrls != null && adsResponse.imageUrls.size !== 0
) {
val url: String = adsResponse.imageUrls[0]
GlideTool.load(context, url, holder.largeImage)
}
if (holder.closeBtn != null) {
holder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
holder.adContainer.visibility = View.GONE
// NativeActivity.closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
//判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (holder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
holder.download_item!!.visibility = View.VISIBLE
holder.AppName.text = adsResponse.downloadAppName
holder.AppVersion.text = adsResponse.appVersion
holder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
holder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
}
//权限说明点击
holder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
//权限弹框,需要客户端处理
val PermissionsMap: Map<String, String> = adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is SmallImageViewHolder) {
val smallImageHolder = holder
smallImageHolder.initViewHolderHeader(context, adsResponse)
if (!TextUtils.isEmpty(adsResponse.desc)) {
smallImageHolder.desc2.text = adsResponse.desc
}
val url: String = adsResponse.imageUrls[0]
GlideTool.load(context, url, smallImageHolder.smallImage)
if (smallImageHolder.closeBtn != null) {
smallImageHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
smallImageHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
//判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (smallImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
smallImageHolder.download_item!!.visibility = View.VISIBLE
smallImageHolder.AppName.text = adsResponse.downloadAppName
smallImageHolder.AppVersion.text = adsResponse.appVersion
smallImageHolder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
smallImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
}
//权限说明点击
smallImageHolder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框,需要客户端处理
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is GroupImageViewHolder) {
val groupImageHolder = holder
groupImageHolder.initViewHolderHeader(context, adsResponse)
val imageUrlList: List<String> = adsResponse.getImageUrls()
val imageNum = imageUrlList.size
if (imageNum > 0) {
groupImageHolder.adImage1.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[0], groupImageHolder.adImage1)
} else {
groupImageHolder.adImage1.visibility = View.GONE
}
if (imageNum > 1) {
groupImageHolder.adImage2.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[1], groupImageHolder.adImage2)
} else {
groupImageHolder.adImage2.visibility = View.GONE
}
if (imageNum > 2) {
groupImageHolder.adImage3.visibility = View.VISIBLE
GlideTool.load(context, imageUrlList[2], groupImageHolder.adImage3)
} else {
groupImageHolder.adImage3.visibility = View.GONE
}
if (groupImageHolder.closeBtn != null) {
groupImageHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
groupImageHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
// 判断是否是下载类广告
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (groupImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
//demo增加显示下载五要素布局
groupImageHolder.download_item!!.visibility = View.VISIBLE
groupImageHolder.AppName.text = adsResponse.downloadAppName
groupImageHolder.AppVersion.text = adsResponse.appVersion
groupImageHolder.DeveloperName.text = adsResponse.developerName
//隐私权限点击
groupImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
//点击跳转url加载
// NativeAd.UrlSkip(this@NativeActivity, adsResponse.privacyUrl)
}
//权限说明点击
groupImageHolder.Permissions.setOnClickListener { v: View? ->
//头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is VideoViewHolder) {
val viewHolder = holder
viewHolder.initViewHolderHeader(context, adsResponse)
if (viewHolder.container != null) {
val videoView: View? = adsResponse.getVideoView(context)
if (videoView != null && videoView.parent !== viewHolder.container) {
val viewGroup = videoView.parent as ViewGroup?
viewGroup?.removeView(videoView)
val lp = RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
)
viewHolder.container!!.addView(videoView, lp)
}
}
if (viewHolder.closeBtn != null) {
viewHolder.closeBtn!!.setOnClickListener {
Toast.makeText(
context,
"关闭广告",
Toast.LENGTH_SHORT
).show()
viewHolder.adContainer.visibility = View.GONE
// closeNativeSelfRenderAd(adsResponse)
notifyDataSetChanged()
}
}
if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
if (viewHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
viewHolder.download_item!!.visibility = View.VISIBLE
viewHolder.AppName.text = adsResponse.downloadAppName
viewHolder.AppVersion.text = adsResponse.appVersion
viewHolder.DeveloperName.text = adsResponse.developerName
viewHolder.PrivacyUrl.setOnClickListener { v: View? ->
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPrivacyUrl()
// )
}
viewHolder.Permissions.setOnClickListener { v: View? ->
if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
// NativeAd.UrlSkip(
// this@NativeActivity,
// adsResponse.getPermissionInfoUrl()
// )
} else {
val PermissionsMap: Map<String, String> =
adsResponse.permissionsMap
//权限弹框
NativeAd.CSJPermissionSkip(context, PermissionsMap)
}
}
}
}
} else if (holder is ExpressNativeHolder) {
// 模板广告
val viewHolder = holder
adsResponse.setTTDefaultDislikeDialog(context as Activity?) //设置穿山甲SDK的dislike弹窗
viewHolder.mAdSource.text = adsResponse.adSource.getName()
if (viewHolder.container != null) {
//获取模板view
val video: View = adsResponse.expressAdView
if (video != null) {
if (video.parent != null) {
val viewGroup = video.parent as ViewGroup
viewGroup.removeView(video)
}
viewHolder.container!!.removeAllViews()
val lp = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
viewHolder.container!!.addView(video, lp)
}
}
}
// 注册原生信息流广告可点击区域视图,建议为客户端单个原生广告位所有区域,在广告展现时调用
adsResponse.registerNativeClickableView(
holder.itemView as ViewGroup,
context,
holder.itemView as ViewGroup
)
}
}
}
/**
* 信息流内容
*/
class FeedViewHolder(v: View) : RecyclerView.ViewHolder(v) {
var title: TextView
init {
title = v.findViewById<View>(R.id.feed_item_title) as TextView
}
fun bindData(data: String) {
title.text = "信息流正文 $data"
}
}
/**
* 可下载广告 viewholder
*/
open class DownloadableAdViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
protected var adPackageName: TextView
protected var title: TextView
protected var desc: TextView
protected var adIcon: ImageView
protected var downloadState: TextView
protected var adCta: TextView
init {
adPackageName = itemView.findViewById(R.id.adPackageName)
title = itemView.findViewById(R.id.adTitle)
adIcon = itemView.findViewById(R.id.adIcon)
desc = itemView.findViewById<View>(R.id.adDesc) as TextView
downloadState = itemView.findViewById(R.id.adDownload)
adCta = itemView.findViewById(R.id.adCta)
}
// 更新下载状态
fun updateDownloadState(state: String?) {
if (state != null) {
downloadState.visibility = View.VISIBLE
downloadState.text = state
} else {
downloadState.visibility = View.INVISIBLE
}
}
// 更新下载状态
fun initViewHolderHeader(context: Context?, response: NativeAdsResponse) {
if (response.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
adIcon.visibility = View.VISIBLE
GlideTool.load(context, response.logoUrl, adIcon)
// 绑定
if (!response.isExpressAd) {
val listener: CAppDownloadListener = response.appDownloadListener
if (listener is NativeAppDownloadListener) {
(listener as NativeAppDownloadListener).bindViewHolder(this)
}
}
} else if (response.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_LANDINGPAGE) {
adIcon.visibility = View.GONE
adIcon.setImageBitmap(null)
updateDownloadState("查看详情")
}
// 广点通广告有个CTA功能,可以控制btn的显示文字跟功能,产品线可以按需接入
// String ctaText = response.getCtaText();
// Log.i("12345678","CTA======"+ctaText);
// // 将该View传递给广点通进行绑定
// response.bindCtaView(adCta);
// if (TextUtils.isEmpty(ctaText)) {
// adCta.setVisibility(View.INVISIBLE);
// } else {
// adCta.setVisibility(View.VISIBLE);
// adCta.setText(ctaText);
// downloadState.setVisibility(View.INVISIBLE);
// }
if (!TextUtils.isEmpty(response.packageName)) {
adPackageName.text = response.packageName
} else {
adPackageName.text = ""
}
if (!TextUtils.isEmpty(response.title)) {
title.text = response.adSource.toString() + response.title
} else {
title.text = response.adSource.getName()
}
if (!TextUtils.isEmpty(response.desc)) {
desc.text = response.desc
} else {
desc.text = ""
}
}
}
/**
* 原生自渲染图文类广告
*/
class LargeImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
var largeImage: ImageView
var closeBtn: View?
var download_item: LinearLayout?
var AppName: TextView
var AppVersion: TextView
var DeveloperName: TextView
var PrivacyUrl: TextView
var Permissions: TextView
var adContainer: NativeSelfRenderAdContainer;
init {
adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
largeImage = v.findViewById<View>(R.id.largeImage) as ImageView
closeBtn = v.findViewById(R.id.adCloseBtn)
download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
AppName = v.findViewById<View>(R.id.AppName) as TextView
Permissions = v.findViewById<View>(R.id.Permissions) as TextView
AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
}
}
/**
* 原生自渲染图文类广告
*/
class SmallImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
var smallImage: ImageView
var desc2: TextView
var closeBtn: View?
var download_item: LinearLayout?
var AppName: TextView
var AppVersion: TextView
var DeveloperName: TextView
var PrivacyUrl: TextView
var Permissions: TextView
var adContainer: NativeSelfRenderAdContainer;
init {
adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
desc2 = v.findViewById<View>(R.id.adDesc2) as TextView
closeBtn = v.findViewById(R.id.adCloseBtn)
smallImage = v.findViewById<View>(R.id.smallImage) as ImageView
download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
AppName = v.findViewById<View>(R.id.AppName) as TextView
Permissions = v.findViewById<View>(R.id.Permissions) as TextView
AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
}
}
/**
* 原生自渲染图文类广告
*/
class GroupImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
var adImage1: ImageView
var adImage2: ImageView
var adImage3: ImageView
var closeBtn: View?
var download_item: LinearLayout?
var AppName: TextView
var AppVersion: TextView
var DeveloperName: TextView
var PrivacyUrl: TextView
var Permissions: TextView
var adContainer: NativeSelfRenderAdContainer;
init {
adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
closeBtn = v.findViewById(R.id.adCloseBtn)
adImage1 = v.findViewById<View>(R.id.adImage1) as ImageView
adImage2 = v.findViewById<View>(R.id.adImage2) as ImageView
adImage3 = v.findViewById<View>(R.id.adImage3) as ImageView
download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
AppName = v.findViewById<View>(R.id.AppName) as TextView
Permissions = v.findViewById<View>(R.id.Permissions) as TextView
AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
}
}
/**
* 原生自渲染视频类广告
*/
class VideoViewHolder(v: View) : DownloadableAdViewHolder(v) {
var container: RelativeLayout?
var closeBtn: View?
var download_item: LinearLayout?
var AppName: TextView
var AppVersion: TextView
var DeveloperName: TextView
var PrivacyUrl: TextView
var Permissions: TextView
var adContainer: NativeSelfRenderAdContainer;
init {
adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
container = v.findViewById(R.id.videoContainer)
closeBtn = v.findViewById(R.id.adCloseBtn)
download_item = v.findViewById<View>(R.id.ad_group_image_download) as LinearLayout
// download_item = adDownload.findViewById<View>(R.id.download_item) as LinearLayout
AppName = download_item!!.findViewById<View>(R.id.AppName) as TextView
Permissions = download_item!!.findViewById<View>(R.id.Permissions) as TextView
AppVersion = download_item!!.findViewById<View>(R.id.AppVersion) as TextView
DeveloperName = download_item!!.findViewById<View>(R.id.DeveloperName) as TextView
PrivacyUrl = download_item!!.findViewById<View>(R.id.PrivacyUrl) as TextView
}
}
/**
* 原生模板广告
*/
class ExpressNativeHolder(v: View) : RecyclerView.ViewHolder(v) {
var container: FrameLayout?
var mAdSource: TextView
init {
container = v.findViewById<View>(R.id.iv_listitem_express) as FrameLayout
mAdSource = v.findViewById(R.id.mAdSource)
}
}
override fun onDestroy() {
super.onDestroy()
nativeAds?.onDestroy()
// 回收广告资源
if (mAdList != null) {
for (ad in mAdList) {
ad.onDestroy()
}
}
}
/**
* 关闭原生自渲染广告
*
* @param response
*/
private fun closeNativeSelfRenderAd(response: NativeAdsResponse) {
mDataList.remove(response)
mAdList.remove(response)
response.onCloseBtnClicked()
}
/**
* 广告下载回调
*/
internal class NativeAppDownloadListener(response: NativeAdsResponse) :
CAppDownloadListener {
var viewHolder: DownloadableAdViewHolder? = null
var adResponse: NativeAdsResponse
init {
adResponse = response
}
/**
* 绑定回调
*
* @param holder
*/
fun bindViewHolder(holder: DownloadableAdViewHolder?) {
viewHolder = holder
mAppDownloadListenerMap.put(viewHolder, this)
}
override fun onIdle() {
if (isInvalidCallBack) {
return
}
if (viewHolder != null) {
viewHolder!!.updateDownloadState("立即下载")
}
}
override fun onDownloadPaused() {
if (viewHolder != null) {
viewHolder!!.updateDownloadState("继续下载")
}
}
override fun onProgressUpdate(i: Int) {
if (isInvalidCallBack) {
return
}
if (viewHolder != null) {
viewHolder!!.updateDownloadState("下载 $i%")
}
}
override fun onDownloadFinished() {
if (isInvalidCallBack) {
return
}
if (viewHolder != null) {
viewHolder!!.updateDownloadState("点击安装")
}
}
override fun onDownloadFailed() {
if (isInvalidCallBack) {
return
}
if (viewHolder != null) {
viewHolder!!.updateDownloadState("下载失败")
}
}
override fun onInstalled() {
if (isInvalidCallBack) {
return
}
if (viewHolder != null) {
viewHolder!!.updateDownloadState("点击打开")
}
}
private val isInvalidCallBack: Boolean
private get() = mAppDownloadListenerMap.get(viewHolder) !== this
}
}