Commit a99a7acd authored by jyx's avatar jyx

添加首页快手信息流

parent 7364b611
...@@ -70,6 +70,8 @@ android { ...@@ -70,6 +70,8 @@ android {
buildConfigField "String", "GROMORE_BANNER_CODE", GROMORE_BANNER_CODE buildConfigField "String", "GROMORE_BANNER_CODE", GROMORE_BANNER_CODE
buildConfigField "String", "GROMORE_FULL_CODE", GROMORE_FULL_CODE buildConfigField "String", "GROMORE_FULL_CODE", GROMORE_FULL_CODE
buildConfigField "String", "GROMORE_HALF_CODE", GROMORE_HALF_CODE buildConfigField "String", "GROMORE_HALF_CODE", GROMORE_HALF_CODE
buildConfigField "long", "KS_EXPRESS_CODE", KS_EXPRESS_CODE
buildConfigField "long", "KS_EXPRESS_2_CODE", KS_EXPRESS_2_CODE
buildConfigField "String", "RELEASE_TALKING_DATA_KEY", RELEASE_TALKING_DATA_KEY buildConfigField "String", "RELEASE_TALKING_DATA_KEY", RELEASE_TALKING_DATA_KEY
buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID
buildConfigField "String", "SM_APP_ID", SM_APP_ID buildConfigField "String", "SM_APP_ID", SM_APP_ID
...@@ -97,6 +99,8 @@ android { ...@@ -97,6 +99,8 @@ android {
buildConfigField "String", "GROMORE_BANNER_CODE", GROMORE_BANNER_CODE buildConfigField "String", "GROMORE_BANNER_CODE", GROMORE_BANNER_CODE
buildConfigField "String", "GROMORE_FULL_CODE", GROMORE_FULL_CODE buildConfigField "String", "GROMORE_FULL_CODE", GROMORE_FULL_CODE
buildConfigField "String", "GROMORE_HALF_CODE", GROMORE_HALF_CODE buildConfigField "String", "GROMORE_HALF_CODE", GROMORE_HALF_CODE
buildConfigField "long", "KS_EXPRESS_CODE", KS_EXPRESS_CODE
buildConfigField "long", "KS_EXPRESS_2_CODE", KS_EXPRESS_2_CODE
buildConfigField "String", "RELEASE_TALKING_DATA_KEY", RELEASE_TALKING_DATA_KEY buildConfigField "String", "RELEASE_TALKING_DATA_KEY", RELEASE_TALKING_DATA_KEY
buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID
buildConfigField "String", "SM_APP_ID", SM_APP_ID buildConfigField "String", "SM_APP_ID", SM_APP_ID
......
package com.duben.miniplaylet.ad.ks
import android.annotation.SuppressLint
import android.app.Activity
import android.content.DialogInterface
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.duben.miniplaylet.BuildConfig
import com.duben.miniplaylet.MintsApplication
import com.duben.miniplaylet.R
import com.duben.miniplaylet.ad.express.ExpressAdCallback
import com.duben.miniplaylet.utils.ForegroundOrBackground
import com.duben.miniplaylet.utils.LogUtil
import com.kwad.sdk.api.*
import com.kwad.sdk.api.KsNativeAd.VideoPlayListener
import com.kwad.sdk.api.model.*
import java.lang.ref.WeakReference
open class KsExpress2Manager {
companion object {
private val TAG = KsExpress2Manager::class.java.simpleName
val instance: KsExpress2Manager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
KsExpress2Manager()
}
}
private var posIdEditTextNum = 0L
private var mWeakActivity: WeakReference<Activity>? = null
fun load(expressAdCallback: ExpressAdCallback) {
posIdEditTextNum = 0L
mWeakActivity = WeakReference(ForegroundOrBackground.getTopActivity())
val ksScene = KsScene.Builder(BuildConfig.KS_EXPRESS_2_CODE)
.setBackUrl("ksad://returnback")
.adNum(1) // 支持返回多条广告,默认1条,最多5条,参数范围1-5
.setNativeAdExtraData(
NativeAdExtraData()
.setShowLiveStatus(1)
.setShowLiveStyle(1)
)
.build()
KsAdSDK.getLoadManager().loadNativeAd(ksScene, object : KsLoadManager.NativeAdListener {
override fun onError(p0: Int, p1: String?) {
LogUtil.e(TAG, "ks首页信息流 二次加载 --> load native ad error : $p0, $p1")
}
override fun onNativeAdLoad(p0: MutableList<KsNativeAd>?) {
LogUtil.d(TAG, "ks首页信息流 二次加载 --> onNativeAdLoad")
p0?.let {
for (ksNativeAd in it) {
LogUtil.d(TAG, "adDescription -> " + ksNativeAd.adDescription)
LogUtil.d(TAG, "productName -> " + ksNativeAd.productName)
LogUtil.d(TAG, "appName -> " + ksNativeAd.appName)
LogUtil.d(TAG, "introductionInfo -> " + ksNativeAd.introductionInfo)
LogUtil.d(TAG, "appPackageName -> " + ksNativeAd.appPackageName)
LogUtil.d(TAG, "ecpm -> " + ksNativeAd.ecpm)
showAd(ksNativeAd, expressAdCallback)
}
}
}
})
}
/**
* 加载自渲染View
*/
private fun showAd(ksNativeAd: KsNativeAd, expressAdCallback: ExpressAdCallback) {
val mNativeAdContainer = FrameLayout(MintsApplication.getContext())
mNativeAdContainer.removeAllViews()
val adView: View? = when (ksNativeAd.materialType) {
MaterialType.VIDEO, MaterialType.ORIGIN_LIVE -> // 视频素材,渲染自定义的视频广告
getVideoItemView(mNativeAdContainer, ksNativeAd)
MaterialType.SINGLE_IMG -> // 单图素材,渲染自定义的单图广告
getSingleImageItemView(mNativeAdContainer, ksNativeAd)
MaterialType.GROUP_IMG -> // 组图素材,渲染自定义的组图广告
getGroupImageItemView(mNativeAdContainer, ksNativeAd)
MaterialType.UNKNOWN -> getNormalItemView(mNativeAdContainer)
else -> getNormalItemView(mNativeAdContainer)
}
if (adView != null && adView.parent == null) {
mNativeAdContainer.addView(adView)
expressAdCallback.renderSuccess(mNativeAdContainer)
}
}
/**
* 使用SDK渲染的播放控件, 直播 or 普通视频
*/
private fun getVideoItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_video, parent, false)
val videoViewHolder = AdVideoViewHolder(convertView)
// 设置广告数据
bindCommonData(convertView as ViewGroup, videoViewHolder as AdBaseViewHolder, ksNativeAd)
ksNativeAd.setVideoPlayListener(object : VideoPlayListener {
override fun onVideoPlayReady() {
LogUtil.d(TAG, "onVideoPlayReady")
}
override fun onVideoPlayStart() {
LogUtil.d(TAG, "onVideoPlayStart")
}
override fun onVideoPlayComplete() {
LogUtil.d(TAG, "onVideoPlayComplete")
}
override fun onVideoPlayError(what: Int, extra: Int) {
LogUtil.e(TAG, "onVideoPlayError")
}
override fun onVideoPlayPause() {
LogUtil.d(TAG, "onVideoPlayPause")
}
override fun onVideoPlayResume() {
LogUtil.d(TAG, "onVideoPlayResume")
}
})
// SDK默认渲染的视频view
val videoPlayConfig = KsAdVideoPlayConfig.Builder()
.dataFlowAutoStart(true) // 流量下自动播放
.videoAutoPlayType(
KsAdVideoPlayConfig.VideoAutoPlayType.NO_AUTO_PLAY
) // 设置在有wifi
// 时视频自动播放,当与dataFlowAutoStart()同时设置时,以最后一个传入的值为准
.build()
val videoView = ksNativeAd.getVideoView(mWeakActivity?.get(), videoPlayConfig)
if (videoView != null && videoView.parent == null) {
videoViewHolder.mAdVideoContainer.removeAllViews()
videoViewHolder.mAdVideoContainer.addView(videoView)
}
return convertView
}
/**
* 使用媒体自己渲染的播放控件
*/
protected fun getVideoItemView2(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_video, parent, false)
val viewHolder = AdVideoViewHolder(convertView)
// 设置广告数据
bindCommonData(convertView as ViewGroup, viewHolder, ksNativeAd)
/** 媒体也可以自渲染视频view start */
// 获取视频地址
val videoUrl = ksNativeAd.videoUrl
// 获取视频时长
val videoDuration = ksNativeAd.videoDuration
// 获取视频封面图片
val ksImage = ksNativeAd.videoCoverImage
// 特别注意,视频播放需要客户自渲染,所以需要客户在合适时机掉如下方法进行打点,用于统计视频观看时长
// 1.请在视频播放开始时调用此方法(每次从0秒开始播放,暂停恢复除外)
ksNativeAd.reportAdVideoPlayStart()
// // 2.请在视频播放结束时调用此方法(每次播放到最后1s,暂停恢复除外)
ksNativeAd.reportAdVideoPlayEnd()
/** 自渲染视频view end */
return convertView
}
protected fun getSingleImageItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_single_image, parent, false)
val viewHolder = AdSingleImageViewHolder(convertView)
bindCommonData(convertView as ViewGroup, viewHolder as AdBaseViewHolder, ksNativeAd)
// 获取图片资源
if (ksNativeAd.imageList != null && !ksNativeAd.imageList!!.isEmpty()) {
val image = ksNativeAd.imageList!![0]
if (image != null && image.isValid) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImage)
}
}
return convertView
}
protected fun getGroupImageItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_group_image, parent, false)
val viewHolder = AdGroupImageViewHolder(convertView)
bindCommonData(convertView as ViewGroup, viewHolder as AdBaseViewHolder, ksNativeAd)
// 获取图片资源
val ksImageList = ksNativeAd.imageList
if (ksImageList != null && !ksImageList.isEmpty()) {
for (i in ksImageList.indices) {
val image = ksNativeAd.imageList!![i]
if (image != null && image.isValid) {
if (i == 0) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageLeft)
} else if (i == 1) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageMid)
} else if (i == 2) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageRight)
}
}
}
}
return convertView
}
@SuppressLint("DefaultLocale")
protected fun getNormalItemView(parent: ViewGroup?): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_normal, parent, false)
val normalViewHolder = NormalViewHolder(convertView)
normalViewHolder.textView.text = "没有广告"
return convertView
}
private fun bindCommonData(
convertView: ViewGroup, adBaseViewHolder: AdBaseViewHolder,
ad: KsNativeAd
) {
// 点击转换view的集合,传入的view点击时会触发转换操作:app下载, 打开h5页面
val clickViewMap: MutableMap<View, Int> = HashMap()
clickViewMap[adBaseViewHolder.mAdContainer] = KsNativeConvertType.CONVERT
clickViewMap[adBaseViewHolder.mAdConvertBtn] = KsNativeConvertType.CONVERT
clickViewMap[adBaseViewHolder.mAdIcon] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdName] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdDes] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdDesc] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
if (adBaseViewHolder is AdSingleImageViewHolder) {
clickViewMap[(adBaseViewHolder as AdSingleImageViewHolder).mAdImage] =
KsNativeConvertType.CONVERT
}
// 如果是自定义弹窗,请使用下面的配置
// 注册View的点击,点击后触发转化
ad.registerViewForInteraction(mWeakActivity?.get(), convertView, clickViewMap,
object : KsNativeAd.AdInteractionListener {
override fun onAdClicked(view: View, ad: KsNativeAd) {
if (ad != null) {
LogUtil.d(TAG, "onAdClicked")
}
}
override fun onAdShow(ad: KsNativeAd) {
if (ad != null) {
LogUtil.d(TAG, "onAdShow")
}
}
/*
* @return 返回为true, 则只会给媒体弹出回调,SDK的默认弹窗逻辑不会执行
* @return 返回为true 返回为 false, 则使用SDK默认的合规弹窗。
* 弹出弹窗dialog后, 用户确认下载,则媒体需要回调 OnClickListener.onClick(dialog, DialogInterface
* .BUTTON_POSITIVE)
* 弹出弹窗dialog后, 用户点击取消,则媒体需要回调 OnClickListener.onClick(dialog, DialogInterface
* .BUTTON_NEGATIVE)
* */
override fun handleDownloadDialog(clickListener: DialogInterface.OnClickListener): Boolean {
LogUtil.d(TAG, "handleDownloadDialog")
return false
}
override fun onDownloadTipsDialogShow() {
LogUtil.d(TAG, "onDownloadTipsDialogShow")
}
override fun onDownloadTipsDialogDismiss() {
LogUtil.d(TAG, "onDownloadTipsDialogDismiss")
}
})
// 其他数据
Log.d("AppInfo", "应用名字 = " + ad.appName)
Log.d("AppInfo", "应用包名 = " + ad.appPackageName)
Log.d("AppInfo", "应用版本 = " + ad.appVersion)
Log.d("AppInfo", "开发者 = " + ad.corporationName)
Log.d("AppInfo", "包大小 = " + ad.appPackageSize)
Log.d("AppInfo", "隐私条款链接 = " + ad.appPrivacyUrl)
Log.d("AppInfo", "权限信息 = " + ad.permissionInfo)
Log.d("AppInfo", "权限信息链接 = " + ad.permissionInfoUrl)
Log.d("AppInfo", "功能介绍 = " + ad.introductionInfo)
Log.d("AppInfo", "功能介绍链接 = " + ad.introductionInfoUrl)
// 获取app的评分,取值范围0~5.0
Log.d("AppInfo", "应用评分 = " + ad.appScore)
// 获取app下载次数文案,例如:800W此下载,自行渲染。
Log.d("AppInfo", "app下载次数文案 = " + ad.appDownloadCountDes)
// 广告描述
adBaseViewHolder.mAdDes.text = ad.adDescription
val adIconUrl = ad.appIconUrl
// 广告icon
if (!TextUtils.isEmpty(adIconUrl)) {
Glide.with(MintsApplication.getContext()).load(adIconUrl).into(adBaseViewHolder.mAdIcon)
adBaseViewHolder.mAdIcon.visibility = View.VISIBLE
} else {
adBaseViewHolder.mAdIcon.visibility = View.GONE
}
// 广告转化文案
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
// 广告名称
if (ad.interactionType == InteractionType.DOWNLOAD) {
adBaseViewHolder.mAdName.text = ad.appName
// 下载类型的可以设置下载监听
bindDownloadListener(adBaseViewHolder, ad)
} else {
adBaseViewHolder.mAdName.text = ad.productName
}
// 广告描述
adBaseViewHolder.mAdDesc.text = ad.adDescription
// 不喜欢
adBaseViewHolder.mDislikeBtn.setOnClickListener {
}
// 广告来源
val adSource = ad.adSource
val grayMode = true // 开发者可根据实际需要调整
if (TextUtils.isEmpty(adSource)) {
adBaseViewHolder.mAdSourceDesc.visibility = View.GONE
adBaseViewHolder.mAdSourceDesc.text = ""
adBaseViewHolder.mAdLogoIcon.visibility = View.GONE
} else {
Glide.with(MintsApplication.getContext())
.load(ad.getAdSourceLogoUrl(if (grayMode) AdSourceLogoType.GREY else AdSourceLogoType.NORMAL))
.into(adBaseViewHolder.mAdLogoIcon)
adBaseViewHolder.mAdSourceDesc.setTextColor(if (grayMode) -0x636364 else -0x66000001)
adBaseViewHolder.mAdSourceDesc.text = adSource
}
}
private val mTextWatcher: TextWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
posIdEditTextNum = 0
val tempPosIdEditTextStr = s.toString()
if (!TextUtils.isEmpty(tempPosIdEditTextStr)) {
try {
posIdEditTextNum = tempPosIdEditTextStr.toLong()
} catch (e: Exception) {
}
}
}
}
private fun bindDownloadListener(adBaseViewHolder: AdBaseViewHolder, ad: KsNativeAd) {
val ksAppDownloadListener: KsApkDownloadListener = object : KsApkDownloadListener {
override fun onIdle() {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
}
override fun onDownloadStarted() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "开始下载"
}
}
override fun onProgressUpdate(progress: Int) {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = String.format("%s/100", progress)
}
}
override fun onPaused(progress: Int) {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "恢复下载"
}
}
override fun onDownloadFinished() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "立即安装"
}
}
override fun onDownloadFailed() {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
}
override fun onInstalled() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "立即打开"
}
}
}
// 注册下载监听器
ad.setDownloadListener(ksAppDownloadListener)
}
private class NormalViewHolder internal constructor(convertView: View) {
var textView: TextView
init {
textView = convertView.findViewById(R.id.tv)
}
}
private class AdSingleImageViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdImage: ImageView
init {
mAdImage = convertView.findViewById(R.id.ad_image)
}
}
private class AdGroupImageViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdImageLeft: ImageView
var mAdImageMid: ImageView
var mAdImageRight: ImageView
init {
mAdImageLeft = convertView.findViewById(R.id.ad_image_left)
mAdImageMid = convertView.findViewById(R.id.ad_image_mid)
mAdImageRight = convertView.findViewById(R.id.ad_image_right)
}
}
private class AdVideoViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdVideoContainer: FrameLayout
init {
mAdVideoContainer = convertView.findViewById(R.id.video_container)
}
}
private open class AdBaseViewHolder internal constructor(convertView: View) {
var mAdDes: TextView
var mAdIcon: ImageView
var mAdName: TextView
var mAdDesc: TextView
var mAdConvertBtn: TextView
var mDislikeBtn: ImageView
var mAdLogoIcon: ImageView
var mAdSourceDesc: TextView
var mAdContainer: ViewGroup
init {
mAdDes = convertView.findViewById(R.id.ad_desc)
mAdIcon = convertView.findViewById(R.id.app_icon)
mAdName = convertView.findViewById(R.id.app_title)
mAdDesc = convertView.findViewById(R.id.app_desc)
mAdConvertBtn = convertView.findViewById(R.id.app_download_btn)
mDislikeBtn = convertView.findViewById(R.id.ad_dislike)
mAdLogoIcon = convertView.findViewById(R.id.ksad_logo_icon)
mAdSourceDesc = convertView.findViewById(R.id.ksad_logo_text)
mAdContainer = convertView.findViewById(R.id.ad_container)
}
}
}
\ No newline at end of file
package com.duben.miniplaylet.ad.ks
import android.annotation.SuppressLint
import android.app.Activity
import android.content.DialogInterface
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.duben.miniplaylet.BuildConfig
import com.duben.miniplaylet.MintsApplication
import com.duben.miniplaylet.R
import com.duben.miniplaylet.ad.express.ExpressAdCallback
import com.duben.miniplaylet.utils.ForegroundOrBackground
import com.duben.miniplaylet.utils.LogUtil
import com.kwad.sdk.api.*
import com.kwad.sdk.api.KsNativeAd.VideoPlayListener
import com.kwad.sdk.api.model.*
import java.lang.ref.WeakReference
open class KsExpressManager {
companion object {
private val TAG = KsExpressManager::class.java.simpleName
val instance: KsExpressManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
KsExpressManager()
}
}
private var posIdEditTextNum = 0L
private var mWeakActivity: WeakReference<Activity>? = null
fun load(expressAdCallback: ExpressAdCallback) {
posIdEditTextNum = 0L
mWeakActivity = WeakReference(ForegroundOrBackground.getTopActivity())
val ksScene = KsScene.Builder(BuildConfig.KS_EXPRESS_CODE)
.setBackUrl("ksad://returnback")
.adNum(1) // 支持返回多条广告,默认1条,最多5条,参数范围1-5
.setNativeAdExtraData(
NativeAdExtraData()
.setShowLiveStatus(1)
.setShowLiveStyle(1)
)
.build()
KsAdSDK.getLoadManager().loadNativeAd(ksScene, object : KsLoadManager.NativeAdListener {
override fun onError(p0: Int, p1: String?) {
LogUtil.e(TAG, "ks首页信息流-->load native ad error : $p0, $p1")
KsExpress2Manager.instance.load(expressAdCallback)
}
override fun onNativeAdLoad(p0: MutableList<KsNativeAd>?) {
LogUtil.d(TAG, "ks首页信息流--> onNativeAdLoad")
p0?.let {
for (ksNativeAd in it) {
LogUtil.d(TAG, "adDescription -> " + ksNativeAd.adDescription)
LogUtil.d(TAG, "productName -> " + ksNativeAd.productName)
LogUtil.d(TAG, "appName -> " + ksNativeAd.appName)
LogUtil.d(TAG, "introductionInfo -> " + ksNativeAd.introductionInfo)
LogUtil.d(TAG, "appPackageName -> " + ksNativeAd.appPackageName)
LogUtil.d(TAG, "ecpm -> " + ksNativeAd.ecpm)
showAd(ksNativeAd, expressAdCallback)
}
}
}
})
}
/**
* 加载自渲染View
*/
private fun showAd(ksNativeAd: KsNativeAd, expressAdCallback: ExpressAdCallback) {
val mNativeAdContainer = FrameLayout(MintsApplication.getContext())
mNativeAdContainer.removeAllViews()
val adView: View? = when (ksNativeAd.materialType) {
MaterialType.VIDEO, MaterialType.ORIGIN_LIVE -> // 视频素材,渲染自定义的视频广告
getVideoItemView(mNativeAdContainer, ksNativeAd)
MaterialType.SINGLE_IMG -> // 单图素材,渲染自定义的单图广告
getSingleImageItemView(mNativeAdContainer, ksNativeAd)
MaterialType.GROUP_IMG -> // 组图素材,渲染自定义的组图广告
getGroupImageItemView(mNativeAdContainer, ksNativeAd)
MaterialType.UNKNOWN -> getNormalItemView(mNativeAdContainer)
else -> getNormalItemView(mNativeAdContainer)
}
if (adView != null && adView.parent == null) {
mNativeAdContainer.addView(adView)
expressAdCallback.renderSuccess(mNativeAdContainer)
}
}
/**
* 使用SDK渲染的播放控件, 直播 or 普通视频
*/
private fun getVideoItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_video, parent, false)
val videoViewHolder = AdVideoViewHolder(convertView)
// 设置广告数据
bindCommonData(convertView as ViewGroup, videoViewHolder as AdBaseViewHolder, ksNativeAd)
ksNativeAd.setVideoPlayListener(object : VideoPlayListener {
override fun onVideoPlayReady() {
LogUtil.d(TAG, "onVideoPlayReady")
}
override fun onVideoPlayStart() {
LogUtil.d(TAG, "onVideoPlayStart")
}
override fun onVideoPlayComplete() {
LogUtil.d(TAG, "onVideoPlayComplete")
}
override fun onVideoPlayError(what: Int, extra: Int) {
LogUtil.e(TAG, "onVideoPlayError")
}
override fun onVideoPlayPause() {
LogUtil.d(TAG, "onVideoPlayPause")
}
override fun onVideoPlayResume() {
LogUtil.d(TAG, "onVideoPlayResume")
}
})
// SDK默认渲染的视频view
val videoPlayConfig = KsAdVideoPlayConfig.Builder()
.dataFlowAutoStart(true) // 流量下自动播放
.videoAutoPlayType(
KsAdVideoPlayConfig.VideoAutoPlayType.NO_AUTO_PLAY
) // 设置在有wifi
// 时视频自动播放,当与dataFlowAutoStart()同时设置时,以最后一个传入的值为准
.build()
val videoView = ksNativeAd.getVideoView(mWeakActivity?.get(), videoPlayConfig)
if (videoView != null && videoView.parent == null) {
videoViewHolder.mAdVideoContainer.removeAllViews()
videoViewHolder.mAdVideoContainer.addView(videoView)
}
return convertView
}
/**
* 使用媒体自己渲染的播放控件
*/
protected fun getVideoItemView2(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_video, parent, false)
val viewHolder = AdVideoViewHolder(convertView)
// 设置广告数据
bindCommonData(convertView as ViewGroup, viewHolder, ksNativeAd)
/** 媒体也可以自渲染视频view start */
// 获取视频地址
val videoUrl = ksNativeAd.videoUrl
// 获取视频时长
val videoDuration = ksNativeAd.videoDuration
// 获取视频封面图片
val ksImage = ksNativeAd.videoCoverImage
// 特别注意,视频播放需要客户自渲染,所以需要客户在合适时机掉如下方法进行打点,用于统计视频观看时长
// 1.请在视频播放开始时调用此方法(每次从0秒开始播放,暂停恢复除外)
ksNativeAd.reportAdVideoPlayStart()
// // 2.请在视频播放结束时调用此方法(每次播放到最后1s,暂停恢复除外)
ksNativeAd.reportAdVideoPlayEnd()
/** 自渲染视频view end */
return convertView
}
protected fun getSingleImageItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_single_image, parent, false)
val viewHolder = AdSingleImageViewHolder(convertView)
bindCommonData(convertView as ViewGroup, viewHolder as AdBaseViewHolder, ksNativeAd)
// 获取图片资源
if (ksNativeAd.imageList != null && !ksNativeAd.imageList!!.isEmpty()) {
val image = ksNativeAd.imageList!![0]
if (image != null && image.isValid) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImage)
}
}
return convertView
}
protected fun getGroupImageItemView(parent: ViewGroup?, ksNativeAd: KsNativeAd): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_group_image, parent, false)
val viewHolder = AdGroupImageViewHolder(convertView)
bindCommonData(convertView as ViewGroup, viewHolder as AdBaseViewHolder, ksNativeAd)
// 获取图片资源
val ksImageList = ksNativeAd.imageList
if (ksImageList != null && !ksImageList.isEmpty()) {
for (i in ksImageList.indices) {
val image = ksNativeAd.imageList!![i]
if (image != null && image.isValid) {
if (i == 0) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageLeft)
} else if (i == 1) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageMid)
} else if (i == 2) {
Glide.with(MintsApplication.getContext()).load(image.imageUrl)
.into(viewHolder.mAdImageRight)
}
}
}
}
return convertView
}
@SuppressLint("DefaultLocale")
protected fun getNormalItemView(parent: ViewGroup?): View? {
val convertView: View =
LayoutInflater.from(mWeakActivity?.get())
.inflate(R.layout.native_item_normal, parent, false)
val normalViewHolder = NormalViewHolder(convertView)
normalViewHolder.textView.text = "没有广告"
return convertView
}
private fun bindCommonData(
convertView: ViewGroup, adBaseViewHolder: AdBaseViewHolder,
ad: KsNativeAd
) {
// 点击转换view的集合,传入的view点击时会触发转换操作:app下载, 打开h5页面
val clickViewMap: MutableMap<View, Int> = HashMap()
clickViewMap[adBaseViewHolder.mAdContainer] = KsNativeConvertType.CONVERT
clickViewMap[adBaseViewHolder.mAdConvertBtn] = KsNativeConvertType.CONVERT
clickViewMap[adBaseViewHolder.mAdIcon] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdName] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdDes] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
clickViewMap[adBaseViewHolder.mAdDesc] = KsNativeConvertType.SHOW_DOWNLOAD_TIPS_DIALOG
if (adBaseViewHolder is AdSingleImageViewHolder) {
clickViewMap[(adBaseViewHolder as AdSingleImageViewHolder).mAdImage] =
KsNativeConvertType.CONVERT
}
// 如果是自定义弹窗,请使用下面的配置
// 注册View的点击,点击后触发转化
ad.registerViewForInteraction(mWeakActivity?.get(), convertView, clickViewMap,
object : KsNativeAd.AdInteractionListener {
override fun onAdClicked(view: View, ad: KsNativeAd) {
if (ad != null) {
LogUtil.d(TAG, "onAdClicked")
}
}
override fun onAdShow(ad: KsNativeAd) {
if (ad != null) {
LogUtil.d(TAG, "onAdShow")
}
}
/*
* @return 返回为true, 则只会给媒体弹出回调,SDK的默认弹窗逻辑不会执行
* @return 返回为true 返回为 false, 则使用SDK默认的合规弹窗。
* 弹出弹窗dialog后, 用户确认下载,则媒体需要回调 OnClickListener.onClick(dialog, DialogInterface
* .BUTTON_POSITIVE)
* 弹出弹窗dialog后, 用户点击取消,则媒体需要回调 OnClickListener.onClick(dialog, DialogInterface
* .BUTTON_NEGATIVE)
* */
override fun handleDownloadDialog(clickListener: DialogInterface.OnClickListener): Boolean {
LogUtil.d(TAG, "handleDownloadDialog")
return false
}
override fun onDownloadTipsDialogShow() {
LogUtil.d(TAG, "onDownloadTipsDialogShow")
}
override fun onDownloadTipsDialogDismiss() {
LogUtil.d(TAG, "onDownloadTipsDialogDismiss")
}
})
// 其他数据
Log.d("AppInfo", "应用名字 = " + ad.appName)
Log.d("AppInfo", "应用包名 = " + ad.appPackageName)
Log.d("AppInfo", "应用版本 = " + ad.appVersion)
Log.d("AppInfo", "开发者 = " + ad.corporationName)
Log.d("AppInfo", "包大小 = " + ad.appPackageSize)
Log.d("AppInfo", "隐私条款链接 = " + ad.appPrivacyUrl)
Log.d("AppInfo", "权限信息 = " + ad.permissionInfo)
Log.d("AppInfo", "权限信息链接 = " + ad.permissionInfoUrl)
Log.d("AppInfo", "功能介绍 = " + ad.introductionInfo)
Log.d("AppInfo", "功能介绍链接 = " + ad.introductionInfoUrl)
// 获取app的评分,取值范围0~5.0
Log.d("AppInfo", "应用评分 = " + ad.appScore)
// 获取app下载次数文案,例如:800W此下载,自行渲染。
Log.d("AppInfo", "app下载次数文案 = " + ad.appDownloadCountDes)
// 广告描述
adBaseViewHolder.mAdDes.text = ad.adDescription
val adIconUrl = ad.appIconUrl
// 广告icon
if (!TextUtils.isEmpty(adIconUrl)) {
Glide.with(MintsApplication.getContext()).load(adIconUrl).into(adBaseViewHolder.mAdIcon)
adBaseViewHolder.mAdIcon.visibility = View.VISIBLE
} else {
adBaseViewHolder.mAdIcon.visibility = View.GONE
}
// 广告转化文案
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
// 广告名称
if (ad.interactionType == InteractionType.DOWNLOAD) {
adBaseViewHolder.mAdName.text = ad.appName
// 下载类型的可以设置下载监听
bindDownloadListener(adBaseViewHolder, ad)
} else {
adBaseViewHolder.mAdName.text = ad.productName
}
// 广告描述
adBaseViewHolder.mAdDesc.text = ad.adDescription
// 不喜欢
adBaseViewHolder.mDislikeBtn.setOnClickListener {
}
// 广告来源
val adSource = ad.adSource
val grayMode = true // 开发者可根据实际需要调整
if (TextUtils.isEmpty(adSource)) {
adBaseViewHolder.mAdSourceDesc.visibility = View.GONE
adBaseViewHolder.mAdSourceDesc.text = ""
adBaseViewHolder.mAdLogoIcon.visibility = View.GONE
} else {
Glide.with(MintsApplication.getContext())
.load(ad.getAdSourceLogoUrl(if (grayMode) AdSourceLogoType.GREY else AdSourceLogoType.NORMAL))
.into(adBaseViewHolder.mAdLogoIcon)
adBaseViewHolder.mAdSourceDesc.setTextColor(if (grayMode) -0x636364 else -0x66000001)
adBaseViewHolder.mAdSourceDesc.text = adSource
}
}
private val mTextWatcher: TextWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
posIdEditTextNum = 0
val tempPosIdEditTextStr = s.toString()
if (!TextUtils.isEmpty(tempPosIdEditTextStr)) {
try {
posIdEditTextNum = tempPosIdEditTextStr.toLong()
} catch (e: Exception) {
}
}
}
}
private fun bindDownloadListener(adBaseViewHolder: AdBaseViewHolder, ad: KsNativeAd) {
val ksAppDownloadListener: KsApkDownloadListener = object : KsApkDownloadListener {
override fun onIdle() {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
}
override fun onDownloadStarted() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "开始下载"
}
}
override fun onProgressUpdate(progress: Int) {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = String.format("%s/100", progress)
}
}
override fun onPaused(progress: Int) {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "恢复下载"
}
}
override fun onDownloadFinished() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "立即安装"
}
}
override fun onDownloadFailed() {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
}
override fun onInstalled() {
if (ad.materialType == MaterialType.ORIGIN_LIVE) {
adBaseViewHolder.mAdConvertBtn.text = ad.actionDescription
} else {
adBaseViewHolder.mAdConvertBtn.text = "立即打开"
}
}
}
// 注册下载监听器
ad.setDownloadListener(ksAppDownloadListener)
}
private class NormalViewHolder internal constructor(convertView: View) {
var textView: TextView
init {
textView = convertView.findViewById(R.id.tv)
}
}
private class AdSingleImageViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdImage: ImageView
init {
mAdImage = convertView.findViewById(R.id.ad_image)
}
}
private class AdGroupImageViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdImageLeft: ImageView
var mAdImageMid: ImageView
var mAdImageRight: ImageView
init {
mAdImageLeft = convertView.findViewById(R.id.ad_image_left)
mAdImageMid = convertView.findViewById(R.id.ad_image_mid)
mAdImageRight = convertView.findViewById(R.id.ad_image_right)
}
}
private class AdVideoViewHolder internal constructor(convertView: View) :
AdBaseViewHolder(convertView) {
var mAdVideoContainer: FrameLayout
init {
mAdVideoContainer = convertView.findViewById(R.id.video_container)
}
}
private open class AdBaseViewHolder internal constructor(convertView: View) {
var mAdDes: TextView
var mAdIcon: ImageView
var mAdName: TextView
var mAdDesc: TextView
var mAdConvertBtn: TextView
var mDislikeBtn: ImageView
var mAdLogoIcon: ImageView
var mAdSourceDesc: TextView
var mAdContainer: ViewGroup
init {
mAdDes = convertView.findViewById(R.id.ad_desc)
mAdIcon = convertView.findViewById(R.id.app_icon)
mAdName = convertView.findViewById(R.id.app_title)
mAdDesc = convertView.findViewById(R.id.app_desc)
mAdConvertBtn = convertView.findViewById(R.id.app_download_btn)
mDislikeBtn = convertView.findViewById(R.id.ad_dislike)
mAdLogoIcon = convertView.findViewById(R.id.ksad_logo_icon)
mAdSourceDesc = convertView.findViewById(R.id.ksad_logo_text)
mAdContainer = convertView.findViewById(R.id.ad_container)
}
}
}
\ No newline at end of file
...@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager ...@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.duben.miniplaylet.R import com.duben.miniplaylet.R
import com.duben.miniplaylet.ad.express.ExpressAdCallback import com.duben.miniplaylet.ad.express.ExpressAdCallback
import com.duben.miniplaylet.ad.express.MainExpressManager import com.duben.miniplaylet.ad.express.MainExpressManager
import com.duben.miniplaylet.ad.ks.KsExpressManager
import com.duben.miniplaylet.common.Constant import com.duben.miniplaylet.common.Constant
import com.duben.miniplaylet.manager.LocalVedioManager import com.duben.miniplaylet.manager.LocalVedioManager
import com.duben.miniplaylet.mvp.model.* import com.duben.miniplaylet.mvp.model.*
...@@ -150,7 +151,7 @@ class MovieFragment : LazyLoadBaseFragment(), PicContentView, OnLoadMoreListener ...@@ -150,7 +151,7 @@ class MovieFragment : LazyLoadBaseFragment(), PicContentView, OnLoadMoreListener
} }
private fun loadAd() { private fun loadAd() {
MainExpressManager.instance.loadAd(object : ExpressAdCallback { KsExpressManager.instance.load(object : ExpressAdCallback {
override fun loadSuccess(adView: FrameLayout?) { override fun loadSuccess(adView: FrameLayout?) {
} }
...@@ -162,7 +163,22 @@ class MovieFragment : LazyLoadBaseFragment(), PicContentView, OnLoadMoreListener ...@@ -162,7 +163,22 @@ class MovieFragment : LazyLoadBaseFragment(), PicContentView, OnLoadMoreListener
override fun loadFail() { override fun loadFail() {
} }
}) })
// MainExpressManager.instance.loadAd(object : ExpressAdCallback {
// override fun loadSuccess(adView: FrameLayout?) {
//
// }
//
// override fun renderSuccess(adView: FrameLayout?): Boolean {
// adView?.let { addAdView(it) }
// return false
// }
//
// override fun loadFail() {
// }
// })
} }
private fun addAdView(adView: FrameLayout) { private fun addAdView(adView: FrameLayout) {
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#168FFF" />
<corners android:radius="4dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="36dp"
android:gravity="center_vertical"
android:orientation="horizontal"
tool:ignore="SpUsage,ContentDescription">
<ImageView
android:id="@+id/app_icon"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="@drawable/test_app_default_icon" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_marginRight="16dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
tool:ignore="RtlHardcoded">
<TextView
android:id="@+id/app_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:textColor="#222222"
android:textSize="14dp"
tool:text="快手APP" />
<TextView
android:id="@+id/app_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:textColor="#9C9C9C"
android:textSize="11dp"
tool:text="记录美好生活" />
</LinearLayout>
<TextView
android:id="@+id/app_download_btn"
android:layout_width="64dp"
android:layout_height="24dp"
android:background="@drawable/native_item_btn_bg"
android:gravity="center"
android:textColor="#168FFF"
android:textSize="11dp"
tool:text="立即下载" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/ad_container"
tools:ignore="ContentDescription,SpUsage,RtlHardcoded">
<TextView
android:id="@+id/ad_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#020202"
android:textSize="18dp"
tools:text="快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp">
<ImageView
android:id="@+id/ad_image_left"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/ad_image_mid"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_weight="1"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/ad_image_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:scaleType="centerCrop" />
</LinearLayout>
<include
android:id="@+id/ad_actionBar_container"
layout="@layout/native_item_app_download"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginTop="4dp"
tools:ignore="ContentDescription,RtlHardcoded">
<ImageView
android:id="@+id/ksad_logo_icon"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_centerVertical="true"
android:src="@drawable/test_logo_gray"
tools:visibility="visible"
android:layout_marginLeft="3dp"
android:layout_marginRight="2dp" />
<TextView
android:id="@+id/ksad_logo_text"
android:layout_toRightOf="@id/ksad_logo_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:textSize="10sp"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="2dp"
android:paddingRight="3dp"
android:text="广告"
tools:visibility="visible"
android:textColor="#9C9C9C" />
<ImageView
android:id="@+id/ad_dislike"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/test_dislike_gray" />
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:gravity="center"
android:text="普通的view" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/ad_container"
tools:ignore="ContentDescription,SpUsage,RtlHardcoded">
<TextView
android:id="@+id/ad_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#020202"
android:textSize="18dp"
tools:text="快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告" />
<ImageView
android:id="@+id/ad_image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:scaleType="centerCrop" />
<include
android:id="@+id/ad_actionBar_container"
layout="@layout/native_item_app_download"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginTop="4dp"
tools:ignore="ContentDescription,RtlHardcoded">
<ImageView
android:id="@+id/ksad_logo_icon"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_centerVertical="true"
android:src="@drawable/test_logo_gray"
tools:visibility="visible"
android:layout_marginLeft="3dp"
android:layout_marginRight="2dp" />
<TextView
android:id="@+id/ksad_logo_text"
android:layout_toRightOf="@id/ksad_logo_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:textSize="10sp"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="2dp"
android:paddingRight="3dp"
android:text="广告"
tools:visibility="visible"
android:textColor="#9C9C9C" />
<ImageView
android:id="@+id/ad_dislike"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/test_dislike_gray" />
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/ad_container"
tools:ignore="ContentDescription,SpUsage,RtlHardcoded">
<TextView
android:id="@+id/ad_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#020202"
android:textSize="18dp"
tools:text="快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告快手广告" />
<FrameLayout
android:id="@+id/video_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" />
<include
android:id="@+id/ad_actionBar_container"
layout="@layout/native_item_app_download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginTop="4dp"
tools:ignore="ContentDescription,RtlHardcoded">
<ImageView
android:id="@+id/ksad_logo_icon"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_centerVertical="true"
android:src="@drawable/test_logo_gray"
tools:visibility="visible"
android:layout_marginLeft="3dp"
android:layout_marginRight="2dp" />
<TextView
android:id="@+id/ksad_logo_text"
android:layout_toRightOf="@id/ksad_logo_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:textSize="10sp"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="2dp"
android:paddingRight="3dp"
android:text="广告"
tools:visibility="visible"
android:textColor="#9C9C9C" />
<ImageView
android:id="@+id/ad_dislike"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/test_dislike_gray" />
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
...@@ -56,3 +56,6 @@ GROMORE_DRAW_CODE="" ...@@ -56,3 +56,6 @@ GROMORE_DRAW_CODE=""
GROMORE_BANNER_CODE="102465294" GROMORE_BANNER_CODE="102465294"
GROMORE_FULL_CODE="102473745" GROMORE_FULL_CODE="102473745"
GROMORE_HALF_CODE="102473745" GROMORE_HALF_CODE="102473745"
KS_EXPRESS_CODE=13782000142L
KS_EXPRESS_2_CODE=13782000143L
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment