Compare commits
4 Commits
dev
...
feat/GHZSC
| Author | SHA1 | Date | |
|---|---|---|---|
| 63e478d314 | |||
| bf30aef686 | |||
| 3cca6b5cb5 | |||
| 49a49d115c |
@ -71,7 +71,7 @@ android_build:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-7058
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -156,4 +156,4 @@ oss-upload&send-email:
|
||||
- /usr/local/bin/python /ci-android-mail-jira-comment.py
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-7058
|
||||
|
||||
@ -153,7 +153,7 @@ android {
|
||||
zipAlignEnabled false
|
||||
signingConfig signingConfigs.debug
|
||||
|
||||
buildConfigField "String", "EXPOSURE_REPO", "\"test\""
|
||||
buildConfigField "String", "EXPOSURE_REPO", "\"exposure\""
|
||||
buildConfigField "String", "EXPOSURE_VERSION", "\"E4\""
|
||||
|
||||
multiDexKeepProguard file("tinker_multidexkeep.pro")
|
||||
|
||||
@ -16,12 +16,10 @@ import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.FixLinearLayoutManager
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
|
||||
import com.gh.gamecenter.databinding.DialogReserveBinding
|
||||
import com.gh.gamecenter.databinding.DialogReserveItemBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureStateChangeListener
|
||||
import com.gh.gamecenter.feature.exposure.RecyclerViewExposureHelper
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
class DefaultExposureStateChangeListener : IExposureStateChangeListener {
|
||||
|
||||
override fun onExposureStateChange(
|
||||
exposureEvent: ExposureEvent,
|
||||
position: Int,
|
||||
inExposure: Boolean
|
||||
) {
|
||||
val exposureStatus = if (inExposure) "曝光中" else "结束曝光"
|
||||
|
||||
val isCPMExposureEvent = exposureEvent.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM
|
||||
|
||||
Utils.log(
|
||||
RecyclerViewExposureHelper.TAG,
|
||||
"onExposureStateChange: 名称 ${exposureEvent.payload.gameName} 位置 $position, $exposureStatus"
|
||||
)
|
||||
|
||||
// 如果是 CPM 曝光事件,且在曝光中,直接上报 CPM 曝光 (内部有做简单的去重处理,CPM 曝光追求一个及时上报,不用理会曝光时长)
|
||||
if (isCPMExposureEvent && inExposure) {
|
||||
Utils.log(
|
||||
RecyclerViewExposureHelper.TAG,
|
||||
"上报 CPM 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
|
||||
)
|
||||
ExposureManager.logCPM(exposureEvent)
|
||||
}
|
||||
|
||||
if (!inExposure
|
||||
&& System.currentTimeMillis() - exposureEvent.timeInMillisecond > DEFAULT_VALID_EXPOSURE_THRESHOLD
|
||||
) {
|
||||
Utils.log(
|
||||
RecyclerViewExposureHelper.TAG,
|
||||
"上报曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id},是否为 CPM 小游戏 -> ${isCPMExposureEvent}," +
|
||||
"曝光时长为 ${System.currentTimeMillis() - exposureEvent.timeInMillisecond}ms"
|
||||
)
|
||||
|
||||
// 标记当前 ExposureEvent 已经被使用过
|
||||
exposureEvent.markIsUsed()
|
||||
ExposureManager.log(exposureEvent)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// 默认曝光有效时长
|
||||
const val DEFAULT_VALID_EXPOSURE_THRESHOLD = 1000L
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,10 +4,12 @@ import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.loghub.TLogHubHelper
|
||||
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.common.utils.toJson
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.minigame.wechat.WGameSubjectCPMListReportHelper
|
||||
import com.google.gson.ExclusionStrategy
|
||||
import com.google.gson.FieldAttributes
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.lightgame.utils.Utils
|
||||
import com.volcengine.model.tls.LogItem
|
||||
|
||||
@ -29,6 +31,20 @@ object ExposureManager {
|
||||
private val exposureSet by lazy { hashSetOf<ExposureEvent>() }
|
||||
private val exposureCache by lazy { FixedSizeLinkedHashSet<String>(300) }
|
||||
|
||||
private val gson by lazy {
|
||||
GsonBuilder()
|
||||
.addSerializationExclusionStrategy(object: ExclusionStrategy {
|
||||
override fun shouldSkipClass(clazz: Class<*>): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun shouldSkipField(f: FieldAttributes): Boolean {
|
||||
return f.name == "additional"
|
||||
}
|
||||
})
|
||||
.create()
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a single exposure event.
|
||||
*/
|
||||
@ -74,6 +90,15 @@ object ExposureManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a wechat mini game cpm collection of exposure event.
|
||||
*/
|
||||
fun logCPM(event: ExposureEvent) {
|
||||
AppExecutor.logExecutor.execute {
|
||||
WGameSubjectCPMListReportHelper.reportExposure(event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param forcedUpload Ignore all restrictions.
|
||||
*/
|
||||
@ -102,14 +127,14 @@ object ExposureManager {
|
||||
|
||||
private fun buildLog(event: ExposureEvent) = LogItem(System.currentTimeMillis()).apply {
|
||||
addContent("__id", event.id)
|
||||
addContent("payload", event.payload.toJson())
|
||||
addContent("payload", gson.toJson(event.payload))
|
||||
addContent("event", event.event.toString())
|
||||
addContent("source", eliminateMultipleBrackets(event.source.toJson()))
|
||||
addContent("meta", event.meta.toJson())
|
||||
addContent("source", eliminateMultipleBrackets(gson.toJson(event.source)))
|
||||
addContent("meta", gson.toJson(event.meta))
|
||||
addContent("real_millisecond", event.timeInMillisecond.toString())
|
||||
addContent(
|
||||
"e-traces", if (event.eTrace != null) {
|
||||
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
|
||||
eliminateMultipleBrackets(gson.toJson(event.eTrace))
|
||||
} else ""
|
||||
)
|
||||
}
|
||||
|
||||
@ -8,13 +8,13 @@ object ExposureTraceUtils {
|
||||
val traceList = arrayListOf<ExposureEvent>()
|
||||
|
||||
event?.let {
|
||||
//这里使用deepCopy,是为了防止循环引用调用hashCode方法触发StackOverflowError错误
|
||||
val deepCopy = it.deepCopy()
|
||||
if (deepCopy.eTrace == null) {
|
||||
traceList.add(deepCopy)
|
||||
//这里使用 copy,是为了防止循环引用调用hashCode方法触发StackOverflowError错误
|
||||
val exposureCopy = it.shallowCopy()
|
||||
if (exposureCopy.eTrace == null) {
|
||||
traceList.add(exposureCopy)
|
||||
} else {
|
||||
traceList.addAll(deepCopy.eTrace!!)
|
||||
traceList.add(flattenTrace(deepCopy))
|
||||
traceList.addAll(exposureCopy.eTrace!!)
|
||||
traceList.add(flattenTrace(exposureCopy))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.entity.LaunchRedirect
|
||||
import com.gh.gamecenter.common.entity.LaunchRedirectWrapper
|
||||
import com.gh.gamecenter.common.pagelevel.PageLevelManager
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
@ -65,9 +66,11 @@ class LaunchRedirectHandler(priority: Int) : PriorityChainHandler(priority) {
|
||||
override fun onProcess(): Boolean {
|
||||
val currentActivity = CurrentActivityHolder.getCurrentActivity()
|
||||
|
||||
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
|
||||
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity) && launchData?.type != "bottom_tab") {
|
||||
if (getStatus() == STATUS_VALID) {
|
||||
// 当 type 为 "bottom_tab" 时上面 doPreProcess 中已经处理过了,但再选中一次好像也没有什么问题,先不特殊处理这个 case 了
|
||||
// 设置下一个页面为顶级页面
|
||||
PageLevelManager.setNextPageAsSupremePageLevel()
|
||||
|
||||
DirectUtils.directToLinkPage(currentActivity!!, launchData!!, "首次启动跳转", "")
|
||||
// 跳转页面不管回调,延迟 500ms 后执行下一个 handler
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
|
||||
@ -27,6 +27,8 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
var packageName = ""
|
||||
var exposureSourceList: List<ExposureSource>? = null
|
||||
var customPageTrackData: CustomPageTrackData? = null
|
||||
var isAd = false
|
||||
var adGroupId = ""
|
||||
|
||||
val boundedObject = downloadButton.getObject()
|
||||
|
||||
@ -54,6 +56,8 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
packageName = boundedObject.getUniquePackageName() ?: ""
|
||||
exposureSourceList = boundedObject.exposureEvent?.source
|
||||
customPageTrackData = boundedObject.customPageTrackData
|
||||
isAd = boundedObject.adGroupId.isNotEmpty()
|
||||
adGroupId = boundedObject.adGroupId
|
||||
}
|
||||
|
||||
is GameUpdateEntity -> {
|
||||
@ -136,6 +140,8 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
|
||||
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
|
||||
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId,
|
||||
"is_ad", isAd.toString(),
|
||||
"ad_group_id", adGroupId,
|
||||
*customPageKV
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.therouter.router.Route
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.provider.IExposureManagerProvider
|
||||
|
||||
@ -12,4 +9,8 @@ class ExposureManagerProviderImpl: IExposureManagerProvider {
|
||||
override fun logExposure(exposureEvent: ExposureEvent) {
|
||||
ExposureManager.log(exposureEvent)
|
||||
}
|
||||
|
||||
override fun logExposureList(exposureEventList: List<ExposureEvent>) {
|
||||
ExposureManager.log(exposureEventList)
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,19 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.entity.IdfaData
|
||||
import com.gh.gamecenter.common.pagelevel.IPageLevelProvider
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.tracker.IBusiness
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.entity.StartupAdEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
object AdHelper {
|
||||
|
||||
@ -12,6 +23,74 @@ object AdHelper {
|
||||
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
|
||||
const val LOCATION_SIMULATOR_GAME = "simulator_game"
|
||||
|
||||
// 广告标识 https://jira.shanqu.cc/browse/GHZSCY-7041
|
||||
private var idfa = ""
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getIdfa(versionName: String, channel: String) {
|
||||
RetrofitManager.getInstance().newApi.getIdfa(versionName, channel)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<IdfaData>() {
|
||||
override fun onSuccess(data: IdfaData) {
|
||||
idfa = data.AD
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getIdfaString() : String {
|
||||
return idfa
|
||||
}
|
||||
|
||||
fun reportAdRequest(exposureEvent: ExposureEvent) {
|
||||
val payload = exposureEvent.payload
|
||||
NewFlatLogUtils.logAdRequest(
|
||||
pageLevel = payload.pageLevel ?: "",
|
||||
currentPageCode = payload.currentPageCode ?: "",
|
||||
currentPageId = payload.currentPageId ?: "",
|
||||
gameName = payload.gameName ?: "",
|
||||
gameId = payload.gameId ?: "",
|
||||
moduleType = payload.moduleType ?: "",
|
||||
moduleStyle = payload.moduleStyle ?: "",
|
||||
moduleName = payload.moduleName ?: "",
|
||||
moduleId = payload.moduleId ?: "",
|
||||
searchContent = payload.searchContent ?: "",
|
||||
sequence = payload.sequence ?: -1,
|
||||
outerSequence = payload.outerSequence ?: -1,
|
||||
adGroupId = payload.adGroupId ?: "",
|
||||
)
|
||||
}
|
||||
|
||||
fun reportAdRequest(gameEntity: GameEntity) {
|
||||
val currentActivity = CurrentActivityHolder.getCurrentActivity()
|
||||
val currentActivitySimpleName = if (currentActivity != null) currentActivity::class.simpleName else "unknown"
|
||||
val businessId = if (currentActivity is IBusiness) currentActivity.getBusinessId() else null
|
||||
|
||||
var pageLevelString: String? = gameEntity.pageLevelString
|
||||
|
||||
if (TextUtils.isEmpty(pageLevelString)) {
|
||||
val pageLevelProvider = currentActivity as? IPageLevelProvider
|
||||
pageLevelString = pageLevelProvider?.getPageLevel()?.toFormatedString()
|
||||
}
|
||||
|
||||
NewFlatLogUtils.logAdRequest(
|
||||
pageLevel = gameEntity.pageLevelString,
|
||||
currentPageCode = currentActivitySimpleName ?: "",
|
||||
currentPageId = businessId?.first ?: "",
|
||||
gameName = gameEntity.name ?: "",
|
||||
gameId = gameEntity.id,
|
||||
moduleStyle = gameEntity.customPageTrackData?.modulePattern ?: "",
|
||||
moduleType = gameEntity.customPageTrackData?.moduleType ?: "",
|
||||
moduleName = gameEntity.customPageTrackData?.linkContentName ?: "",
|
||||
moduleId = gameEntity.customPageTrackData?.linkContentId ?: "",
|
||||
searchContent = "",
|
||||
sequence = gameEntity.sequence ?: -1,
|
||||
outerSequence = gameEntity.outerSequence ?: -1,
|
||||
adGroupId = gameEntity.adGroupId,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun getStartUp(): StartupAdEntity? {
|
||||
return Config.getNewApiSettingsEntity()?.startup
|
||||
|
||||
@ -821,6 +821,8 @@ object DownloadItemUtils {
|
||||
"last_page_id", getLastPageEntity().pageId,
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId,
|
||||
"source", gameEntity.exposureEvent?.source?.toString() ?: "",
|
||||
"is_ad", if (gameEntity.adGroupId.isEmpty()) "false" else "true",
|
||||
"ad_group_id", gameEntity.adGroupId,
|
||||
*gameEntity.customPageTrackData?.toKV() ?: arrayOf()
|
||||
)
|
||||
allStateClickCallback?.onCallback()
|
||||
|
||||
@ -497,6 +497,7 @@ object DownloadObserver {
|
||||
|
||||
val isPlatformRecommend =
|
||||
java.lang.Boolean.parseBoolean(downloadEntity.getMetaExtra(Constants.IS_PLATFORM_RECOMMEND))
|
||||
val adGroupId = downloadEntity.getMetaExtra(Constants.AD_GROUP_ID)
|
||||
val exposureEvent = ExposureUtils.logADownloadCompleteExposureEvent(
|
||||
GameEntity(
|
||||
_id = downloadEntity.gameId,
|
||||
@ -529,6 +530,8 @@ object DownloadObserver {
|
||||
"game_id", downloadEntity.gameId,
|
||||
"game_type", downloadEntity.categoryChinese,
|
||||
"game_schema_type", if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
"is_ad", if (adGroupId.isEmpty()) "false" else "true",
|
||||
"ad_group_id", adGroupId,
|
||||
*kvs
|
||||
)
|
||||
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
|
||||
@ -572,6 +575,8 @@ object DownloadObserver {
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId,
|
||||
"download_status", downloadEntity.meta[Constants.DOWNLOAD_STATUS_IN_CHINESE] ?: "",
|
||||
"download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
|
||||
"is_ad", if (adGroupId.isEmpty()) "false" else "true",
|
||||
"ad_group_id", adGroupId,
|
||||
*kvs
|
||||
)
|
||||
}
|
||||
|
||||
@ -2779,6 +2779,44 @@ object NewFlatLogUtils {
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告游戏填充
|
||||
* 广告游戏填充到广告位置时,上报该广告游戏插入的位置信息(用于数据回收验证策略的效果,无须曝光,只要请求了广告,就上报)
|
||||
*/
|
||||
fun logAdRequest(
|
||||
pageLevel: String,
|
||||
currentPageCode: String,
|
||||
currentPageId: String,
|
||||
gameName: String,
|
||||
gameId: String,
|
||||
moduleType: String,
|
||||
moduleStyle: String,
|
||||
moduleName: String,
|
||||
moduleId: String,
|
||||
searchContent: String,
|
||||
sequence: Int,
|
||||
outerSequence: Int,
|
||||
adGroupId: String,
|
||||
) {
|
||||
json {
|
||||
KEY_EVENT to "ad_request"
|
||||
"page_level" to pageLevel
|
||||
"current_page_code" to currentPageCode
|
||||
"current_page_id" to currentPageId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_ID to gameId
|
||||
"module_type" to moduleType
|
||||
"module_style" to moduleStyle
|
||||
"module_name" to moduleName
|
||||
"module_id" to moduleId
|
||||
"search_content" to searchContent
|
||||
"sequence" to sequence
|
||||
"outer_sequence" to outerSequence
|
||||
"ad_group_id" to adGroupId
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 自有开屏广告加载
|
||||
fun logSplashAdLoad(id: String) {
|
||||
json {
|
||||
|
||||
@ -80,6 +80,8 @@ object ReservationHelper {
|
||||
"last_page_id", getLastPageEntity().pageId,
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId,
|
||||
"source", game?.exposureEvent?.source?.toString() ?: "",
|
||||
"is_ad", if (game?.adGroupId.isNullOrEmpty() == true) "false" else "true",
|
||||
"ad_group_id", game?.adGroupId ?: "",
|
||||
*game?.customPageTrackData?.toKV() ?: arrayOf()
|
||||
)
|
||||
|
||||
@ -117,6 +119,8 @@ object ReservationHelper {
|
||||
"last_page_id", getLastPageEntity().pageId,
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId,
|
||||
"source", game?.exposureEvent?.source?.toString() ?: "",
|
||||
"is_ad", if (game?.adGroupId.isNullOrEmpty() == true) "false" else "true",
|
||||
"ad_group_id", game?.adGroupId ?: "",
|
||||
*game?.customPageTrackData?.toKV() ?: arrayOf()
|
||||
)
|
||||
ToastUtils.showToast(exception.message ?: "")
|
||||
|
||||
@ -59,6 +59,7 @@ import com.gh.ndownload.NDownloadBridge;
|
||||
import com.gh.ndownload.NDownloadService;
|
||||
import com.gh.vspace.VHelper;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lg.vspace.archive.common.Const;
|
||||
import com.lightgame.download.DataWatcher;
|
||||
import com.lightgame.download.DownloadConfig;
|
||||
import com.lightgame.download.DownloadDao;
|
||||
@ -401,6 +402,9 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
// 将下载事件放入 downloadEntity 中供下载完成时取出使用
|
||||
downloadEntity.setExposureTrace(GsonUtils.toJson(downloadExposureEvent));
|
||||
|
||||
// 记录广告组 id
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_GROUP_ID, gameEntity.getAdGroupId());
|
||||
|
||||
// 保存所有游戏标签
|
||||
List<String> tags = new ArrayList<>();
|
||||
for (TagStyleEntity tag : gameEntity.getTagStyle()) {
|
||||
@ -433,7 +437,9 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
"game_name", gameEntity.getName(),
|
||||
"game_id", gameEntity.getId(),
|
||||
"game_type", gameEntity.getCategoryChinese(),
|
||||
"game_schema_type", gameEntity.getGameBitChinese()
|
||||
"game_schema_type", gameEntity.getGameBitChinese(),
|
||||
"is_ad", TextUtils.isEmpty(gameEntity.getAdGroupId()) ? "false" : "true",
|
||||
"ad_group_id", gameEntity.getAdGroupId(),
|
||||
};
|
||||
List<String> vaList = new ArrayList<>(Arrays.asList(vaKvs));
|
||||
if (customPageTrackData != null) {
|
||||
@ -451,11 +457,12 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
trackDownloadType = "本地下载";
|
||||
}
|
||||
|
||||
|
||||
String[] arrayKv = {
|
||||
"game_id", gameEntity.getId(),
|
||||
"game_name", gameEntity.getName(),
|
||||
"game_type", gameEntity.getCategoryChinese(),
|
||||
"is_ad", TextUtils.isEmpty(gameEntity.getAdGroupId()) ? "false" : "true",
|
||||
"ad_group_id", gameEntity.getAdGroupId(),
|
||||
"game_label", String.join(",", tags),
|
||||
"game_schema_type", gameEntity.getGameBitChinese(),
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
|
||||
|
||||
@ -76,6 +76,8 @@ import com.gh.gamecenter.common.entity.SuggestType;
|
||||
import com.gh.gamecenter.common.eventbus.EBNetworkState;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gamecenter.common.pagelevel.PageLevel;
|
||||
import com.gh.gamecenter.common.pagelevel.PageLevelManager;
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
@ -88,7 +90,6 @@ import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.utils.ClassUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
@ -227,9 +228,6 @@ public class MainActivity extends BaseActivity {
|
||||
},
|
||||
() -> {
|
||||
DirectUtils.directToSuggestion(MainActivity.this, SuggestType.APP, "APP闪退:", false, 100);
|
||||
MtaHelper.onEventWithBasicDeviceInfo(
|
||||
"闪退弹窗",
|
||||
"玩家操作", "点击反馈");
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
@ -237,17 +235,9 @@ public class MainActivity extends BaseActivity {
|
||||
, "暂不", "马上反馈",
|
||||
() -> {
|
||||
DirectUtils.directToSuggestion(MainActivity.this, SuggestType.APP, "APP闪退:", false, 100);
|
||||
MtaHelper.onEventWithBasicDeviceInfo(
|
||||
"闪退弹窗",
|
||||
"玩家操作", "点击反馈");
|
||||
return null;
|
||||
},
|
||||
() -> {
|
||||
MtaHelper.onEventWithBasicDeviceInfo(
|
||||
"闪退弹窗",
|
||||
"玩家操作", "点击关闭");
|
||||
return null;
|
||||
});
|
||||
() -> null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,7 +379,6 @@ public class MainActivity extends BaseActivity {
|
||||
HistoryHelper.deleteAttentionVideoRecord();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,4 +1073,26 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPageLevel(@Nullable Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.getParcelable(PageLevelManager.KEY_PAGE_LEVEL) != null) {
|
||||
mPageLevel = savedInstanceState.getParcelable(PageLevelManager.KEY_PAGE_LEVEL);
|
||||
}
|
||||
}
|
||||
|
||||
if (mPageLevel == null) {
|
||||
mPageLevel = new PageLevel(
|
||||
PageLevel.TYPE_T,
|
||||
-1,
|
||||
-1,
|
||||
new HashMap<>(),
|
||||
-1,
|
||||
null);
|
||||
}
|
||||
|
||||
PageLevelManager.INSTANCE.setCurrentPageLevel(mPageLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -316,6 +316,9 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
|
||||
}
|
||||
}
|
||||
|
||||
override fun initPageLevel(savedInstanceState: Bundle?) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_REGISTRATION_ID = "registration_id"
|
||||
|
||||
@ -453,6 +453,8 @@ class DetailViewHolder(
|
||||
"last_page_id", getLastPageEntity().pageId,
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId,
|
||||
"source", mGameEntity.exposureEvent?.source?.toString() ?: "",
|
||||
"is_ad", if (mGameEntity.adGroupId.isEmpty()) "false" else "true",
|
||||
"ad_group_id", mGameEntity.adGroupId,
|
||||
*mGameEntity.customPageTrackData?.toKV() ?: arrayOf()
|
||||
)
|
||||
CheckLoginUtils.checkLogin(mViewHolder.context, mEntrance) {
|
||||
|
||||
@ -8,14 +8,20 @@ import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.GameImageItemBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
|
||||
/**
|
||||
* 游戏专题-大图-显示/只显示
|
||||
*/
|
||||
class GameImageViewHolder(var binding: GameImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
class GameImageViewHolder(var binding: GameImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root),
|
||||
IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
// 注意:专题详情的大图不能用此方法
|
||||
fun bindImage(entity: GameEntity, applyRoundCorner: Boolean = false) {
|
||||
boundedGameEntity = entity
|
||||
binding.run {
|
||||
gameContainer.goneIf(!(entity.type == "game" && entity.getApk().isNotEmpty()))
|
||||
gameIcon.displayGameIcon(entity)
|
||||
@ -28,11 +34,17 @@ class GameImageViewHolder(var binding: GameImageItemBinding) : BaseRecyclerViewH
|
||||
|
||||
if (applyRoundCorner) {
|
||||
val roundingParams = RoundingParams.fromCornersRadius(
|
||||
binding.root.resources.getDimensionPixelSize(com.gh.gamecenter.common.R.dimen.home_large_image_radius).toFloat()
|
||||
binding.root.resources.getDimensionPixelSize(com.gh.gamecenter.common.R.dimen.home_large_image_radius)
|
||||
.toFloat()
|
||||
)
|
||||
binding.gameImageIcon.hierarchy.roundingParams = roundingParams
|
||||
}
|
||||
|
||||
ImageUtils.displayWithAdaptiveHeight(binding.gameImageIcon, entity.image, width)
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGameEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,25 +13,26 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.common.constant.ItemViewType
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.common.baselist.ListAdapter
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
|
||||
import com.gh.gamecenter.databinding.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SpecialCatalogEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.subject.SubjectActivity.Companion.startSubjectActivity
|
||||
|
||||
class SpecialCatalogAdapter(
|
||||
context: Context,
|
||||
private val mCatalogViewModel: SpecialCatalogViewModel,
|
||||
private val mLastPageDataMap: HashMap<String, String>? = null
|
||||
) : ListAdapter<SpecialCatalogItemData>(context), IExposable {
|
||||
) : ListAdapter<SpecialCatalogItemData>(context) {
|
||||
|
||||
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
|
||||
var isAutoScroll = true
|
||||
@ -153,8 +154,8 @@ class SpecialCatalogAdapter(
|
||||
payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
|
||||
}
|
||||
}
|
||||
mExposureEventSparseArray.append(position, exposureEvent)
|
||||
}
|
||||
holder.exposureEvent = exposureEvent
|
||||
root.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(
|
||||
mContext,
|
||||
@ -208,28 +209,35 @@ class SpecialCatalogAdapter(
|
||||
is CatalogSubjectItemHolder -> {
|
||||
val subject = mEntityList[position].subject!!
|
||||
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
for ((index, game) in subject.link.data.withIndex()) {
|
||||
game.sequence = index
|
||||
game.subjectName = subject.link.text
|
||||
game.outerSequence = mEntityList[position].position
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
for ((index, game) in subject.link.data.withIndex()) {
|
||||
game.sequence = index
|
||||
game.subjectName = subject.link.text
|
||||
game.outerSequence = mEntityList[position].position
|
||||
|
||||
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
|
||||
game,
|
||||
mCatalogViewModel.basicExposureSource,
|
||||
listOf(ExposureSource("精选页专题", subject.link.text ?: ""))
|
||||
).apply {
|
||||
mLastPageDataMap?.let {
|
||||
payload.sourcePage = it[PageSwitchDataHelper.PAGE_BUSINESS_TYPE]
|
||||
payload.sourcePageId = it[PageSwitchDataHelper.PAGE_BUSINESS_ID]
|
||||
payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
|
||||
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
|
||||
game,
|
||||
mCatalogViewModel.basicExposureSource,
|
||||
listOf(ExposureSource("精选页专题", subject.link.text ?: ""))
|
||||
).apply {
|
||||
mLastPageDataMap?.let {
|
||||
payload.sourcePage = it[PageSwitchDataHelper.PAGE_BUSINESS_TYPE]
|
||||
payload.sourcePageId = it[PageSwitchDataHelper.PAGE_BUSINESS_ID]
|
||||
payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
|
||||
}
|
||||
}
|
||||
exposureList.add(exposureEvent)
|
||||
|
||||
game.exposureEvent = exposureEvent
|
||||
|
||||
if (!game.adGroupId.isEmpty() && !game.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(exposureEvent)
|
||||
game.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
exposureList.add(exposureEvent)
|
||||
|
||||
game.exposureEvent = exposureEvent
|
||||
mEntityList[position].exposureEventList = exposureList
|
||||
}
|
||||
mEntityList[position].exposureEventList = exposureList
|
||||
|
||||
holder.bindSubject(subject.link.data, mEntityList[position].position)
|
||||
}
|
||||
@ -265,10 +273,6 @@ class SpecialCatalogAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? = mExposureEventSparseArray.get(pos)
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? = mEntityList[pos].exposureEventList
|
||||
|
||||
inner class CatalogBannerItemHolder(val binding: CatalogBannerItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
@ -393,7 +397,14 @@ class SpecialCatalogAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
inner class CatalogImageItemHolder(val binding: CatalogImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
inner class CatalogImageItemHolder(val binding: CatalogImageItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
inner class CatalogHeaderItemHolder(val binding: CatalogHeaderItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root)
|
||||
|
||||
@ -3,14 +3,15 @@ package com.gh.gamecenter.catalog
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.ethanhua.skeleton.Skeleton
|
||||
import com.gh.common.exposure.DefaultExposureStateChangeListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.baselist.ListFragment
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
|
||||
import com.gh.gamecenter.feature.exposure.addExposureHelper
|
||||
|
||||
class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatalogViewModel>() {
|
||||
|
||||
@ -21,8 +22,6 @@ class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatal
|
||||
private var mAdapter: SpecialCatalogAdapter? = null
|
||||
private var mLastPageDataMap: HashMap<String, String>? = null
|
||||
|
||||
private lateinit var mExposureListener: ExposureListener
|
||||
|
||||
override fun getLayoutId() = 0
|
||||
|
||||
override fun getInflatedLayout() = mBinding.root
|
||||
@ -43,7 +42,6 @@ class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatal
|
||||
mLastPageDataMap
|
||||
).apply {
|
||||
mAdapter = this
|
||||
mExposureListener = ExposureListener(this@SpecialCatalogFragment, this)
|
||||
}
|
||||
|
||||
override fun getItemDecoration() = null
|
||||
@ -51,7 +49,6 @@ class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatal
|
||||
override fun isAutomaticLoad(): Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
mIsCategoryV2 = arguments?.getBoolean(EntranceConsts.KEY_IS_CATEGORY_V2) ?: false
|
||||
mCatalogId = arguments?.getString(EntranceConsts.KEY_CATALOG_ID) ?: ""
|
||||
mCatalogTitle = arguments?.getString(EntranceConsts.KEY_CATALOG_TITLE) ?: ""
|
||||
@ -65,6 +62,8 @@ class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatal
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mListRv.addExposureHelper(this, DefaultExposureStateChangeListener())
|
||||
|
||||
val skeletonLayoutId =
|
||||
if (mIsCategoryV2) R.layout.fragment_special_catalog_second_skeleton else R.layout.fragment_special_catalog_first_skeleton
|
||||
mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton)
|
||||
@ -77,8 +76,6 @@ class SpecialCatalogFragment : ListFragment<SpecialCatalogItemData, SpecialCatal
|
||||
.load(skeletonLayoutId)
|
||||
.show()
|
||||
onLoadRefresh()
|
||||
|
||||
mListRv.addOnScrollListener(mExposureListener)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
||||
@ -9,6 +9,8 @@ import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.CatalogSubjectGameItemBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class SpecialCatalogSubjectAdapter(
|
||||
@ -41,6 +43,8 @@ class SpecialCatalogSubjectAdapter(
|
||||
}
|
||||
|
||||
val entity = mList[position]
|
||||
|
||||
holder.bindGameEntity(entity)
|
||||
gameIcon.displayGameIcon(entity)
|
||||
gameName.text = entity.name
|
||||
gameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
|
||||
@ -84,5 +88,15 @@ class SpecialCatalogSubjectAdapter(
|
||||
}
|
||||
|
||||
class CatalogSubjectGameItemViewHolder(val binding: CatalogSubjectGameItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root)
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindGameEntity(gameEntity: GameEntity) {
|
||||
boundedGameEntity = gameEntity
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGameEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,7 +35,6 @@ class SpecialCatalogSubjectCollectionAdapter(
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
CatalogSubjectCollectionListItemViewHolder(parent.toBinding())
|
||||
|
||||
|
||||
override fun onBindViewHolder(holder: CatalogSubjectCollectionListItemViewHolder, position: Int) {
|
||||
holder.binding.run {
|
||||
root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
|
||||
@ -28,6 +28,12 @@ class CategoryV2Activity : DownloadToolbarActivity() {
|
||||
|
||||
override fun isAutoResetViewBackgroundEnabled() = true
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val categoryId = intent.extras?.getString(EntranceConsts.KEY_CATEGORY_ID, "") ?: ""
|
||||
return Pair(categoryId, "")
|
||||
return super.getBusinessId()
|
||||
}
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
package com.gh.gamecenter.category2
|
||||
|
||||
import android.content.Context
|
||||
import android.util.SparseArray
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.databind.BindingAdapters
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
@ -17,6 +16,7 @@ import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.DrawableView
|
||||
import com.gh.gamecenter.common.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
|
||||
import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.databinding.CategoryGameItemBinding
|
||||
@ -24,6 +24,7 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import org.json.JSONException
|
||||
@ -35,9 +36,7 @@ class CategoryV2ListAdapter(
|
||||
private val mCategoryViewModel: CategoryV2ViewModel,
|
||||
private val mEntrance: String?,
|
||||
private var mLastPageDataMap: HashMap<String, String>? = null
|
||||
) : ListAdapter<GameEntity>(context), IExposable {
|
||||
|
||||
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
|
||||
) : ListAdapter<GameEntity>(context) {
|
||||
|
||||
val positionAndPackageMap = HashMap<String, Int>()
|
||||
|
||||
@ -76,8 +75,15 @@ class CategoryV2ListAdapter(
|
||||
ItemViewType.GAME_NORMAL -> {
|
||||
CategoryGameItemViewHolder(parent.toBinding())
|
||||
}
|
||||
|
||||
else -> {
|
||||
FooterViewHolder(mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false))
|
||||
FooterViewHolder(
|
||||
mLayoutInflater.inflate(
|
||||
com.gh.gamecenter.common.R.layout.refresh_footerview,
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,7 +132,13 @@ class CategoryV2ListAdapter(
|
||||
payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
|
||||
}
|
||||
}
|
||||
mExposureEventSparseArray.put(position, event)
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
if (gameEntity.adGroupId.isEmpty() && !gameEntity.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(event)
|
||||
gameEntity.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(
|
||||
@ -227,17 +239,13 @@ class CategoryV2ListAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? {
|
||||
return mExposureEventSparseArray.get(pos)
|
||||
}
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
|
||||
return null
|
||||
}
|
||||
|
||||
inner class CategoryGameItemViewHolder(val binding: CategoryGameItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindGameItem(gameEntity: GameEntity) {
|
||||
boundedGameEntity = gameEntity
|
||||
binding.run {
|
||||
gameIconView.displayGameIcon(gameEntity)
|
||||
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
|
||||
@ -266,24 +274,34 @@ class CategoryV2ListAdapter(
|
||||
binding.gameKaifuType.visibility = View.GONE
|
||||
binding.gameKaifuType.text = ""
|
||||
}
|
||||
|
||||
serverLabel != null -> {
|
||||
binding.gameKaifuType.visibility = View.VISIBLE
|
||||
binding.gameKaifuType.text = serverLabel.value
|
||||
if (gameEntity.isUseDefaultServerStyle()) {
|
||||
binding.gameKaifuType.background =
|
||||
com.gh.gamecenter.feature.R.drawable.server_label_default_bg.toDrawable(binding.root.context)
|
||||
binding.gameKaifuType.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(binding.root.context))
|
||||
binding.gameKaifuType.setTextColor(
|
||||
com.gh.gamecenter.common.R.color.text_secondary.toColor(
|
||||
binding.root.context
|
||||
)
|
||||
)
|
||||
} else {
|
||||
binding.gameKaifuType.background = DrawableView.getServerDrawable(serverLabel.color)
|
||||
binding.gameKaifuType.setTextColor(com.gh.gamecenter.common.R.color.white.toColor(binding.root.context))
|
||||
}
|
||||
}
|
||||
|
||||
else -> binding.gameKaifuType.visibility = View.GONE
|
||||
}
|
||||
|
||||
// 由于RecyclerView的复用机制 需要每次测量gameName的宽
|
||||
binding.gameName.requestLayout()
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGameEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
inner class CategoryGameViewHolder(val binding: CategoryGameItemBinding) : GameViewHolder(binding.root) {
|
||||
|
||||
@ -4,8 +4,8 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.ethanhua.skeleton.Skeleton
|
||||
import com.gh.common.exposure.DefaultExposureStateChangeListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.view.CategoryFilterView
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
@ -22,6 +22,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SubjectSettingEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.exposure.addExposureHelper
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -119,7 +120,7 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
|
||||
}
|
||||
}
|
||||
|
||||
mListRv.addOnScrollListener(ExposureListener(this, provideListAdapter()))
|
||||
mListRv.addExposureHelper(this, DefaultExposureStateChangeListener())
|
||||
|
||||
mSkeletonScreen = Skeleton.bind(mBinding?.listSkeleton)
|
||||
.shimmer(true)
|
||||
|
||||
@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.gamecenter.common.entity.ExposureEntity
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils
|
||||
import com.gh.common.view.CategoryFilterView
|
||||
import com.gh.gamecenter.common.baselist.ListViewModel
|
||||
@ -35,7 +36,7 @@ class CategoryV2ListViewModel(
|
||||
return RetrofitManager
|
||||
.getInstance()
|
||||
.api
|
||||
.getCategoryV2Games(categoryId, getFilter(), getSortType(), page)
|
||||
.getCategoryV2Games(categoryId, getFilter(), getSortType(), AdHelper.getIdfaString(), page)
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
@ -79,7 +80,6 @@ class CategoryV2ListViewModel(
|
||||
"min_size", sortSize.min.toString(),
|
||||
"max_size", sortSize.max.toString()
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private fun getSortType(): String? {
|
||||
|
||||
@ -35,6 +35,7 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
|
||||
@ -346,7 +347,9 @@ class DiscoveryAdapter(
|
||||
return null
|
||||
}
|
||||
|
||||
class DiscoveryGameViewHolder(val binding: DiscoveryGameItemBinding) : GameViewHolder(binding.root) {
|
||||
class DiscoveryGameViewHolder(val binding: DiscoveryGameItemBinding) : GameViewHolder(binding.root), IExposureProvider {
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
init {
|
||||
gameDownloadBtn = binding.downloadBtn
|
||||
gameDes = binding.gameDes
|
||||
@ -358,6 +361,7 @@ class DiscoveryAdapter(
|
||||
}
|
||||
|
||||
fun bindGameItem(gameEntity: GameEntity) {
|
||||
boundedGameEntity = gameEntity
|
||||
binding.run {
|
||||
root.background = com.gh.gamecenter.common.R.drawable.reuse_listview_item_style.toDrawable(root.context)
|
||||
gameKaifuType.setBackgroundColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(root.context))
|
||||
@ -415,8 +419,12 @@ class DiscoveryAdapter(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
}
|
||||
|
||||
class RecommendInterestViewHolder(val binding: ItemRecommendInterestBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root)
|
||||
|
||||
@ -4,6 +4,7 @@ import android.os.Parcelable
|
||||
import com.gh.gamecenter.common.entity.IconFloat
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
@ -42,12 +43,16 @@ data class AmwayCommentEntity(
|
||||
// 曝光用的位置
|
||||
var sequence: Int = 0,
|
||||
var outerSequence: Int = 0
|
||||
|
||||
) : Parcelable {
|
||||
|
||||
@IgnoredOnParcel
|
||||
val name: String?
|
||||
get() = mName.removeSuffix(".")
|
||||
|
||||
@IgnoredOnParcel
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
fun toGameEntity(): GameEntity {
|
||||
val gameEntity = GameEntity()
|
||||
gameEntity.id = id
|
||||
|
||||
@ -33,7 +33,6 @@ class FollowCommonCollectionViewHolder(
|
||||
override fun addExposureEvent(childPosition: Int, link: ExposureLinkEntity) = Unit
|
||||
|
||||
override fun onChildItemClick(childPosition: Int, entity: CommonCollectionContentEntity) {
|
||||
|
||||
val linkEntity = entity.linkEntity
|
||||
|
||||
NewLogUtils.logCommonCollectionClick(
|
||||
|
||||
@ -50,9 +50,6 @@ class FollowHomeSlideListViewHolder(
|
||||
}
|
||||
|
||||
override fun updateImmersiveColor(color: Int) = Unit
|
||||
|
||||
override fun createExposureEvent(childPosition: Int, game: GameEntity?): ExposureEvent? = null
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -29,15 +29,12 @@ class FollowHomeSlideWithCardsViewHolder(
|
||||
useCase,
|
||||
lifecycleOwner,
|
||||
binding,
|
||||
0,
|
||||
null,
|
||||
"",
|
||||
object : CommonContentHomeSlideWithCardsUi.HomeSLideWithCardsEventListener {
|
||||
override fun updateImmersiveColor(color: Int) = Unit
|
||||
|
||||
override fun createEventWithSourceConcat(game: GameEntity, subSlideId: String) = Unit
|
||||
|
||||
override fun createExposureEvent(actualPosition: Int, game: GameEntity?): ExposureEvent? = null
|
||||
|
||||
override fun addGameExposureEvent(position: Int, game: GameEntity, subSlideId: String) = Unit
|
||||
|
||||
override fun navigateToGameDetailPage(
|
||||
childPosition: Int,
|
||||
gameEntity: GameEntity,
|
||||
|
||||
@ -399,7 +399,8 @@ class GameFragmentAdapter(
|
||||
position = prefixedPosition,
|
||||
gameColumnName = gameEntity.name ?: "",
|
||||
gameColumnId = gameEntity.link ?: "",
|
||||
text = "游戏专题"
|
||||
text = "游戏专题",
|
||||
adGroupId = gameEntity.adGroupId
|
||||
)
|
||||
}
|
||||
|
||||
@ -574,7 +575,7 @@ class GameFragmentAdapter(
|
||||
position = sequence,
|
||||
gameColumnName = subject.name ?: "",
|
||||
gameColumnId = subject.id ?: "",
|
||||
text = "游戏专题"
|
||||
text = "游戏专题",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -134,7 +134,8 @@ class GameHorizontalAdapter(
|
||||
gameColumnName = mSubjectEntity.name ?: "",
|
||||
gameColumnId = mSubjectEntity.id ?: "",
|
||||
text = "游戏",
|
||||
columnPattern = subjectTypeToComponentStyle[mSubjectEntity.type] ?: ""
|
||||
columnPattern = subjectTypeToComponentStyle[mSubjectEntity.type] ?: "",
|
||||
adGroupId = gameEntity.adGroupId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,9 +6,22 @@ import android.widget.TextView
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.databinding.GameHorizontalSimpleItemBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
|
||||
class GameHorizontalSimpleItemViewHolder(val binding: GameHorizontalSimpleItemBinding) :
|
||||
BaseRecyclerViewHolder<GameEntity>(binding.root) {
|
||||
BaseRecyclerViewHolder<GameEntity>(binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindData(game: GameEntity) {
|
||||
boundedGameEntity = game
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGameEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun setHorizontalNameAndGravity(view: TextView, name: String?) {
|
||||
|
||||
@ -26,8 +26,9 @@ class HotGameListViewModel(
|
||||
subjectData.subjectId,
|
||||
subjectData.sort,
|
||||
subjectData.filter.ifEmpty { "type:全部" },
|
||||
page
|
||||
)
|
||||
"",
|
||||
"",
|
||||
page)
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
|
||||
@ -819,6 +819,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
"game_schema_type", mGameEntity?.gameBitChinese ?: "",
|
||||
"download_type", mGameEntity?.downloadType ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
"is_ad", if (mGameEntity?.adGroupId.isNullOrEmpty()) "false" else "true",
|
||||
"ad_group_id", mGameEntity?.adGroupId ?: "",
|
||||
*(mTraceEvent?.additional ?: emptyArray())
|
||||
)
|
||||
}, 120)
|
||||
|
||||
@ -842,7 +842,8 @@ class DescAdapter(
|
||||
linkType = itemData.moreLink?.type ?: "",
|
||||
linkId = itemData.moreLink?.link ?: "",
|
||||
text = "右上角",
|
||||
buttonType = itemData.displayHome
|
||||
buttonType = itemData.displayHome,
|
||||
adGroupId = "",
|
||||
)
|
||||
if (itemData.displayHome == "换一批") {
|
||||
headPb.visibility = View.VISIBLE
|
||||
|
||||
@ -360,7 +360,8 @@ class LegacyHomeFragmentAdapterAssistant(
|
||||
position = prefixedPosition,
|
||||
gameColumnName = gameEntity.name ?: "",
|
||||
gameColumnId = gameEntity.link ?: "",
|
||||
text = "游戏专题"
|
||||
text = "游戏专题",
|
||||
adGroupId = gameEntity.adGroupId
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.gamecenter.home.custom
|
||||
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
@ -18,6 +19,7 @@ fun createExposureEvent(
|
||||
game?.sequence = childPosition
|
||||
game?.outerSequence = position
|
||||
game?.customPageTrackData = customPageTrackData
|
||||
game?.pageLevelString = customPageTrackData.pageLocation.pageLevelString
|
||||
val event = ExposureEvent.createEventWithSourceConcat(
|
||||
gameEntity = game,
|
||||
basicSource = base,
|
||||
@ -32,9 +34,7 @@ fun fillExposureInSubjectCollection(
|
||||
base: List<ExposureSource>,
|
||||
customPageTrackData: CustomPageTrackData
|
||||
) {
|
||||
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
item.data.data.forEachIndexed { index, customSubject ->
|
||||
val source = if (item.isSubjectCollection) {
|
||||
listOf(
|
||||
@ -51,8 +51,9 @@ fun fillExposureInSubjectCollection(
|
||||
)
|
||||
}
|
||||
customSubject.games.forEach { game ->
|
||||
game.pageLevelString = customPageTrackData.pageLocation.pageLevelString
|
||||
game.isAdData = customSubject.adIconActive
|
||||
val event = createExposureEvent(
|
||||
game.exposureEvent = createExposureEvent(
|
||||
game,
|
||||
source,
|
||||
base,
|
||||
@ -60,10 +61,12 @@ fun fillExposureInSubjectCollection(
|
||||
item.componentPosition,
|
||||
customPageTrackData
|
||||
)
|
||||
eventList.add(event)
|
||||
|
||||
if (!game.adGroupId.isEmpty() && !game.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(game.exposureEvent!!)
|
||||
game.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item.exposureEventList = eventList
|
||||
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.exposure.DefaultExposureStateChangeListener
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.iinterface.ISearchToolbarTab
|
||||
import com.gh.common.iinterface.ISmartRefresh
|
||||
@ -39,6 +39,7 @@ import com.gh.gamecenter.common.databinding.ReuseNoneDataBinding
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.pagelevel.IPageLevelProvider
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.ScrollableLinearLayoutManager
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
@ -57,6 +58,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.exposure.addExposureHelper
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
|
||||
@ -108,6 +110,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
private var customPageName = ""
|
||||
private var bottomTabId = ""
|
||||
private var bottomTabName = ""
|
||||
private var bottomTabIndex = -1
|
||||
private var tabIndex = -1
|
||||
|
||||
private lateinit var pageLocation: PageLocation
|
||||
@ -138,6 +141,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
customPageName = arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, "") ?: ""
|
||||
bottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
|
||||
bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
|
||||
bottomTabIndex = arguments?.getInt(EntranceConsts.KEY_BOTTOM_TAB_INDEX, -1) ?: -1
|
||||
tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
|
||||
val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: ""
|
||||
val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
|
||||
@ -174,8 +178,16 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
exposureSourceList,
|
||||
isInSearchToolbarTabWrapperPage
|
||||
)
|
||||
|
||||
val precisePageLevelString = (activity as? IPageLevelProvider)?.getPageLevel()?.geTempNewPageLevel(
|
||||
topTabPosition = tabIndex,
|
||||
bottomTabPosition = bottomTabIndex
|
||||
)?.toFormatedString(ignoreBottomTabPositionMap = true) ?: ""
|
||||
|
||||
pageLocation = PageLocation(
|
||||
bottomTabName,
|
||||
bottomTabIndex,
|
||||
precisePageLevelString,
|
||||
multiTabNavName,
|
||||
multiTabNavId,
|
||||
tabIndex,
|
||||
@ -328,7 +340,6 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
traceEvent = game.exposureEvent,
|
||||
)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
subjectDestination.observe(viewLifecycleOwner, EventObserver { subject ->
|
||||
@ -529,6 +540,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
binding.gameList.itemAnimator = null
|
||||
binding.gameList.layoutManager = layoutManager
|
||||
binding.gameList.adapter = adapter
|
||||
binding.gameList.addExposureHelper(this, DefaultExposureStateChangeListener())
|
||||
|
||||
var listScrollHeight = 0
|
||||
binding.gameList.addOnScrollListener(object : OnScrollListener() {
|
||||
@ -546,9 +558,6 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
}
|
||||
})
|
||||
|
||||
val exposureListener = ExposureListener(this, adapter)
|
||||
binding.gameList.addOnScrollListener(exposureListener)
|
||||
|
||||
binding.gameRefresh.setOnRefreshListener {
|
||||
onRefresh()
|
||||
}
|
||||
|
||||
@ -100,8 +100,6 @@ class CustomPageViewModel(
|
||||
*/
|
||||
private val cpmSubjectChangedPageMap: ArrayMap<String, Int> = ArrayMap()
|
||||
|
||||
var slideDiscoveryGamesPage = -1
|
||||
|
||||
private lateinit var _pageTracker: CustomPageTracker
|
||||
|
||||
val pageTracker: CustomPageTracker
|
||||
|
||||
@ -7,6 +7,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.databinding.GameCollectionBannerItemBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
|
||||
class AnnouncementBannerAdapter(
|
||||
@ -44,7 +46,6 @@ class AnnouncementBannerAdapter(
|
||||
} else {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +73,6 @@ class AnnouncementBannerAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: AnnouncementBannerChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
listener.exposure(position, item)
|
||||
holder.bind(item)
|
||||
holder.binding.bannerIv.setOnClickListener {
|
||||
listener.onItemClick(getDataPosition(position), item)
|
||||
@ -80,19 +80,23 @@ class AnnouncementBannerAdapter(
|
||||
}
|
||||
|
||||
class AnnouncementBannerChildViewHolder(val binding: GameCollectionBannerItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
fun bind(item: CustomPageData.Announcement) {
|
||||
exposureEvent = item.exposureEvent
|
||||
ImageUtils.display(binding.bannerIv, item.image)
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
interface OnChildEventListener {
|
||||
|
||||
fun onItemClick(childPosition: Int, announcement: CustomPageData.Announcement)
|
||||
|
||||
fun getCurrentPosition(): Int
|
||||
|
||||
fun exposure(childPosition: Int, announcement: CustomPageData.Announcement)
|
||||
}
|
||||
}
|
||||
@ -9,12 +9,13 @@ import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.databinding.RecyclerContentLabelLaneItemBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
|
||||
class ContentLabelLaneAdapter(
|
||||
context: Context,
|
||||
private val clickInvoke: (Int, CustomPageData.CommonContentCollection.ContentTag) -> Unit,
|
||||
private val exposureInvoke: (Int, CustomPageData.CommonContentCollection.ContentTag) -> Unit
|
||||
) : CustomBaseChildAdapter<CustomPageData.CommonContentCollection.ContentTag, ContentLabelLaneAdapter.ContentLabelChildViewHolder>(
|
||||
context
|
||||
) {
|
||||
@ -29,6 +30,9 @@ class ContentLabelLaneAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: ContentLabelChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
|
||||
holder.exposureEvent = item.exposureEvent
|
||||
|
||||
with(holder.binding) {
|
||||
vBackground.background = R.drawable.bg_shape_content_label_lane_item.toDrawable(context)
|
||||
tvTitle.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
|
||||
@ -47,7 +51,6 @@ class ContentLabelLaneAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
exposureInvoke(position, item)
|
||||
holder.itemView.setOnClickListener {
|
||||
clickInvoke(position, item)
|
||||
}
|
||||
@ -55,9 +58,12 @@ class ContentLabelLaneAdapter(
|
||||
|
||||
class ContentLabelChildViewHolder(
|
||||
val binding: RecyclerContentLabelLaneItemBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
) : RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
var exposureEvent : ExposureEvent? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -9,6 +9,8 @@ import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.databinding.CommonCollectionItemBinding
|
||||
import com.gh.gamecenter.entity.CommonCollectionContentEntity
|
||||
import com.gh.gamecenter.entity.ExposureLinkEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_IMAGE_TEXT
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
|
||||
@ -57,6 +59,7 @@ class CustomCommonCollectionAdapter(
|
||||
}
|
||||
}
|
||||
listener.addExposureEvent(position, item.linkEntity)
|
||||
holder.boundedLinkEntity = item.linkEntity
|
||||
|
||||
holder.binding.apply {
|
||||
ImageUtils.display(commonCollectionImage, item.image)
|
||||
@ -109,10 +112,15 @@ class CustomCommonCollectionAdapter(
|
||||
}
|
||||
|
||||
class CustomCommonCollectionItemViewHolder(val binding: CommonCollectionItemBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root)
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
var boundedLinkEntity: ExposureLinkEntity? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedLinkEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
interface OnEventListener {
|
||||
|
||||
fun addExposureEvent(childPosition: Int, exposureLinkEntity: ExposureLinkEntity)
|
||||
|
||||
fun onChildItemClick(childPosition: Int, item: CommonCollectionContentEntity)
|
||||
|
||||
@ -166,7 +166,6 @@ class CustomDiscoverCardGameAdapter(
|
||||
RetrofitManager.getInstance().api.discorveryFeedback(gameId, paramsMap.toRequestBody())
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
@ -194,7 +193,6 @@ class CustomDiscoverCardGameAdapter(
|
||||
notifyChildItem(busFour.packageName)
|
||||
}
|
||||
|
||||
|
||||
private fun notifyChildItem(packageName: String) {
|
||||
dataList.forEachIndexed { position, gameEntity ->
|
||||
gameEntity.getApk().forEach { apkEntity ->
|
||||
|
||||
@ -25,8 +25,9 @@ import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.databinding.RecyclerFoldSlideLargeImageItemBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
@ -53,7 +54,6 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
}
|
||||
submitList(list, true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getKey(t: GameEntity): String {
|
||||
@ -88,10 +88,8 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
holder.itemView.setOnClickListener {
|
||||
eventHelper.navigateToGameDetailPage(realPosition, game)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||
_recyclerView = recyclerView
|
||||
}
|
||||
@ -107,7 +105,6 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun notifyDownloadDeleted(status: EBDownloadStatus) {
|
||||
@ -139,7 +136,6 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
action(position, game)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getInitPosition() =
|
||||
@ -153,7 +149,7 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
private val eventHelper: SubjectEventHelper,
|
||||
val binding: RecyclerFoldSlideLargeImageItemBinding
|
||||
) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
|
||||
private lateinit var item: GameEntity
|
||||
|
||||
@ -200,7 +196,6 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
}
|
||||
|
||||
if (data.shouldShowDownloadButton) {
|
||||
|
||||
binding.btnDownload.goneIf(false)
|
||||
DownloadItemUtils.setOnClickListener(
|
||||
itemView.context, binding.btnDownload, game, bindingAdapterPosition,
|
||||
@ -226,7 +221,6 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
} else {
|
||||
binding.btnDownload.goneIf(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getBottomBackground(oColor: String): Pair<Int, Drawable> {
|
||||
@ -303,6 +297,11 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
item.updateBoundedExposureEventIfNeeded()
|
||||
return item.exposureEvent
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val BUBBLE_SHOW_DURATION = 4000L
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@ class CustomGameHorizontalSlideAdapter(
|
||||
|
||||
var gameName = ""
|
||||
var entrance = ""
|
||||
private var _exposureEventList: List<ExposureEvent>? = null
|
||||
|
||||
private var isShowFirstLine = false
|
||||
private var isShowSecondLine = false
|
||||
@ -42,12 +41,11 @@ class CustomGameHorizontalSlideAdapter(
|
||||
get() = _data.data
|
||||
|
||||
|
||||
fun setData(data: CustomSubjectItem, exposureEventList: List<ExposureEvent>?) {
|
||||
fun setData(data: CustomSubjectItem) {
|
||||
isShowFirstLine = false
|
||||
isShowSecondLine = false
|
||||
hasTwoLinesName = false
|
||||
_data = data
|
||||
_exposureEventList = exposureEventList
|
||||
data.data.data?.forEach {
|
||||
if (!isShowFirstLine && it.assignRemark.firstLine.isNotEmpty()) {
|
||||
isShowFirstLine = true
|
||||
@ -86,7 +84,6 @@ class CustomGameHorizontalSlideAdapter(
|
||||
}
|
||||
holder.bindGameHorizontalItem(gameEntity, subjectEntity, isShowFirstLine, isShowSecondLine)
|
||||
holder.itemView.setOnClickListener {
|
||||
gameEntity.exposureEvent = _exposureEventList?.getOrNull(position)
|
||||
eventHelper.navigateToGameDetailPage(position, gameEntity)
|
||||
}
|
||||
|
||||
@ -99,7 +96,7 @@ class CustomGameHorizontalSlideAdapter(
|
||||
this,
|
||||
StringUtils.buildString("(游戏-专题:", subjectEntity.name, "-列表[", (position + 1).toString(), "])"),
|
||||
location = StringUtils.buildString("游戏-专题-", subjectEntity.name, ":", gameEntity.name),
|
||||
traceEvent = _exposureEventList?.getOrNull(position)
|
||||
traceEvent = gameEntity.exposureEvent
|
||||
) {
|
||||
eventHelper.onDownloadButtonClick(position, gameEntity)
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.gh.gamecenter.entity.GameNavigationEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
|
||||
class CustomGameNavigationAdapter(
|
||||
context: Context,
|
||||
@ -46,6 +47,7 @@ class CustomGameNavigationAdapter(
|
||||
// 是否显示小红点
|
||||
var isShowHint = false
|
||||
val entity = dataList[position]
|
||||
holder.exposureEvent = exposureEventList?.getOrNull(position)
|
||||
ImageUtils.display(holder.binding.navigationView, entity.image)
|
||||
holder.binding.navigationNameTv.text = if (entity.isShowEntryName) {
|
||||
entity.entryName
|
||||
@ -132,7 +134,6 @@ class CustomGameNavigationAdapter(
|
||||
listener.navigateToLinkPage(it, "导航栏", exposureEvent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun showGuide(entity: GameNavigationEntity, binding: ItemGameNavigationCustomBinding) {
|
||||
@ -156,7 +157,6 @@ class CustomGameNavigationAdapter(
|
||||
gradientDrawable.setStroke(1F.dip2px(), entity.guide.borderColorInt)
|
||||
gradientDrawable.setColor(entity.guide.backgroundColorInt)
|
||||
binding.tvBubble.background = gradientDrawable
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -164,7 +164,14 @@ class CustomGameNavigationAdapter(
|
||||
}
|
||||
|
||||
class GameNavigationViewHolder(val binding: ItemGameNavigationCustomBinding) :
|
||||
BaseRecyclerViewHolder<RecyclerView.ViewHolder>(binding.root)
|
||||
BaseRecyclerViewHolder<RecyclerView.ViewHolder>(binding.root), IExposureProvider {
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
interface OnEventListener {
|
||||
fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
|
||||
|
||||
@ -15,7 +15,6 @@ import com.gh.common.util.HomePluggableHelper
|
||||
import com.gh.gamecenter.common.constant.ItemViewType
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.MtaHelper.onEvent
|
||||
import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
@ -119,7 +118,6 @@ class CustomGamePluginAdapter(
|
||||
null
|
||||
)
|
||||
holder.itemView.setOnClickListener { v: View? ->
|
||||
onEvent("首页_新", "点击", "插件化" + (position + 1) + "_" + gameEntity.name)
|
||||
DataCollectionUtils.uploadClick(
|
||||
context,
|
||||
"插件化" + "-列表",
|
||||
|
||||
@ -11,10 +11,10 @@ import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.game.vertical.GameItemUi
|
||||
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
@ -95,12 +95,13 @@ class CustomGameRefreshVerticalAdapter(
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class SimpleGameItemViewHolder(private val ui: GameItemUi) : ViewHolder(ui.root) {
|
||||
inner class SimpleGameItemViewHolder(private val ui: GameItemUi) : ViewHolder(ui.root), IExposureProvider {
|
||||
var placeholderGameViewHolder: GameViewHolder? = null
|
||||
|
||||
private var exposureEvent: ExposureEvent? = null
|
||||
|
||||
fun bindSimpleGameItem(
|
||||
adapter: RecyclerView.Adapter<ViewHolder>,
|
||||
gameEntity: GameEntity,
|
||||
@ -124,6 +125,8 @@ class CustomGameRefreshVerticalAdapter(
|
||||
var paddingEnd = if (isEndOfRow) 16F.dip2px() else 0F.dip2px()
|
||||
val height = 80F.dip2px()
|
||||
|
||||
exposureEvent = gameEntity.exposureEvent
|
||||
|
||||
itemView.layoutParams = if (!isEndOfRow) {
|
||||
paddingEnd += 1
|
||||
ViewGroup.LayoutParams(maxWidth - 24F.dip2px(), height)
|
||||
@ -209,6 +212,9 @@ class CustomGameRefreshVerticalAdapter(
|
||||
root.setPadding(paddingStart, 8F.dip2px(), paddingEnd, 8F.dip2px())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,8 +13,9 @@ import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.game.vertical.GameItemUi
|
||||
@ -102,9 +103,11 @@ class CustomGameVerticalAdapter(
|
||||
class SimpleGameItemViewHolder(
|
||||
private val ui: GameItemUi,
|
||||
private val eventHelper: SubjectEventHelper
|
||||
) : ViewHolder(ui.root) {
|
||||
) : ViewHolder(ui.root), IExposureProvider {
|
||||
var placeholderGameViewHolder: GameViewHolder? = null
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindSimpleGameItem(
|
||||
adapter: RecyclerView.Adapter<ViewHolder>,
|
||||
gameEntity: GameEntity,
|
||||
@ -120,6 +123,8 @@ class CustomGameVerticalAdapter(
|
||||
) {
|
||||
val context = itemView.context
|
||||
|
||||
boundedGameEntity = gameEntity
|
||||
|
||||
val paddingStart = 16F.dip2px()
|
||||
val isEndOfRow = position >= if (adapter.itemCount % spanCount == 0) {
|
||||
adapter.itemCount - spanCount
|
||||
@ -211,6 +216,11 @@ class CustomGameVerticalAdapter(
|
||||
root.setPadding(paddingStart, root.paddingTop, paddingEnd, root.paddingBottom)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -12,6 +12,8 @@ import com.gh.gamecenter.common.utils.safelyGetInRelease
|
||||
import com.gh.gamecenter.common.view.AsyncCell
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.HomeGameCollectionCardItemCustomBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
@ -21,10 +23,9 @@ class CustomHomeGameCollectionCarouselAdapter(
|
||||
context: Context,
|
||||
private val pageConfigure: PageConfigure,
|
||||
private val eventHelper: GameSubjectCollectionEventHelper
|
||||
) :
|
||||
CustomBaseChildAdapter<CustomPageData.LinkColumnCollection.CustomSubjectEntity, CustomHomeGameCollectionCarouselAdapter.HomeGameCollectionCardViewHolder>(
|
||||
context
|
||||
) {
|
||||
) : CustomBaseChildAdapter<
|
||||
CustomPageData.LinkColumnCollection.CustomSubjectEntity,
|
||||
CustomHomeGameCollectionCarouselAdapter.HomeGameCollectionCardViewHolder>(context) {
|
||||
|
||||
private val mPosterWidth = DisplayUtils.getScreenWidth() - 50F.dip2px()
|
||||
|
||||
@ -48,10 +49,8 @@ class CustomHomeGameCollectionCarouselAdapter(
|
||||
pageConfigure.entrance,
|
||||
position
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int) = position
|
||||
@ -68,15 +67,18 @@ class CustomHomeGameCollectionCarouselAdapter(
|
||||
}
|
||||
|
||||
inner class HomeGameCollectionCardViewHolder(cell: HomeGameCollectionCarouselItemCell) :
|
||||
BaseRecyclerViewHolder<Any>(cell) {
|
||||
BaseRecyclerViewHolder<Any>(cell), IExposureListProvider {
|
||||
private var boundedItemData: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null
|
||||
|
||||
fun bindGameCollectionCard(
|
||||
binding: HomeGameCollectionCardItemCustomBinding,
|
||||
itemData: CustomPageData.LinkColumnCollection.CustomSubjectEntity,
|
||||
entrance: String,
|
||||
itemPosition: Int
|
||||
) {
|
||||
boundedItemData = itemData
|
||||
|
||||
binding.run {
|
||||
val context = root.context
|
||||
root.layoutParams.width = mPosterWidth
|
||||
|
||||
if (itemData.user.isValid) {
|
||||
@ -121,8 +123,16 @@ class CustomHomeGameCollectionCarouselAdapter(
|
||||
root.setOnClickListener {
|
||||
eventHelper.navigateSubjectCollectionPage(itemPosition, itemData)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
return boundedItemData?.games?.map {
|
||||
it.updateBoundedExposureEventIfNeeded()
|
||||
it.exposureEvent!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,8 +18,9 @@ import com.gh.gamecenter.databinding.ItemHomeGameCollectionBigSlideCardGameBindi
|
||||
import com.gh.gamecenter.databinding.ItemHomeGameCollectionSmallSlideCardCustomBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
@ -106,6 +107,7 @@ class CustomHomeGameCollectionSlideAdapter(
|
||||
|
||||
// 小卡片
|
||||
if (holder is HomeGameCollectionSmallSlideCardViewHolder) {
|
||||
holder.updateSubject(subject)
|
||||
holder.binding.run {
|
||||
val params = root.layoutParams as ViewGroup.MarginLayoutParams
|
||||
params.leftMargin = if (position == 0) 0 else (-24F).dip2px()
|
||||
@ -184,8 +186,10 @@ class CustomHomeGameCollectionSlideAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
inner class HomeGameCollectionBigSlideCardViewHolder(view: View) : BaseRecyclerViewHolder<Any>(view),
|
||||
IGameChangedNotifier {
|
||||
inner class HomeGameCollectionBigSlideCardViewHolder(view: View) :
|
||||
BaseRecyclerViewHolder<Any>(view),
|
||||
IGameChangedNotifier,
|
||||
IExposureListProvider {
|
||||
|
||||
private var subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null
|
||||
|
||||
@ -294,8 +298,35 @@ class CustomHomeGameCollectionSlideAdapter(
|
||||
eventHelper.navigateToGameDetailPage(bindingAdapterPosition, gameEntity, subject)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
return subject?.games?.map {
|
||||
it.updateBoundedExposureEventIfNeeded()
|
||||
it.exposureEvent!!
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
|
||||
}
|
||||
|
||||
class HomeGameCollectionSmallSlideCardViewHolder(val binding: ItemHomeGameCollectionSmallSlideCardCustomBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
RecyclerView.ViewHolder(binding.root),
|
||||
IExposureListProvider {
|
||||
|
||||
private var boundedSubject: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null
|
||||
|
||||
fun updateSubject(subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity) {
|
||||
boundedSubject = subject
|
||||
}
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
return boundedSubject?.games?.map {
|
||||
it.updateBoundedExposureEventIfNeeded()
|
||||
it.exposureEvent!!
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
}
|
||||
}
|
||||
@ -5,20 +5,28 @@ import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.entity.GameDataWrapper
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.OtherItemEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListPlaceHolderViewHolder
|
||||
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListSpaceViewHolder
|
||||
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* @author : liujiarui
|
||||
@ -30,7 +38,9 @@ class CustomHomeGameTestV2GameListRvAdapter(
|
||||
private val childEventHelper: OtherItemEventHelper,
|
||||
private val linkText: String,
|
||||
private val pageLocation: PageLocation,
|
||||
private val exposureInvoke: (Int, GameEntity) -> ExposureEvent
|
||||
private val pageConfigure: PageConfigure,
|
||||
private val componentPosition: Int,
|
||||
private val trackData: CustomPageTrackData,
|
||||
) : CustomBaseChildAdapter<GameDataWrapper, ViewHolder>(context) {
|
||||
|
||||
private val mEntrance: String = "新游开测"
|
||||
@ -62,7 +72,6 @@ class CustomHomeGameTestV2GameListRvAdapter(
|
||||
&& oldItem.gameData?.id == newItem.gameData?.id
|
||||
&& oldItem.gameData?.name == newItem.gameData?.name
|
||||
}
|
||||
|
||||
}, false).dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
@ -175,7 +184,6 @@ class CustomHomeGameTestV2GameListRvAdapter(
|
||||
notifyItemChanged(index)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun notifyDownloadDeleted(status: EBDownloadStatus) {
|
||||
@ -201,17 +209,21 @@ class CustomHomeGameTestV2GameListRvAdapter(
|
||||
gameEntity: GameEntity,
|
||||
position: Int
|
||||
): ExposureEvent {
|
||||
return exposureInvoke(position, gameEntity)
|
||||
val time = gameEntity.time?.time ?: 0L
|
||||
val date = Date(time * 1000L)
|
||||
val sdf = SimpleDateFormat("MM.dd", Locale.CHINA)
|
||||
val format = sdf.format(date)
|
||||
|
||||
gameEntity.exposureEvent = createExposureEvent(
|
||||
gameEntity,
|
||||
listOf(ExposureSource("新游开测", "$linkText-$format")),
|
||||
pageConfigure.exposureSourceList,
|
||||
position,
|
||||
componentPosition,
|
||||
trackData
|
||||
)
|
||||
|
||||
return gameEntity.exposureEvent!!
|
||||
}
|
||||
|
||||
/**
|
||||
* 左右滑动曝光条目
|
||||
*/
|
||||
fun exposureItem(firstItemPosition: Int) {
|
||||
val gameList = dataList
|
||||
for (position in firstItemPosition..firstItemPosition + 2) {
|
||||
val gameEntity = gameList.getOrNull(position)?.gameData ?: continue
|
||||
putExposureEvent(gameEntity, position)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,9 +6,7 @@ import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -23,7 +21,6 @@ class CustomHomeHorizontalSlideVideoAdapter(
|
||||
context: Context,
|
||||
private val pageConfigure: PageConfigure,
|
||||
private val eventHelper: SubjectEventHelper,
|
||||
private val exposureClosure: (GameEntity, Int) -> ExposureEvent,
|
||||
) : CustomBaseChildAdapter<GameEntity, CustomHomeHorizontalSlideVideoItemViewHolder>(context) {
|
||||
|
||||
private lateinit var item: CustomSubjectItem
|
||||
@ -44,8 +41,6 @@ class CustomHomeHorizontalSlideVideoAdapter(
|
||||
override fun onBindViewHolder(holder: CustomHomeHorizontalSlideVideoItemViewHolder, position: Int) {
|
||||
val gameEntity = dataList[position]
|
||||
|
||||
val event = exposureClosure(gameEntity, position)
|
||||
|
||||
holder.binding.root.setPadding(
|
||||
16F.dip2px(),
|
||||
holder.binding.root.topPadding,
|
||||
@ -67,13 +62,11 @@ class CustomHomeHorizontalSlideVideoAdapter(
|
||||
gameEntity,
|
||||
this,
|
||||
pageConfigure.entrance,
|
||||
event,
|
||||
item.data.showIndexIconSubscript,
|
||||
item.data.showIndexSubtitle
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun notifyDownload(download: DownloadEntity) {
|
||||
dataList.forEachIndexed { index, game ->
|
||||
if (game.id == download.gameId) {
|
||||
|
||||
@ -10,6 +10,8 @@ import com.gh.gamecenter.common.entity.IconFloat
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.databinding.ItemHomeVgameRefactorBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.eventlistener.OtherItemEventHelper
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.vspace.VGameItemData
|
||||
@ -52,9 +54,13 @@ class CustomHomeRecentVGameAdapter(
|
||||
private var binding: ItemHomeVgameRefactorBinding,
|
||||
private val childEventHelper: OtherItemEventHelper
|
||||
) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
|
||||
private var boundedItem: VGameItemData? = null
|
||||
|
||||
fun bindView(entity: VGameItemData) {
|
||||
boundedItem = entity
|
||||
|
||||
if (binding.gameIconIv.getTag(R.string.app_name) != entity.downloadEntity.packageName) {
|
||||
val iconFloat = IconFloat(
|
||||
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT),
|
||||
@ -176,5 +182,9 @@ class CustomHomeRecentVGameAdapter(
|
||||
binding.controlTv.text = itemData.controlText
|
||||
binding.progressBar.progress = downloadEntity.percent.toInt()
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedItem?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,7 +130,6 @@ class CustomHomeRecommendItemGridAdapter(
|
||||
}
|
||||
|
||||
interface OnEventListener {
|
||||
|
||||
fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
|
||||
}
|
||||
}
|
||||
@ -15,8 +15,6 @@ import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.utils.DataLogUtils
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
|
||||
import com.gh.gamecenter.entity.HomeSlide
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
@ -50,7 +48,6 @@ class CustomHomeSlideListAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val dataCount: Int
|
||||
get() = dataList.size
|
||||
|
||||
@ -77,21 +74,8 @@ class CustomHomeSlideListAdapter(
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
val homeSlide = dataList[actualPosition]
|
||||
|
||||
val game = homeSlide.linkGame
|
||||
if (homeSlide.linkType == "game") {
|
||||
game?.exposureEvent = listener.createExposureEvent(actualPosition, game)
|
||||
} else {
|
||||
game?.exposureEvent = listener.createExposureEvent(actualPosition, game)
|
||||
?.also {
|
||||
it.payload.controlType = "轮播图"
|
||||
it.payload.controlName = homeSlide.title
|
||||
it.payload.controlLinkName = homeSlide.linkText
|
||||
it.payload.controlLinkType = homeSlide.linkType
|
||||
}
|
||||
}
|
||||
|
||||
if (holder is CustomHomeSlideListItemViewHolder) {
|
||||
holder.bindSlideListItem(homeSlide)
|
||||
@ -129,11 +113,6 @@ class CustomHomeSlideListAdapter(
|
||||
) {
|
||||
rootView.setOnClickListener {
|
||||
val actualPositionString = (actualPosition + 1).toString()
|
||||
if (homeSlide.linkType == "video") {
|
||||
MtaHelper.onEvent("首页_新", "轮播_点击", actualPositionString + "_视频详情")
|
||||
} else if (homeSlide.linkType == "game") {
|
||||
MtaHelper.onEvent("首页_新", "轮播_点击", actualPositionString + "_游戏详情")
|
||||
}
|
||||
|
||||
PageSwitchDataHelper.pushCurrentPageData(
|
||||
hashMapOf(
|
||||
@ -240,11 +219,8 @@ class CustomHomeSlideListAdapter(
|
||||
fun getActualSize() = dataList.size
|
||||
|
||||
interface OnEventListener {
|
||||
fun createExposureEvent(actualPosition: Int, game: GameEntity?): ExposureEvent?
|
||||
|
||||
fun navigateToGameDetailPage(actualPosition: Int, game: GameEntity, text: String, link: LinkEntity?)
|
||||
|
||||
fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,18 @@
|
||||
package com.gh.gamecenter.home.custom.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.databinding.RecyclerChildIconMatrixCustomBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomPageAdapter.Companion.PAYLOAD_REFRESH_GAME_CHANGED
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
@ -50,6 +48,9 @@ class CustomIconMatrixAdapter(
|
||||
val isRefreshDownloadStatus = payloads.any {
|
||||
PAYLOAD_REFRESH_GAME_CHANGED == it
|
||||
}
|
||||
|
||||
holder.boundedGameEntity = getItem(position)
|
||||
|
||||
if (isRefreshDownloadStatus) {
|
||||
DownloadItemUtils.updateItem(
|
||||
context,
|
||||
@ -77,7 +78,6 @@ class CustomIconMatrixAdapter(
|
||||
item.name
|
||||
)
|
||||
gameName.maxLines = if (subject.showDownload) 1 else 2
|
||||
|
||||
}
|
||||
val showStar = subject.showStar
|
||||
&& subject.data?.any { it.commentCount > 3 } ?: false
|
||||
@ -123,7 +123,6 @@ class CustomIconMatrixAdapter(
|
||||
notifyItemChanged(index, PAYLOAD_REFRESH_GAME_CHANGED)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun notifyDownloadDeleted(status: EBDownloadStatus) {
|
||||
@ -147,5 +146,12 @@ class CustomIconMatrixAdapter(
|
||||
|
||||
class CustomChildIconMatrixViewHolder(
|
||||
val binding: RecyclerChildIconMatrixCustomBinding
|
||||
) : ViewHolder(binding.root)
|
||||
) : ViewHolder(binding.root), IExposureProvider {
|
||||
var boundedGameEntity: GameEntity? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,13 +9,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.baselist.LoadStatus
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.game.GameAndPosition
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
@ -66,7 +64,7 @@ class CustomPageAdapter(
|
||||
private val viewModel: CustomPageViewModel,
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
private val scrollCalculatorHelper: ScrollCalculatorHelper,
|
||||
) : ListAdapter<CustomPageItem, BaseCustomViewHolder>(CALLBACK), IExposable, IGameChangedNotifier {
|
||||
) : ListAdapter<CustomPageItem, BaseCustomViewHolder>(CALLBACK), IGameChangedNotifier {
|
||||
|
||||
private var loadStatus: LoadStatus? = null
|
||||
|
||||
@ -283,10 +281,10 @@ class CustomPageAdapter(
|
||||
val item = getItem(position)
|
||||
when (holder) {
|
||||
is CustomDoubleCardViewHolder -> holder.bindView(item)
|
||||
|
||||
is CustomHomeHorizontalSlideVideoListViewHolder -> holder.bindView(item)
|
||||
is CustomGameItemViewHolder -> {
|
||||
holder.bindView(item, this)
|
||||
}
|
||||
|
||||
is CustomGameItemViewHolder -> holder.bindView(item, this)
|
||||
|
||||
is CustomGameVerticalSlideViewHolder -> holder.bindView(item)
|
||||
|
||||
@ -316,9 +314,7 @@ class CustomPageAdapter(
|
||||
|
||||
is CustomHomeItemGameTestV2ViewHolder -> holder.bindView(item, position)
|
||||
|
||||
is CustomHomeDiscoverCardViewHolder -> {
|
||||
holder.bindView(item, position)
|
||||
}
|
||||
is CustomHomeDiscoverCardViewHolder -> holder.bindView(item, position)
|
||||
|
||||
is CustomBigImageRecommendViewHolder -> holder.bindView(item)
|
||||
|
||||
@ -392,14 +388,6 @@ class CustomPageAdapter(
|
||||
holder.onViewDetach(recyclerView)
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? {
|
||||
return getItem(pos).exposureEvent
|
||||
}
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
|
||||
return getItem(pos).exposureEventList
|
||||
}
|
||||
|
||||
override fun notifyDownload(download: DownloadEntity) {
|
||||
val data = getGameEntityByPackage(download.packageName)
|
||||
data.forEach { (game, position, _) ->
|
||||
@ -425,7 +413,6 @@ class CustomPageAdapter(
|
||||
it.notifyDownloadDeleted(status)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun notifyInstalled(busFour: EBPackage) {
|
||||
@ -488,7 +475,6 @@ class CustomPageAdapter(
|
||||
|
||||
|
||||
private val onLoadMoreListener = object : OnScrollListener() {
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
val layoutManger = recyclerView.layoutManager
|
||||
@ -499,7 +485,6 @@ class CustomPageAdapter(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -10,8 +10,9 @@ import com.gh.gamecenter.common.view.AsyncCell
|
||||
import com.gh.gamecenter.databinding.RankCollectionItemCustomBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.game.rank.CustomRankGameItem
|
||||
import com.gh.gamecenter.game.rank.RankGameItemUi
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
@ -109,8 +110,6 @@ class CustomRankCollectionAdapter(
|
||||
holder.gameItemList[i].rankItemUi.root.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +137,6 @@ class CustomRankCollectionAdapter(
|
||||
override fun onViewAttachedToWindow(holder: RankCollectionItemViewHolder) {
|
||||
super.onViewAttachedToWindow(holder)
|
||||
viewHolderList.add(holder)
|
||||
|
||||
}
|
||||
|
||||
override fun onViewDetachedFromWindow(holder: RankCollectionItemViewHolder) {
|
||||
@ -162,7 +160,7 @@ class CustomRankCollectionAdapter(
|
||||
}
|
||||
|
||||
inner class RankCollectionItemViewHolder(view: View) :
|
||||
BaseRecyclerViewHolder<Any>(view), IGameChangedNotifier {
|
||||
BaseRecyclerViewHolder<Any>(view), IGameChangedNotifier, IExposureListProvider {
|
||||
|
||||
val gameItemList = arrayListOf<CustomRankGameItem>()
|
||||
|
||||
@ -235,5 +233,14 @@ class CustomRankCollectionAdapter(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
return subjectEntity?.games?.map {
|
||||
it.updateBoundedExposureEventIfNeeded()
|
||||
it.exposureEvent!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,8 @@ import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.RecyclerRefreshIconItemCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.game.horizontal.GameHorizontalSimpleItemViewHolder
|
||||
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
@ -16,7 +18,6 @@ import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
class CustomRefreshIconAdapter(
|
||||
context: Context,
|
||||
private val eventHelper: GameSubjectCollectionEventHelper,
|
||||
private val exposureInvoke: (Int, GameEntity) -> Unit
|
||||
) : CustomBaseChildAdapter<GameEntity, CustomRefreshIconAdapter.RefreshIconChildViewHolder>(context) {
|
||||
|
||||
private var collectionName = ""
|
||||
@ -45,8 +46,7 @@ class CustomRefreshIconAdapter(
|
||||
override fun onBindViewHolder(holder: RefreshIconChildViewHolder, position: Int) {
|
||||
val gameEntity = getItem(position)
|
||||
|
||||
exposureInvoke(position, gameEntity)
|
||||
|
||||
holder.exposureEvent = gameEntity.exposureEvent
|
||||
holder.binding.run {
|
||||
val padR = if (position == itemCount - 1) 16F.dip2px() else 0
|
||||
root.setPadding(16F.dip2px(), 0, padR, 0)
|
||||
@ -65,10 +65,15 @@ class CustomRefreshIconAdapter(
|
||||
)
|
||||
eventHelper.navigateToGameDetailPage(position, gameEntity, subject)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RefreshIconChildViewHolder(val binding: RecyclerRefreshIconItemCustomBinding) : ViewHolder(binding.root)
|
||||
class RefreshIconChildViewHolder(val binding: RecyclerRefreshIconItemCustomBinding) :
|
||||
ViewHolder(binding.root), IExposureProvider {
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,12 +6,11 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.visibleIf
|
||||
import com.gh.gamecenter.databinding.RecyclerNotificationColumnItemBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
|
||||
class NotificationColumnAdapter(
|
||||
context: Context,
|
||||
private val exposureInvoke: (Int, CustomPageData.Notify) -> Unit
|
||||
) :
|
||||
class NotificationColumnAdapter(context: Context, ) :
|
||||
CustomBaseChildAdapter<CustomPageData.Notify, NotificationColumnAdapter.NotificationColumChildViewHolder>(context) {
|
||||
|
||||
private var toBeDeletedItemIds = arrayListOf<String>()
|
||||
@ -51,13 +50,14 @@ class NotificationColumnAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: NotificationColumChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
|
||||
holder.exposureEvent = item.exposureEvent
|
||||
with(holder.binding) {
|
||||
ivIcon.displayGameIcon(item.image, null, goneIfEmpty = true, null)
|
||||
tvTitle.text = item.title
|
||||
tvDesc.text = item.addedContent
|
||||
ivClose.visibleIf(item.isClosable)
|
||||
}
|
||||
exposureInvoke(position, item)
|
||||
}
|
||||
|
||||
private fun getValidItem(position: Int): CustomPageData.Notify {
|
||||
@ -90,5 +90,13 @@ class NotificationColumnAdapter(
|
||||
|
||||
class NotificationColumChildViewHolder(
|
||||
val binding: RecyclerNotificationColumnItemBinding
|
||||
) : RecyclerView.ViewHolder(binding.root)
|
||||
) : RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.databinding.RecyclerRecommendCardItemBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.home.custom.ui.RecommendCardUi
|
||||
|
||||
@ -23,7 +25,6 @@ class RecommendCardAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: RecommendCardChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
listener.onItemExposure(position, item)
|
||||
holder.bind(item, position)
|
||||
holder.itemView.setOnClickListener {
|
||||
listener.onItemClick(position, item)
|
||||
@ -31,9 +32,13 @@ class RecommendCardAdapter(
|
||||
}
|
||||
|
||||
class RecommendCardChildViewHolder(val binding: RecyclerRecommendCardItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
RecyclerView.ViewHolder(binding.root), IExposureProvider {
|
||||
|
||||
private var exposureEvent: ExposureEvent? = null
|
||||
|
||||
fun bind(item: CustomPageData.RecommendCard, position: Int) {
|
||||
exposureEvent = item.exposureEvent
|
||||
|
||||
binding.tvTitle.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(itemView.context))
|
||||
binding.tvOriginalPrice.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(itemView.context))
|
||||
|
||||
@ -87,5 +92,9 @@ class RecommendCardAdapter(
|
||||
hideOutOfBoundViewsIfNeed(views)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.FloatingWindowEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
|
||||
@ -560,6 +561,8 @@ class CustomPageData(
|
||||
community = _linkCommunity
|
||||
)
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
data class Guide(
|
||||
@SerializedName("text")
|
||||
private val _text: String? = null
|
||||
@ -627,6 +630,8 @@ class CustomPageData(
|
||||
text = linkText,
|
||||
community = _linkCommunity
|
||||
)
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
}
|
||||
|
||||
data class Announcement(
|
||||
@ -669,6 +674,8 @@ class CustomPageData(
|
||||
text = linkText,
|
||||
community = _linkCommunity
|
||||
)
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
}
|
||||
|
||||
data class LinkQqGameRecentlyPlayed(
|
||||
@ -749,6 +756,8 @@ class CustomPageData(
|
||||
community = _linkCommunity
|
||||
)
|
||||
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
|
||||
data class TextWithSymbol(
|
||||
@SerializedName("text")
|
||||
private val _text: String? = null,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.gamecenter.home.custom.model
|
||||
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
@ -36,7 +37,7 @@ class CustomPageRemoteDataSource(
|
||||
it.onSuccess(mainWrapperRepository.customPageLiveData.value!!)
|
||||
}
|
||||
} else {
|
||||
newApi.getCustomPageData(pageId, page)
|
||||
newApi.getCustomPageData(pageId, page, AdHelper.getIdfaString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -635,14 +635,14 @@ class CustomPageRepository private constructor(
|
||||
}
|
||||
|
||||
if (gameSubject != null && !gameSubject.data.isNullOrEmpty()) {
|
||||
// 替换游戏
|
||||
substituteGameIfNeeded(gameSubject)
|
||||
|
||||
// 记录已显示的游戏 id
|
||||
for (game in gameSubject.data!!) {
|
||||
displayingGameIdSet.add(game.id)
|
||||
}
|
||||
|
||||
// 替换游戏
|
||||
substituteGameIfNeeded(gameSubject)
|
||||
|
||||
if (gameSubject.tag == "update") {
|
||||
// 优先显示更新标签
|
||||
gameSubject.data?.forEach {
|
||||
|
||||
@ -90,7 +90,8 @@ class GameSubjectCollectionTracker(private val pageLocation: PageLocation) {
|
||||
game?.name ?: "",
|
||||
link?.type ?: "",
|
||||
link?.link ?: "",
|
||||
link?.text ?: ""
|
||||
link?.text ?: "",
|
||||
adGroupId = game?.adGroupId ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,8 @@ class SubjectTracker(private val pageLocation: PageLocation) {
|
||||
"自定义页面",
|
||||
item.componentStyle,
|
||||
text,
|
||||
buttonType
|
||||
buttonType,
|
||||
adGroupId = game?.adGroupId ?: "",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ class CommonContentCollection12Ui(
|
||||
collection: CustomPageData.CommonContentCollection,
|
||||
leftPosition: Int
|
||||
) {
|
||||
|
||||
val data = collection.data
|
||||
|
||||
val isFirstLine = leftPosition == 0
|
||||
@ -43,7 +42,6 @@ class CommonContentCollection12Ui(
|
||||
listener.navigateToCommonCollectionDetailPage(collection)
|
||||
}
|
||||
|
||||
|
||||
val width = (DisplayUtils.getScreenWidth() - 16F.dip2px() * 2 - 8F.dip2px()) / 2
|
||||
val height = if (collection.layout == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD) {
|
||||
width * 4 / 3
|
||||
@ -54,7 +52,6 @@ class CommonContentCollection12Ui(
|
||||
val leftBinding = CommonCollectionItemBinding.bind(binding.leftView.root)
|
||||
val rightBinding = CommonCollectionItemBinding.bind(binding.rightView.root)
|
||||
|
||||
|
||||
bindSubView(
|
||||
data[leftPosition],
|
||||
leftBinding,
|
||||
@ -94,7 +91,6 @@ class CommonContentCollection12Ui(
|
||||
with(binding.root) {
|
||||
setPadding(paddingLeft, paddingTop, paddingRight, _paddingBottom)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun bindSubView(
|
||||
|
||||
@ -62,10 +62,6 @@ class CommonContentHomeSLideListUi(
|
||||
layoutManager,
|
||||
false,
|
||||
object : CustomHomeSlideListAdapter.OnEventListener {
|
||||
override fun createExposureEvent(actualPosition: Int, game: GameEntity?): ExposureEvent? {
|
||||
return listener.createExposureEvent(actualPosition, game)
|
||||
}
|
||||
|
||||
override fun navigateToGameDetailPage(
|
||||
actualPosition: Int,
|
||||
game: GameEntity,
|
||||
@ -78,7 +74,6 @@ class CommonContentHomeSLideListUi(
|
||||
override fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?) {
|
||||
listener.navigateToLinkPage(link, text, exposureEvent)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -277,13 +272,10 @@ class CommonContentHomeSLideListUi(
|
||||
}
|
||||
|
||||
interface OnCommonHomeSlideListEventListener {
|
||||
|
||||
fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
|
||||
|
||||
fun navigateToGameDetailPage(position: Int, game: GameEntity, text: String, link: LinkEntity?)
|
||||
|
||||
fun updateImmersiveColor(color: Int)
|
||||
|
||||
fun createExposureEvent(childPosition: Int, game: GameEntity?): ExposureEvent?
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,7 @@ import androidx.viewpager2.widget.ViewPager2
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.FixLinearLayoutManager
|
||||
import com.gh.gamecenter.common.view.ScrollEventListener
|
||||
@ -43,9 +44,11 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
private val useCase: CommonContentCollectionUseCase,
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
val binding: HomeSlideWithCardsCustomBinding,
|
||||
private val listener: HomeSLideWithCardsEventListener
|
||||
private val refreshCount: Int,
|
||||
private val basicExposureSource: List<ExposureSource> ? = null,
|
||||
private val pageLevelString: String,
|
||||
private val listener: HomeSLideWithCardsEventListener,
|
||||
) {
|
||||
|
||||
private var collection: CustomPageData.CommonContentCollection? = null
|
||||
|
||||
private val context: Context
|
||||
@ -59,7 +62,6 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
PagerSnapHelper()
|
||||
}
|
||||
|
||||
|
||||
private val adapter by lazy {
|
||||
CustomHomeSlideListAdapter(
|
||||
context,
|
||||
@ -67,10 +69,6 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
layoutManager,
|
||||
true,
|
||||
object : CustomHomeSlideListAdapter.OnEventListener {
|
||||
override fun createExposureEvent(actualPosition: Int, game: GameEntity?): ExposureEvent? {
|
||||
return listener.createExposureEvent(actualPosition, game)
|
||||
}
|
||||
|
||||
override fun navigateToGameDetailPage(
|
||||
actualPosition: Int,
|
||||
game: GameEntity,
|
||||
@ -83,7 +81,6 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
override fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?) {
|
||||
listener.navigateToLinkPage(link, text, exposureEvent)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -115,13 +112,11 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
if (collection.slides.subSlide.isNotEmpty()) {
|
||||
bindCards(collection, collection.slides.subSlide)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun bindSlide(
|
||||
slideList: List<HomeSlide>
|
||||
) {
|
||||
|
||||
if (binding.recyclerView.adapter == null) {
|
||||
binding.recyclerView.layoutManager = layoutManager
|
||||
binding.recyclerView.adapter = adapter
|
||||
@ -227,14 +222,12 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
?: com.gh.gamecenter.common.R.color.ui_surface.toColor(binding.root.context)
|
||||
)
|
||||
|
||||
|
||||
binding.bannerIndicator.run {
|
||||
pageSize = adapter.getActualSize()
|
||||
notifyDataChanged()
|
||||
}
|
||||
|
||||
bannerController.start()
|
||||
|
||||
}
|
||||
|
||||
private fun bindCards(
|
||||
@ -337,8 +330,6 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
}
|
||||
|
||||
homeSubSlide.cardData.games.take(3).forEachIndexed { index, gameEntity ->
|
||||
listener.addGameExposureEvent(position, gameEntity, homeSubSlide.id)
|
||||
|
||||
when (index) {
|
||||
0 -> gameIconIv1.setGame(index, gameEntity)
|
||||
|
||||
@ -348,6 +339,31 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ((index, game) in homeSubSlide.cardData.games.take(3).withIndex()) {
|
||||
game.pageLevelString = pageLevelString
|
||||
game.exposureEvent = ExposureEvent.createEventWithSourceConcat(
|
||||
gameEntity = game.apply {
|
||||
sequence = index
|
||||
outerSequence = refreshCount
|
||||
},
|
||||
basicSource = basicExposureSource ?: arrayListOf(),
|
||||
source = listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${data.name}+${data.layoutChinese}+${data.id}"
|
||||
),
|
||||
ExposureSource("右侧卡片", homeSubSlide.id)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cardCv.setExposureEventList(
|
||||
homeSubSlide.cardData.games.mapNotNull { gameEntity ->
|
||||
gameEntity.exposureEvent
|
||||
}
|
||||
)
|
||||
|
||||
countTv.isVisible = homeSubSlide.cardData.gameTotal.game > 3
|
||||
countTv.typeface = Typeface.createFromAsset(countTv.context.assets, Constants.DIN_FONT_PATH)
|
||||
countTv.text = "+${homeSubSlide.cardData.gameTotal.game - 3}"
|
||||
@ -408,17 +424,10 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
connect(textContainer.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
|
||||
connect(textContainer.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
|
||||
}.applyTo(cardContainer)
|
||||
listener.addGameExposureEvent(
|
||||
position,
|
||||
GameEntity(sequence = position, outerSequence = useCase.refreshCount),
|
||||
homeSubSlide.id
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cardCv.setOnClickListener {
|
||||
|
||||
com.gh.common.util.NewFlatLogUtils.logRightSideCardClick(homeSubSlide, useCase.refreshCount, "卡片")
|
||||
listener.navigateToLinkPageInSubSlide(
|
||||
GameEntity(sequence = position, outerSequence = useCase.refreshCount),
|
||||
@ -481,12 +490,6 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
interface HomeSLideWithCardsEventListener {
|
||||
fun updateImmersiveColor(color: Int)
|
||||
|
||||
fun createEventWithSourceConcat(game: GameEntity, subSlideId: String)
|
||||
|
||||
fun createExposureEvent(actualPosition: Int, game: GameEntity?): ExposureEvent?
|
||||
|
||||
fun addGameExposureEvent(position: Int, game: GameEntity, subSlideId: String)
|
||||
|
||||
fun navigateToGameDetailPage(childPosition: Int, gameEntity: GameEntity, text: String, link: LinkEntity?)
|
||||
|
||||
fun navigateToLinkPageInSubSlide(game: GameEntity, homeSubSlide: HomeSubSlide, text: String)
|
||||
|
||||
@ -40,9 +40,7 @@ class CommonContentHorizontalSlideListUi(
|
||||
override fun onChildItemClick(childPosition: Int, item: CommonCollectionContentEntity) {
|
||||
listener.onChildItemClick(childPosition, item)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
fun bind(data: CustomPageData.CommonContentCollection) {
|
||||
@ -99,7 +97,6 @@ class CommonContentHorizontalSlideListUi(
|
||||
}
|
||||
|
||||
interface OnHorizontalSlideListListener {
|
||||
|
||||
fun addExposureEvent(childPosition: Int, link: ExposureLinkEntity)
|
||||
|
||||
fun onChildItemClick(childPosition: Int, entity: CommonCollectionContentEntity)
|
||||
|
||||
@ -24,16 +24,13 @@ class CommonContentNavigationUi(
|
||||
|
||||
private val adapter by lazy {
|
||||
CustomGameNavigationAdapter(context, object : CustomGameNavigationAdapter.OnEventListener {
|
||||
|
||||
override fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?) {
|
||||
listener.navigateToLinkPage(link, text, exposureEvent)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
fun bind(navigationList: List<GameNavigationEntity>?, trackEventList: List<ExposureEvent>?) {
|
||||
|
||||
if (binding.rvNavigation.adapter == null) {
|
||||
binding.rvNavigation.layoutManager = layoutManager
|
||||
binding.rvNavigation.addItemDecoration(GridSpacingItemDecoration(4, 8f.dip2px(), false, 16f.dip2px()))
|
||||
@ -42,14 +39,11 @@ class CommonContentNavigationUi(
|
||||
}
|
||||
|
||||
if (!navigationList.isNullOrEmpty()) {
|
||||
|
||||
adapter.setData(navigationList, trackEventList)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface OnNavigationListener {
|
||||
|
||||
fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,6 @@ class CommonContentRecommendUi(
|
||||
override fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?) {
|
||||
listener.navigateToLinkPage(link, text, exposureEvent)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -59,7 +58,6 @@ class CommonContentRecommendUi(
|
||||
}
|
||||
binding.recommendGv.adapter = adapter
|
||||
adapter.submitList(filteredList, spanCount, exposureList)
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -54,11 +54,8 @@ class RecommendCardUi(
|
||||
}
|
||||
|
||||
interface OnRecommendCardEventListener {
|
||||
|
||||
fun onItemClick(childPosition: Int, card: CustomPageData.RecommendCard)
|
||||
|
||||
fun onItemExposure(childPosition: Int, card: CustomPageData.RecommendCard)
|
||||
|
||||
fun onAllClick()
|
||||
}
|
||||
}
|
||||
@ -4,14 +4,17 @@ import android.view.View
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.databinding.LayoutTitleCustomBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
@ -102,6 +105,28 @@ abstract class BaseCustomViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
fun fillExposureInfoAndReportAd(gameEntity: GameEntity, sequence: Int, item: CustomPageItem) {
|
||||
gameEntity.pageLevelString = pageLocation.pageLevelString
|
||||
gameEntity.sequence = sequence
|
||||
gameEntity.outerSequence = item.componentPosition
|
||||
if (item is CustomSplitSubjectItem || item is CustomSplitSubjectItem) {
|
||||
gameEntity.isAdData = item.data.adIconActive
|
||||
}
|
||||
gameEntity.outerSequence = item.componentPosition
|
||||
gameEntity.customPageTrackData = createTrackData(item)
|
||||
gameEntity.exposureSource = ArrayList<ExposureSource>().apply {
|
||||
addAll(pageConfigure.exposureSourceList)
|
||||
if (item is CustomSplitSubjectItem || item is CustomSplitSubjectItem) {
|
||||
addAll(item.exposureSource)
|
||||
}
|
||||
}
|
||||
|
||||
if (!gameEntity.adGroupId.isEmpty() && gameEntity.isAdRequestReported == false) {
|
||||
AdHelper.reportAdRequest(gameEntity)
|
||||
gameEntity.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
|
||||
private val _title = TitleData()
|
||||
|
||||
// 专题标题
|
||||
@ -320,7 +345,6 @@ abstract class BaseCustomViewHolder(
|
||||
lavRefresh.setAnimation(if (DarkModeUtils.isDarkModeOn(root.context)) "lottie/icon_title_change_dark.json" else "lottie/icon_title_change_light.json")
|
||||
lavRefresh.progress = 0F
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.RecyclerContentLabelLaneCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
@ -10,6 +11,7 @@ import com.gh.gamecenter.home.custom.adapter.ContentLabelLaneAdapter
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.CommonContentCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomCommonContentCollectionItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData.CommonContentCollection.ContentTag
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
|
||||
/**
|
||||
@ -25,59 +27,59 @@ class ContentLabelLaneViewHolder(
|
||||
}
|
||||
|
||||
private val adapter by lazy {
|
||||
ContentLabelLaneAdapter(itemView.context,
|
||||
{ index, contentTag ->
|
||||
childEventHelper.navigateToLinkPage(
|
||||
contentTag.link,
|
||||
"内容标签泳道",
|
||||
_item.exposureEventList.getOrNull(index)
|
||||
)
|
||||
},
|
||||
{ index, contentTag ->
|
||||
|
||||
val item = _item as CustomCommonContentCollectionItem
|
||||
val gameEntity = if (contentTag.linkType == "game") {
|
||||
GameEntity(id = contentTag.linkId, name = contentTag.linkText)
|
||||
} else {
|
||||
GameEntity()
|
||||
}
|
||||
_item.exposureEventList.add(
|
||||
createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = index
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${item.data.name}+${item.data.layoutChinese}+${item.data.id}"
|
||||
),
|
||||
ExposureSource(
|
||||
item.data.layoutChinese,
|
||||
"${contentTag.title}+${contentTag.id}"
|
||||
)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
)
|
||||
|
||||
})
|
||||
ContentLabelLaneAdapter(itemView.context) { index, contentTag ->
|
||||
childEventHelper.navigateToLinkPage(
|
||||
contentTag.link,
|
||||
"内容标签泳道",
|
||||
contentTag.exposureEvent
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomCommonContentCollectionItem) {
|
||||
item.exposureEventList.clear()
|
||||
val contentTags = item.data.contentTags
|
||||
if (binding.rvGames.adapter == null) {
|
||||
binding.rvGames.layoutManager = LinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false)
|
||||
binding.rvGames.adapter = adapter
|
||||
}
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureInfo(item.data.contentTags)
|
||||
}
|
||||
adapter.submitList(contentTags)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureInfo(contentTags: List<ContentTag>) {
|
||||
for ((index, contentTag) in contentTags.withIndex()) {
|
||||
val item = _item as CustomCommonContentCollectionItem
|
||||
val gameEntity = if (contentTag.linkType == "game") {
|
||||
GameEntity(id = contentTag.linkId, name = contentTag.linkText)
|
||||
} else {
|
||||
GameEntity()
|
||||
}
|
||||
contentTag.exposureEvent = createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = index
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${item.data.name}+${item.data.layoutChinese}+${item.data.id}"
|
||||
),
|
||||
ExposureSource(
|
||||
item.data.layoutChinese,
|
||||
"${contentTag.title}+${contentTag.id}"
|
||||
)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,8 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.RecyclerAnnouncementBannerBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.home.custom.BannerInRecyclerController
|
||||
@ -31,44 +31,13 @@ class CustomAnnouncementBannerViewHolder(
|
||||
childEventHelper.navigateToLinkPage(
|
||||
announcement.link,
|
||||
"公告横幅",
|
||||
_item.exposureEventList.getOrNull(childPosition)
|
||||
announcement.exposureEvent
|
||||
)
|
||||
}
|
||||
|
||||
override fun getCurrentPosition(): Int {
|
||||
return binding.vpBanner.currentItem
|
||||
}
|
||||
|
||||
override fun exposure(childPosition: Int, announcement: CustomPageData.Announcement) {
|
||||
val item = _item as CustomCommonContentCollectionItem
|
||||
val gameEntity = if (announcement.linkType == "game") {
|
||||
GameEntity(id = announcement.linkId, name = announcement.linkText)
|
||||
} else {
|
||||
GameEntity()
|
||||
}
|
||||
_item.exposureEventList.add(
|
||||
createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = childPosition
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${item.data.name}+${item.data.layoutChinese}+${item.data.id}"
|
||||
),
|
||||
ExposureSource(
|
||||
item.data.layoutChinese
|
||||
)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
childPosition,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -78,7 +47,6 @@ class CustomAnnouncementBannerViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val childEventHelper by lazy {
|
||||
CommonContentCollectionEventHelper(viewModel)
|
||||
}
|
||||
@ -89,12 +57,10 @@ class CustomAnnouncementBannerViewHolder(
|
||||
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
_item.exposureEventList.clear()
|
||||
if (item is CustomCommonContentCollectionItem) {
|
||||
if (binding.vpBanner.adapter == null) {
|
||||
binding.vpBanner.adapter = adapter
|
||||
binding.vpBanner.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
binding.bannerIndicator.onPageScrolled(adapter.getDataPosition(position), positionOffset)
|
||||
}
|
||||
@ -105,8 +71,12 @@ class CustomAnnouncementBannerViewHolder(
|
||||
bannerInRecyclerController.start()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureInfo(item.data.announcements)
|
||||
}
|
||||
|
||||
adapter.submitList(item.data.announcements)
|
||||
if (item.selectedPosition != 0) {
|
||||
binding.vpBanner.setCurrentItem(item.selectedPosition, false)
|
||||
@ -118,6 +88,31 @@ class CustomAnnouncementBannerViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureInfo(dataList: List<CustomPageData.Announcement>) {
|
||||
for ((index, announcement) in dataList.withIndex()) {
|
||||
val item = _item as CustomCommonContentCollectionItem
|
||||
val gameEntity = if (announcement.linkType == "game") {
|
||||
GameEntity(id = announcement.linkId, name = announcement.linkText)
|
||||
} else {
|
||||
GameEntity()
|
||||
}
|
||||
announcement.exposureEvent = createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = index
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource("通用内容合集", "${item.data.name}+${item.data.layoutChinese}+${item.data.id}"),
|
||||
ExposureSource(item.data.layoutChinese)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewAttach(parent: RecyclerView?) {
|
||||
bannerInRecyclerController.onViewAttachedToWindow(parent)
|
||||
}
|
||||
|
||||
@ -1,27 +1,20 @@
|
||||
package com.gh.gamecenter.home.custom.viewholder
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.exposure.ExposureTraceUtils
|
||||
import com.gh.common.util.NewLogUtils
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.CommonCollection12ItemCustomBinding
|
||||
import com.gh.gamecenter.databinding.CommonCollectionItemBinding
|
||||
import com.gh.gamecenter.entity.CommonCollectionContentEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.CommonContentCollectionEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitCommonContentCollectionItem
|
||||
import com.gh.gamecenter.home.custom.ui.CommonContentCollection12Ui
|
||||
|
||||
@ -32,8 +25,9 @@ import com.gh.gamecenter.home.custom.ui.CommonContentCollection12Ui
|
||||
class CustomCommonCollection12ViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
val binding: CommonCollection12ItemCustomBinding
|
||||
) :
|
||||
BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root), IExposureListProvider {
|
||||
|
||||
private var exposureEventList = arrayListOf<ExposureEvent>()
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
CommonContentCollectionEventHelper(viewModel)
|
||||
@ -69,7 +63,7 @@ class CustomCommonCollection12ViewHolder(
|
||||
"板块",
|
||||
"blockData?.name"
|
||||
)
|
||||
item.exposureEventList.getOrNull(childPosition)?.let {
|
||||
linkEntity.exposureEvent?.let {
|
||||
val clickEvent = ExposureEvent(
|
||||
payload = it.payload,
|
||||
source = it.source,
|
||||
@ -83,45 +77,45 @@ class CustomCommonCollection12ViewHolder(
|
||||
childEventHelper.navigateToLinkPage(
|
||||
linkEntity,
|
||||
"内容卡片",
|
||||
item.exposureEventList.getOrNull(childPosition)
|
||||
linkEntity.exposureEvent
|
||||
)
|
||||
}
|
||||
|
||||
override fun navigateToCommonCollectionDetailPage(collection: CustomPageData.CommonContentCollection) {
|
||||
childEventHelper.navigateToCommonCollectionDetailPage(_item.link)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSplitCommonContentCollectionItem) {
|
||||
|
||||
item.exposureEventList.clear()
|
||||
|
||||
val data = item.data.data
|
||||
val leftPosition = item.leftPosition
|
||||
addExposureEvent(leftPosition, data[leftPosition])
|
||||
val firstExposureEvent = addExposureEvent(leftPosition, data[leftPosition])
|
||||
firstExposureEvent?.let {
|
||||
exposureEventList.add(0, firstExposureEvent)
|
||||
}
|
||||
|
||||
val rightPosition = item.leftPosition + 1
|
||||
if (rightPosition < data.size) {
|
||||
addExposureEvent(rightPosition, data[rightPosition])
|
||||
val secondExposureEvent = addExposureEvent(rightPosition, data[rightPosition])
|
||||
secondExposureEvent?.let {
|
||||
exposureEventList.add(1, secondExposureEvent)
|
||||
}
|
||||
}
|
||||
item.isFirstLine
|
||||
collection12Ui.bind(item.data, item.leftPosition)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun addExposureEvent(childPosition: Int, contentEntity: CommonCollectionContentEntity) {
|
||||
private fun addExposureEvent(childPosition: Int, contentEntity: CommonCollectionContentEntity): ExposureEvent? {
|
||||
(_item as? CustomSplitCommonContentCollectionItem)?.let { item ->
|
||||
val gameEntity = if (contentEntity.linkEntity.type == "game") {
|
||||
GameEntity(id = contentEntity.linkEntity.link, name = contentEntity.linkEntity.text)
|
||||
} else {
|
||||
GameEntity()
|
||||
}
|
||||
val event = createExposureEvent(
|
||||
return createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = childPosition
|
||||
it.outerSequence = item.position
|
||||
@ -136,58 +130,14 @@ class CustomCommonCollection12ViewHolder(
|
||||
childPosition,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
|
||||
).also { contentEntity.linkEntity.exposureEvent = it }
|
||||
item.exposureEventList.add(event)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun bindSubView(
|
||||
contentEntity: CommonCollectionContentEntity,
|
||||
subBinding: CommonCollectionItemBinding,
|
||||
layout: Int,
|
||||
width: Int,
|
||||
height: Int,
|
||||
position: Int,
|
||||
clickClosure: (position: Int, contentEntity: CommonCollectionContentEntity) -> Unit
|
||||
) {
|
||||
subBinding.run {
|
||||
ImageUtils.display(commonCollectionImage, contentEntity.image)
|
||||
maskView.goneIf(layout == COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT || (contentEntity.title.isEmpty() && contentEntity.addedContent1.isNullOrEmpty()))
|
||||
titleTv.goneIf(layout == COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT) {
|
||||
titleTv.text = contentEntity.title
|
||||
}
|
||||
desTv.goneIf(layout != COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD) {
|
||||
desTv.text = contentEntity.addedContent1
|
||||
}
|
||||
linkTitleTv.goneIf(layout != COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT) {
|
||||
linkTitleTv.text = contentEntity.title
|
||||
}
|
||||
linkDes1.goneIf(layout != COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT) {
|
||||
linkDes1.text = contentEntity.addedContent1
|
||||
linkDes1.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(root.context))
|
||||
}
|
||||
linkDes2.goneIf(layout != COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT) {
|
||||
linkDes2.text = contentEntity.addedContent2
|
||||
linkDes2.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(root.context))
|
||||
}
|
||||
|
||||
val maskHeight = if (layout == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD) {
|
||||
60f.dip2px()
|
||||
} else {
|
||||
38f.dip2px()
|
||||
}
|
||||
val maskParams = maskView.layoutParams as ConstraintLayout.LayoutParams
|
||||
maskParams.height = maskHeight
|
||||
maskView.layoutParams = maskParams
|
||||
|
||||
val imageParams = commonCollectionImage.layoutParams as ConstraintLayout.LayoutParams
|
||||
imageParams.width = width
|
||||
imageParams.height = height
|
||||
commonCollectionImage.layoutParams = imageParams
|
||||
|
||||
root.setOnClickListener { clickClosure.invoke(position, contentEntity) }
|
||||
}
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
return exposureEventList
|
||||
}
|
||||
|
||||
}
|
||||
@ -31,7 +31,6 @@ class CustomCommonCollectionViewHolder(
|
||||
val binding: CommonCollectionListCustomBinding,
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
CommonContentCollectionEventHelper(viewModel)
|
||||
}
|
||||
@ -43,26 +42,23 @@ class CustomCommonCollectionViewHolder(
|
||||
(_item as? CustomCommonContentCollectionItem)?.let { item ->
|
||||
val gameEntity =
|
||||
if (link.type == "game") GameEntity(id = link.link, name = link.text) else GameEntity()
|
||||
_item.exposureEventList.add(
|
||||
createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = childPosition
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${item.data.name}+${item.data.layoutChinese}+${item.data.id}"
|
||||
)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
childPosition,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
).also { link.exposureEvent = it }
|
||||
)
|
||||
createExposureEvent(
|
||||
gameEntity.also {
|
||||
it.sequence = childPosition
|
||||
it.outerSequence = _item.position
|
||||
},
|
||||
listOf(
|
||||
ExposureSource(
|
||||
"通用内容合集",
|
||||
"${item.data.name}+${item.data.layoutChinese}+${item.data.id}"
|
||||
)
|
||||
),
|
||||
pageConfigure.exposureSourceList,
|
||||
childPosition,
|
||||
_item.componentPosition,
|
||||
createTrackData(item)
|
||||
).also { link.exposureEvent = it }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onChildItemClick(childPosition: Int, entity: CommonCollectionContentEntity) {
|
||||
@ -108,30 +104,25 @@ class CustomCommonCollectionViewHolder(
|
||||
childEventHelper.navigateToLinkPage(
|
||||
linkEntity,
|
||||
"内容卡片",
|
||||
(_item as CustomCommonContentCollectionItem).exposureEventList.getOrNull(childPosition)
|
||||
linkEntity.exposureEvent
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun navigateToCommonCollectionDetailPage(data: CustomPageData.CommonContentCollection) {
|
||||
childEventHelper.navigateToCommonCollectionDetailPage(_item.link)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomCommonContentCollectionItem) {
|
||||
item.exposureEventList.clear()
|
||||
horizontalSlideUi.bind(item.data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun setTitle(
|
||||
data: CustomPageData.CommonContentCollection,
|
||||
layoutTitle: LayoutTitleCustomBinding,
|
||||
|
||||
@ -11,9 +11,9 @@ import com.gh.gamecenter.databinding.GameDoubleCardItemAlCustomBinding
|
||||
import com.gh.gamecenter.databinding.GameDoubleCardItemCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
@ -25,10 +25,13 @@ import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
class CustomDoubleCardViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
val binding: GameDoubleCardItemAlCustomBinding
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root), IExposureListProvider {
|
||||
|
||||
private val mPosterWidth = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 2
|
||||
|
||||
private var leftBoundedGameEntity: GameEntity? = null
|
||||
private var rightBoundedGameEntity: GameEntity? = null
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
SubjectEventHelper(viewModel)
|
||||
}
|
||||
@ -36,10 +39,11 @@ class CustomDoubleCardViewHolder(
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSplitSubjectItem) {
|
||||
|
||||
val gameList = item.data.data ?: return
|
||||
|
||||
fillExposureList(item)
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureInfoAndReportAd(item)
|
||||
}
|
||||
|
||||
setSplitSubjectTitle(binding.layoutTitle, item, childEventHelper)
|
||||
|
||||
@ -59,16 +63,16 @@ class CustomDoubleCardViewHolder(
|
||||
itemView.layoutParams = it
|
||||
}
|
||||
|
||||
|
||||
val leftPosition = item.startChildPosition
|
||||
|
||||
val rightPosition = leftPosition + 1
|
||||
|
||||
val hasLeft = gameList.size > leftPosition
|
||||
if (hasLeft) {
|
||||
leftBoundedGameEntity = gameList[leftPosition]
|
||||
bindSubView(
|
||||
item,
|
||||
gameList[leftPosition],
|
||||
leftBoundedGameEntity!!,
|
||||
binding.leftCardView,
|
||||
leftPosition
|
||||
)
|
||||
@ -76,15 +80,16 @@ class CustomDoubleCardViewHolder(
|
||||
|
||||
val hasRight = gameList.size > rightPosition
|
||||
if (hasRight) {
|
||||
rightBoundedGameEntity = gameList[rightPosition]
|
||||
binding.rightCardView.posterCardView.visibility = View.VISIBLE
|
||||
bindSubView(
|
||||
item,
|
||||
gameList[rightPosition],
|
||||
rightBoundedGameEntity!!,
|
||||
binding.rightCardView,
|
||||
rightPosition
|
||||
)
|
||||
|
||||
} else {
|
||||
rightBoundedGameEntity = null
|
||||
binding.rightCardView.posterCardView.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
@ -121,24 +126,27 @@ class CustomDoubleCardViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureList(item: CustomSplitSubjectItem) {
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
for (i in item.startChildPosition..item.endChildPosition) {
|
||||
val game = item.data.data?.getOrNull(i) ?: break
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.exposureEvent = event
|
||||
eventList.add(event)
|
||||
}
|
||||
private fun fillExposureInfoAndReportAd(item: CustomSplitSubjectItem) {
|
||||
for (i in item.startChildPosition..item.endChildPosition) {
|
||||
val game = item.data.data?.getOrNull(i) ?: break
|
||||
|
||||
fillExposureInfoAndReportAd(game, i, item)
|
||||
}
|
||||
item.exposureEventList = eventList
|
||||
}
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
val gameEntityList = arrayListOf<GameEntity?>().apply {
|
||||
leftBoundedGameEntity?.let { add(leftBoundedGameEntity) }
|
||||
rightBoundedGameEntity?.let { add(rightBoundedGameEntity) }
|
||||
}
|
||||
|
||||
for (gameEntity in gameEntityList) {
|
||||
gameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
}
|
||||
|
||||
return gameEntityList.mapNotNull { it?.exposureEvent }
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
|
||||
}
|
||||
@ -5,6 +5,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.marginStart
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
@ -15,6 +16,7 @@ import com.gh.gamecenter.databinding.GameDoubleWelfareCardCustomBinding
|
||||
import com.gh.gamecenter.databinding.RecyclerDoubleWelfareCardCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
@ -27,7 +29,9 @@ import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
class CustomDoubleWelfareCardViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
val binding: RecyclerDoubleWelfareCardCustomBinding
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root), IExposureListProvider {
|
||||
|
||||
private var exposureEventList: ArrayList<ExposureEvent>? = arrayListOf()
|
||||
|
||||
private val posterWidth by lazy {
|
||||
(itemView.context.resources.displayMetrics.widthPixels - 40F.dip2px()) / 2
|
||||
@ -42,7 +46,9 @@ class CustomDoubleWelfareCardViewHolder(
|
||||
if (item is CustomSplitSubjectItem) {
|
||||
val gameList = item.data.data ?: return
|
||||
|
||||
fillExposureList(item)
|
||||
runOnIoThread(true) {
|
||||
fillExposureList(item)
|
||||
}
|
||||
|
||||
setSplitSubjectTitle(binding.layoutTitle, item, childEventHelper)
|
||||
|
||||
@ -62,9 +68,7 @@ class CustomDoubleWelfareCardViewHolder(
|
||||
itemView.layoutParams = it
|
||||
}
|
||||
|
||||
|
||||
val leftPosition = item.startChildPosition
|
||||
|
||||
val rightPosition = leftPosition + 1
|
||||
|
||||
val hasLeft = gameList.size > leftPosition
|
||||
@ -151,7 +155,6 @@ class CustomDoubleWelfareCardViewHolder(
|
||||
root.setOnClickListener {
|
||||
childEventHelper.navigateToGameDetailPage(position, gameEntity)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,22 +173,34 @@ class CustomDoubleWelfareCardViewHolder(
|
||||
}
|
||||
|
||||
private fun fillExposureList(item: CustomSplitSubjectItem) {
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
for (i in item.startChildPosition..item.endChildPosition) {
|
||||
val game = item.data.data?.getOrNull(i) ?: break
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.exposureEvent = event
|
||||
eventList.add(event)
|
||||
exposureEventList = arrayListOf<ExposureEvent>()
|
||||
for (i in item.startChildPosition..item.endChildPosition) {
|
||||
val game = item.data.data?.getOrNull(i) ?: break
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.exposureEvent = event
|
||||
|
||||
if (!game.adGroupId.isEmpty() && !game.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(game.exposureEvent!!)
|
||||
game.isAdRequestReported = true
|
||||
}
|
||||
|
||||
exposureEventList?.add(event)
|
||||
}
|
||||
item.exposureEventList = eventList
|
||||
}
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
exposureEventList?.forEach {
|
||||
it.getRefreshedExposureEvent()
|
||||
}
|
||||
return exposureEventList
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
}
|
||||
@ -8,12 +8,11 @@ import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.view.stacklayoutmanager2.StackAnimation2
|
||||
import com.gh.gamecenter.common.view.stacklayoutmanager2.StackLayoutManagerV2
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.RecyclerFoldSlideLargeImageCustomBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomFoldSlideLargeImageItemAdapter
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -46,14 +45,14 @@ class CustomFoldSlideLargeImageViewHolder(
|
||||
private val onScrollListener = object : OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
if (newState == SCROLL_STATE_IDLE) {
|
||||
showBubble(layoutManager.selectedPosition)
|
||||
updateTopViewHolder(layoutManager.selectedPosition)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
if (dy == 0) {
|
||||
showBubble(layoutManager.selectedPosition)
|
||||
updateTopViewHolder(layoutManager.selectedPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,15 +63,14 @@ class CustomFoldSlideLargeImageViewHolder(
|
||||
binding.recyclerView.isNestedScrollingEnabled = false
|
||||
layoutManager.setOnItemSelectedListener(object : StackLayoutManagerV2.OnStackListener {
|
||||
override fun onSelectedPositionChanged(position: Int) {
|
||||
showBubble(position)
|
||||
updateTopViewHolder(position)
|
||||
}
|
||||
|
||||
override fun onScrollStateChanged(isScrolling: Boolean) = Unit
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
private fun showBubble(position: Int) {
|
||||
private fun updateTopViewHolder(position: Int) {
|
||||
val viewHolder = binding.recyclerView.findViewHolderForAdapterPosition(position)
|
||||
if (topViewHolder != viewHolder) {
|
||||
topViewHolder?.dismissBubble()
|
||||
@ -89,13 +87,18 @@ class CustomFoldSlideLargeImageViewHolder(
|
||||
|
||||
setSubjectTitle(binding.layoutTitle, item, childEventHelper)
|
||||
|
||||
fillExposureEventList(item)
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
item.data.data?.forEachIndexed { index, game ->
|
||||
fillExposureInfoAndReportAd(game, index, item)
|
||||
}
|
||||
}
|
||||
|
||||
if (binding.recyclerView.adapter == null) {
|
||||
binding.recyclerView.layoutManager = layoutManager
|
||||
binding.recyclerView.adapter = adapter
|
||||
}
|
||||
adapter.setData(item)
|
||||
|
||||
if (isInit) {
|
||||
isInit = false
|
||||
binding.recyclerView.scrollToPosition(adapter.getInitPosition())
|
||||
@ -103,22 +106,6 @@ class CustomFoldSlideLargeImageViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureEventList(item: CustomSubjectItem) {
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
item.data.data?.forEachIndexed { index, game ->
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
eventList.add(event)
|
||||
}
|
||||
item.exposureEventList = eventList
|
||||
}
|
||||
|
||||
override fun onViewAttach(parent: RecyclerView?) {
|
||||
parent?.addOnScrollListener(onScrollListener)
|
||||
}
|
||||
|
||||
@ -2,12 +2,10 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.DarkModeUtils
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.GameVerticalSlideItemCustomBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.game.vertical.OnPagerSnapScrollListener
|
||||
import com.gh.gamecenter.game.vertical.SpanCountPagerSnapHelper
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
@ -74,55 +72,9 @@ class CustomGameCollectionRefreshVerticalSlideViewHolder(
|
||||
val games = subjectEntity.games
|
||||
spanCount = if (games.size < 3) games.size else 3
|
||||
|
||||
val listExposureEventList = arrayListOf<ExposureEvent>()
|
||||
val exposureEventList = arrayListOf<ExposureEvent>()
|
||||
val exposureClosure: (Int) -> Unit = {
|
||||
runOnIoThread(true) {
|
||||
listExposureEventList.clear()
|
||||
|
||||
val source = if (item.isSubjectCollection) {
|
||||
listOf(
|
||||
ExposureSource("专题合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
|
||||
ExposureSource(
|
||||
"专题",
|
||||
"${subjectEntity.title}+${subjectEntity.styleChinese}+${subjectEntity.id}"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
ExposureSource("游戏单合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
|
||||
ExposureSource("游戏单", "${subjectEntity.title}+${subjectEntity.id}")
|
||||
)
|
||||
}
|
||||
|
||||
val startOffset = it * spanCount
|
||||
val endOffset = if (startOffset + spanCount >= games.size) {
|
||||
games.size
|
||||
} else {
|
||||
startOffset + spanCount
|
||||
}
|
||||
for (i in startOffset until endOffset) {
|
||||
val game = games.getOrNull(i) ?: break
|
||||
game.isAdData = subjectEntity.adIconActive
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
source,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
|
||||
listExposureEventList.add(event)
|
||||
}
|
||||
exposureEventList.addAll(listExposureEventList)
|
||||
}
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureInfo(item, subjectEntity)
|
||||
}
|
||||
item.exposureEventList = exposureEventList
|
||||
|
||||
exposureClosure(0)
|
||||
|
||||
|
||||
if (binding.recyclerView.adapter == null) {
|
||||
binding.recyclerView.clearOnScrollListeners()
|
||||
@ -132,9 +84,6 @@ class CustomGameCollectionRefreshVerticalSlideViewHolder(
|
||||
binding.recyclerView.adapter = adapter
|
||||
snapHelper?.let {
|
||||
it.attachToRecyclerView(binding.recyclerView)
|
||||
binding.recyclerView.addOnScrollListener(OnPagerSnapScrollListener(it) {
|
||||
exposureClosure(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
changeSpanCountIfNeeded()
|
||||
@ -152,6 +101,44 @@ class CustomGameCollectionRefreshVerticalSlideViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureInfo(
|
||||
item: CustomSubjectCollectionItem,
|
||||
subjectEntity: CustomPageData.LinkColumnCollection.CustomSubjectEntity
|
||||
) {
|
||||
val games = subjectEntity.games
|
||||
val source = if (item.isSubjectCollection) {
|
||||
listOf(
|
||||
ExposureSource("专题合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
|
||||
ExposureSource(
|
||||
"专题",
|
||||
"${subjectEntity.title}+${subjectEntity.styleChinese}+${subjectEntity.id}"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
ExposureSource("游戏单合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
|
||||
ExposureSource("游戏单", "${subjectEntity.title}+${subjectEntity.id}")
|
||||
)
|
||||
}
|
||||
|
||||
for ((i, game) in games.withIndex()) {
|
||||
game.isAdData = subjectEntity.adIconActive
|
||||
game.exposureEvent = createExposureEvent(
|
||||
game,
|
||||
source,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
|
||||
if (!game.adGroupId.isEmpty() && !game.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(game.exposureEvent!!)
|
||||
game.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeSpanCountIfNeeded() {
|
||||
binding.recyclerView.run {
|
||||
if (spanCount != (layoutManager as GridLayoutManager).spanCount) {
|
||||
|
||||
@ -14,8 +14,9 @@ import com.gh.gamecenter.databinding.GameGallerySlideItemCustomBinding
|
||||
import com.gh.gamecenter.databinding.ItemWithinGameGallerySlideCustomBinding
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -49,37 +50,23 @@ class CustomGameGallerySlideViewHolder(
|
||||
val rvList =
|
||||
arrayListOf(binding.firstRecyclerView, binding.secondRecyclerView, binding.thirdRecyclerView)
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
cachedSubject?.data?.forEachIndexed { index, gameEntity ->
|
||||
fillExposureInfoAndReportAd(gameEntity, index, item)
|
||||
}
|
||||
}
|
||||
|
||||
for ((index, recyclerView) in rvList.withIndex()) {
|
||||
if (recyclerView.adapter == null) {
|
||||
recyclerView.layoutManager =
|
||||
LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false)
|
||||
recyclerView.adapter =
|
||||
GameGallerySlideAdapter(
|
||||
binding.root.context,
|
||||
index
|
||||
) { childPosition, game ->
|
||||
runOnIoThread(true) {
|
||||
game.sequence = childPosition
|
||||
item.exposureEventList.add(
|
||||
createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
childPosition,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
recyclerView.adapter = GameGallerySlideAdapter(binding.root.context, index)
|
||||
recyclerView.isNestedScrollingEnabled = false
|
||||
}
|
||||
val gameList = item.data.data ?: emptyList()
|
||||
(recyclerView.adapter as? GameGallerySlideAdapter)?.submitList(gameList)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
@ -105,7 +92,6 @@ class CustomGameGallerySlideViewHolder(
|
||||
inner class GameGallerySlideAdapter(
|
||||
context: Context,
|
||||
private val index: Int,
|
||||
private val exposureInvoke: (Int, GameEntity) -> Unit
|
||||
) : BaseRecyclerAdapter<GameGallerySlideAdapter.GameGallerySlideItemViewHolder>(context) {
|
||||
|
||||
private val dataList = arrayListOf<GameEntity>()
|
||||
@ -128,13 +114,15 @@ class CustomGameGallerySlideViewHolder(
|
||||
val realPosition = dataPosition % dataList.size
|
||||
val gameEntity = dataList[realPosition]
|
||||
|
||||
exposureInvoke(realPosition, gameEntity)
|
||||
holder.bindView(realPosition, gameEntity)
|
||||
}
|
||||
|
||||
inner class GameGallerySlideItemViewHolder(val binding: ItemWithinGameGallerySlideCustomBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindView(realPosition: Int, gameEntity: GameEntity) {
|
||||
boundedGameEntity = gameEntity
|
||||
binding.iconIv.displayGameIconWithIfShowSubscript(
|
||||
gameEntity,
|
||||
cachedSubject?.showIndexIconSubscript ?: false
|
||||
@ -143,8 +131,12 @@ class CustomGameGallerySlideViewHolder(
|
||||
childEventHelper.navigateToGameDetailPage(realPosition, gameEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,15 +2,17 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.safelyGetInRelease
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.view.AsyncCell
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.GameGalleryItemCustomBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureListProvider
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.CustomPageItemChildEventHelper
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -21,7 +23,9 @@ import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
class CustomGameGalleryViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
cell: GameGalleryItemCell
|
||||
) : BaseCustomViewHolder(viewModel, cell.rootView) {
|
||||
) : BaseCustomViewHolder(viewModel, cell.rootView), IExposureListProvider {
|
||||
|
||||
private var boundedItem: CustomSubjectItem? = null
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
SubjectEventHelper(viewModel)
|
||||
@ -32,6 +36,7 @@ class CustomGameGalleryViewHolder(
|
||||
if (item is CustomSubjectItem) {
|
||||
val subjectEntity = item.data
|
||||
item.exposureEventList.clear()
|
||||
boundedItem = item
|
||||
(itemView as? GameGalleryItemCell)?.let {
|
||||
it.bindWhenInflated {
|
||||
val binding = it.binding ?: return@bindWhenInflated
|
||||
@ -57,6 +62,7 @@ class CustomGameGalleryViewHolder(
|
||||
val gameEntity = subjectEntity.data?.safelyGetInRelease(index) ?: continue
|
||||
|
||||
gameEntity.subjectId = subjectEntity.id
|
||||
gameEntity.pageLevelString = pageLocation.pageLevelString
|
||||
|
||||
gameIcon.visibility = View.VISIBLE
|
||||
gameIcon.rotation = 35F
|
||||
@ -70,16 +76,20 @@ class CustomGameGalleryViewHolder(
|
||||
}
|
||||
|
||||
runOnIoThread(true) {
|
||||
item.exposureEventList.add(
|
||||
createExposureEvent(
|
||||
gameEntity,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
val exposureEvent = createExposureEvent(
|
||||
gameEntity,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
|
||||
if (!gameEntity.adGroupId.isEmpty() && !gameEntity.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(exposureEvent)
|
||||
gameEntity.isAdRequestReported = true
|
||||
}
|
||||
item.exposureEventList.add(exposureEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,6 +105,18 @@ class CustomGameGalleryViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? = null
|
||||
|
||||
override fun provideExposureDataList(): List<ExposureEvent>? {
|
||||
if (boundedItem?.exposureEventList == null) return null
|
||||
|
||||
for (exposure in boundedItem!!.exposureEventList) {
|
||||
exposure.getRefreshedExposureEvent()
|
||||
}
|
||||
|
||||
return boundedItem?.exposureEventList
|
||||
}
|
||||
|
||||
class GameGalleryItemCell(context: Context) : AsyncCell(context) {
|
||||
var binding: GameGalleryItemCustomBinding? = null
|
||||
|
||||
|
||||
@ -8,10 +8,14 @@ import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.databinding.GameHorizontalItemCustomBinding
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomViewExt
|
||||
|
||||
class CustomGameHorizontalItemViewHolder(val binding: GameHorizontalItemCustomBinding) :
|
||||
BaseRecyclerViewHolder<GameEntity>(binding.root) {
|
||||
class CustomGameHorizontalItemViewHolder(val binding: GameHorizontalItemCustomBinding)
|
||||
: BaseRecyclerViewHolder<GameEntity>(binding.root), IExposureProvider
|
||||
{
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
fun bindGameHorizontalItem(
|
||||
gameEntity: GameEntity,
|
||||
@ -23,6 +27,8 @@ class CustomGameHorizontalItemViewHolder(val binding: GameHorizontalItemCustomBi
|
||||
&& subjectEntity.data?.any { it.commentCount > 3 } ?: false
|
||||
CustomViewExt.setGameRattingWithSubject(binding.gameRating, showStar, gameEntity)
|
||||
|
||||
boundedGameEntity = gameEntity
|
||||
|
||||
binding.firstRemark.text = gameEntity.assignRemark.firstLine
|
||||
binding.firstRemark.setTextColor(
|
||||
if (gameEntity.assignRemark.markedRed) Color.parseColor("#F10000") else com.gh.gamecenter.common.R.color.text_primary.toColor(
|
||||
@ -105,4 +111,9 @@ class CustomGameHorizontalItemViewHolder(val binding: GameHorizontalItemCustomBi
|
||||
binding.lineContainer.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
}
|
||||
@ -3,19 +3,14 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.view.FixLinearLayoutManager
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.databinding.RecyclerHorizontalSlideListCustomBinding
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomGameHorizontalSlideAdapter
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -48,7 +43,6 @@ class CustomGameHorizontalSlideListViewHolder(
|
||||
setSubjectTitle(binding.layoutTitle, item, childEventHelper)
|
||||
val subjectEntity = item.data
|
||||
if (binding.recyclerView.adapter == null) {
|
||||
|
||||
binding.recyclerView.layoutManager =
|
||||
FixLinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false)
|
||||
binding.recyclerView.itemAnimator = null
|
||||
@ -56,7 +50,6 @@ class CustomGameHorizontalSlideListViewHolder(
|
||||
binding.recyclerView.isNestedScrollingEnabled = false
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
|
||||
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
@ -66,7 +59,6 @@ class CustomGameHorizontalSlideListViewHolder(
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if (item.scrolledOffset == 0 && item.firstPositionInHorizontalTimeline != -1) {
|
||||
@ -77,36 +69,21 @@ class CustomGameHorizontalSlideListViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
val exposureEventList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
subjectEntity.data?.let {
|
||||
it.forEachIndexed { index, game ->
|
||||
game.isAdData = subjectEntity.adIconActive
|
||||
game.sequence = index
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
exposureEventList.add(event)
|
||||
fillExposureInfoAndReportAd(game, index, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
item.exposureEventList = exposureEventList
|
||||
|
||||
adapter.setData(item, item.exposureEventList)
|
||||
|
||||
adapter.setData(item)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏专题中 "今天/最靠近今天的一天(未来优先于过去)" 游戏的位置
|
||||
*/
|
||||
|
||||
|
||||
private fun getTopOfLineContainer(vg: ViewGroup): Int {
|
||||
var height = 0
|
||||
for (i in 0 until vg.childCount) {
|
||||
|
||||
@ -11,7 +11,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.therouter.TheRouter
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.DrawableView
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
@ -19,11 +18,12 @@ import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.databinding.GameItemCustomBinding
|
||||
import com.gh.gamecenter.feature.R
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomViewExt
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
@ -35,7 +35,9 @@ import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
class CustomGameItemViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
val binding: GameItemCustomBinding
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
override val onlyNotifyItemChanged: Boolean
|
||||
get() = true
|
||||
@ -50,12 +52,17 @@ class CustomGameItemViewHolder(
|
||||
) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSplitSubjectItem) {
|
||||
fillExposureEventList(item)
|
||||
|
||||
setSplitSubjectTitle(binding.layoutTitle, item, childEventHelper, TITLE_TYPE_SMALL)
|
||||
|
||||
val subject = item.data
|
||||
val entity = subject.data?.getOrNull(item.startChildPosition) ?: return
|
||||
boundedGameEntity = subject.data?.getOrNull(item.startChildPosition) ?: return
|
||||
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureInfoAndReportAd(boundedGameEntity!!, item.startChildPosition, item)
|
||||
}
|
||||
|
||||
val entity = boundedGameEntity ?: return
|
||||
|
||||
binding.run {
|
||||
val paddingBottom = if (item.isLastLine) {
|
||||
8f.dip2px()
|
||||
@ -64,7 +71,6 @@ class CustomGameItemViewHolder(
|
||||
}
|
||||
root.setPadding(root.paddingLeft, root.paddingTop, root.paddingRight, paddingBottom)
|
||||
|
||||
|
||||
clContainer.background = com.gh.gamecenter.common.R.drawable.reuse_listview_item_style.toDrawable(root.context)
|
||||
selectIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(root.context))
|
||||
gameKaifuType.setBackgroundColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(root.context))
|
||||
@ -134,20 +140,6 @@ class CustomGameItemViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureEventList(item: CustomSplitSubjectItem) {
|
||||
val game = item.data.data?.getOrNull(item.startChildPosition) ?: return
|
||||
runOnIoThread(true) {
|
||||
item.exposureEvent = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
item.startChildPosition,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ADVANCED_DOWNLOAD_WIDTH = 34F
|
||||
private const val SUBTITLE_MIN_WIDTH = 24F
|
||||
@ -283,4 +275,9 @@ class CustomGameItemViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,9 +7,16 @@ import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.common.view.DrawableView
|
||||
import com.gh.gamecenter.databinding.GameItemCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
|
||||
class CustomGamePluggableViewHolder(val binding: GameItemCustomBinding)
|
||||
: BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
class CustomGamePluggableViewHolder(val binding: GameItemCustomBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
fun initServerType(gameEntity: GameEntity) {
|
||||
boundedGameEntity = gameEntity
|
||||
val serverLabel = gameEntity.serverLabel
|
||||
when {
|
||||
gameEntity.test != null -> {
|
||||
@ -35,4 +42,8 @@ class CustomGamePluggableViewHolder(val binding: GameItemCustomBinding) : BaseRe
|
||||
// 由于RecyclerView的复用机制 需要每次测量gameName的宽
|
||||
binding.gameName.requestLayout()
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGameEntity?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
@ -151,25 +151,21 @@ class CustomGamePluginViewHolder(
|
||||
binding.pluginHead.setOnClickListener(View.OnClickListener(function = expandClick))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun fillExposureEvent(item: CustomPluginItem) {
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
item.data.forEachIndexed { index, game ->
|
||||
exposureList.add(
|
||||
createExposureEvent(
|
||||
game,
|
||||
listOf(ExposureSource("插件化", "")),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.pageLevelString = pageLocation.pageLevelString
|
||||
game.exposureEvent = createExposureEvent(
|
||||
game,
|
||||
listOf(ExposureSource("插件化", "")),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
}
|
||||
}
|
||||
item.exposureEventList = exposureList
|
||||
}
|
||||
}
|
||||
@ -3,15 +3,11 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.databinding.GameVerticalSlideItemCustomBinding
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.game.vertical.OnPagerSnapScrollListener
|
||||
import com.gh.gamecenter.game.vertical.SpanCountPagerSnapHelper
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
import com.gh.gamecenter.home.custom.adapter.CustomGameVerticalAdapter
|
||||
import com.gh.gamecenter.home.custom.createExposureEvent
|
||||
import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
@ -66,49 +62,16 @@ class CustomGameVerticalSlideViewHolder(
|
||||
gridLayoutManager?.spanCount = spanCount
|
||||
}
|
||||
}
|
||||
adapter.setData(item.data)
|
||||
|
||||
snapHelper.attachToRecyclerView(binding.recyclerView)
|
||||
|
||||
val listExposureEventList = arrayListOf<ExposureEvent>()
|
||||
val exposureEventList = arrayListOf<ExposureEvent>()
|
||||
item.exposureEventList = exposureEventList
|
||||
val exposureClosure: (Int) -> Unit = {
|
||||
runOnIoThread(true) {
|
||||
listExposureEventList.clear()
|
||||
|
||||
val startOffset = it * subjectEntity.list
|
||||
val endOffset = if (startOffset + subjectEntity.list >= games.size) {
|
||||
games.size
|
||||
} else {
|
||||
startOffset + subjectEntity.list
|
||||
}
|
||||
for (i in startOffset until endOffset) {
|
||||
val game = games[i].apply {
|
||||
isAdData = subjectEntity.adIconActive
|
||||
}
|
||||
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
item.exposureSource,
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.exposureEvent = event
|
||||
listExposureEventList.add(event)
|
||||
}
|
||||
exposureEventList.addAll(listExposureEventList)
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
games.forEachIndexed { index, gameEntity ->
|
||||
fillExposureInfoAndReportAd(gameEntity, index, item)
|
||||
}
|
||||
}
|
||||
|
||||
exposureClosure(0)
|
||||
adapter.setData(item.data)
|
||||
|
||||
binding.recyclerView.addOnScrollListener(OnPagerSnapScrollListener(snapHelper) {
|
||||
MtaHelper.onEvent("游戏专题", "滑动", subjectEntity.name)
|
||||
exposureClosure(it)
|
||||
})
|
||||
snapHelper.attachToRecyclerView(binding.recyclerView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,14 +10,20 @@ import com.gh.gamecenter.common.view.AsyncCell
|
||||
import com.gh.gamecenter.databinding.HomeAmwayItemBinding
|
||||
import com.gh.gamecenter.databinding.HomeAmwayItemCustomBinding
|
||||
import com.gh.gamecenter.entity.AmwayCommentEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class CustomHomeAmwayItemViewHolder(val binding: HomeAmwayItemCustomBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
class CustomHomeAmwayItemViewHolder(val binding: HomeAmwayItemCustomBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGame: AmwayCommentEntity.Game? = null
|
||||
|
||||
fun bindAmway(amway: AmwayCommentEntity) {
|
||||
val gameEntity = amway.game.toGameEntity()
|
||||
boundedGame = amway.game
|
||||
|
||||
binding.gameIcon.displayGameIcon(gameEntity)
|
||||
binding.gameName.text = amway.game.name
|
||||
@ -37,7 +43,10 @@ class CustomHomeAmwayItemViewHolder(val binding: HomeAmwayItemCustomBinding) : B
|
||||
|
||||
val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(amway.comment.content)
|
||||
if (m.find()) {
|
||||
val contents = TextHelper.getCommentLabelSpannableStringBuilder(amway.comment.content, com.gh.gamecenter.common.R.color.text_theme)
|
||||
val contents = TextHelper.getCommentLabelSpannableStringBuilder(
|
||||
amway.comment.content,
|
||||
com.gh.gamecenter.common.R.color.text_theme
|
||||
)
|
||||
binding.content.setTextWithHighlightedTextWrappedInsideWrapper(
|
||||
contents,
|
||||
highlightedTextClickListener = TextHelper.DirectToWebViewHighlightedTextClick(
|
||||
@ -66,6 +75,10 @@ class CustomHomeAmwayItemViewHolder(val binding: HomeAmwayItemCustomBinding) : B
|
||||
}
|
||||
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, binding.gameSubtitleTv)
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
return boundedGame?.exposureEvent?.getRefreshedExposureEvent()
|
||||
}
|
||||
}
|
||||
|
||||
class HomeAmwayAsyncCell(context: Context) : AsyncCell(context) {
|
||||
|
||||
@ -56,7 +56,9 @@ class CustomHomeAmwayListViewHolder(
|
||||
super.bindView(item)
|
||||
if (item is CustomAmwayItem) {
|
||||
|
||||
fillExposureEventList(item)
|
||||
runOnIoThread(isLightWeightTask = true) {
|
||||
fillExposureEventList(item)
|
||||
}
|
||||
|
||||
setTitle()
|
||||
|
||||
@ -67,7 +69,6 @@ class CustomHomeAmwayListViewHolder(
|
||||
snapHelper.attachToRecyclerView(binding.recyclerView)
|
||||
}
|
||||
adapter.submitList(item.data)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,26 +81,20 @@ class CustomHomeAmwayListViewHolder(
|
||||
binding.layoutTitle.tvRight.setOnClickListener {
|
||||
NewLogUtils.logHomeShareWallButtonClick("右上角")
|
||||
childEventHelper.navigateToAmway()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillExposureEventList(item: CustomAmwayItem) {
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
runOnIoThread(true) {
|
||||
item.data.forEachIndexed { index, amway ->
|
||||
val event = createExposureEvent(
|
||||
amway.game.toGameEntity(),
|
||||
listOf(ExposureSource("安利墙", "")),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
exposureList.add(event)
|
||||
}
|
||||
item.data.forEachIndexed { index, amway ->
|
||||
amway.game.exposureEvent = createExposureEvent(
|
||||
amway.game.toGameEntity(),
|
||||
listOf(ExposureSource("安利墙", "")),
|
||||
pageConfigure.exposureSourceList,
|
||||
index,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
}
|
||||
item.exposureEventList = exposureList
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,15 +7,13 @@ import android.widget.TextView
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.databinding.HomeDiscoverCardItemCustomBinding
|
||||
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.game.vertical.OnPagerSnapScrollListener
|
||||
import com.gh.gamecenter.game.vertical.SpanCountPagerSnapHelper
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
import com.gh.gamecenter.home.custom.IGameChangedNotifier
|
||||
@ -84,7 +82,6 @@ class CustomHomeDiscoverCardViewHolder(
|
||||
}
|
||||
adapter.submitList(entity.games)
|
||||
|
||||
|
||||
val childCount = labelContainer.childCount
|
||||
entity.label.forEachIndexed { index, label ->
|
||||
if (index < childCount) {
|
||||
@ -114,12 +111,7 @@ class CustomHomeDiscoverCardViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
fillExposureEventList(0, item)
|
||||
|
||||
binding.recyclerView.addOnScrollListener(OnPagerSnapScrollListener(snapHelper) {
|
||||
fillExposureEventList(it, item)
|
||||
})
|
||||
|
||||
fillExposureEventList(item)
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,31 +156,22 @@ class CustomHomeDiscoverCardViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
fun fillExposureEventList(position: Int, item: CustomDiscoverCardItem) {
|
||||
val exposureEventList = arrayListOf<ExposureEvent>()
|
||||
fun fillExposureEventList(item: CustomDiscoverCardItem) {
|
||||
val gameList = item.data?.games ?: return
|
||||
runOnIoThread(true) {
|
||||
val startOffset = position * item.spanCount
|
||||
val endOffset = if (startOffset + item.spanCount >= gameList.size) {
|
||||
gameList.size
|
||||
} else {
|
||||
startOffset + item.spanCount
|
||||
}
|
||||
for (i in startOffset until endOffset) {
|
||||
val game = gameList.getOrNull(i) ?: return@runOnIoThread
|
||||
val event = createExposureEvent(
|
||||
game,
|
||||
listOf(ExposureSource("发现", game.getTypeName())),
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
game.exposureEvent = event
|
||||
exposureEventList.add(event)
|
||||
for ((i, gameEntity) in gameList.withIndex()) {
|
||||
gameEntity.exposureEvent = createExposureEvent(
|
||||
gameEntity,
|
||||
listOf(ExposureSource("发现", gameEntity.getTypeName())),
|
||||
pageConfigure.exposureSourceList,
|
||||
i,
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
|
||||
if (!gameEntity.adGroupId.isEmpty() && !gameEntity.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(gameEntity.exposureEvent!!)
|
||||
gameEntity.isAdRequestReported = true
|
||||
}
|
||||
}
|
||||
item.exposureEventList = exposureEventList
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ package com.gh.gamecenter.home.custom.viewholder
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||
import com.gh.gamecenter.common.utils.DarkModeUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.view.stacklayoutmanager.StackLayoutManager
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
@ -26,14 +25,12 @@ class CustomHomeGameCollectionCarouselViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
licOwner: LifecycleOwner,
|
||||
val binding: HomeGameCollectionItemCustomBinding
|
||||
) :
|
||||
BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
|
||||
private val bannerController = BannerInRecyclerController {
|
||||
if (adapter.itemCount > 0) {
|
||||
binding.recyclerView.smoothScrollToPosition(layoutManager.getFirstVisibleItemPosition() + 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
@ -65,7 +62,6 @@ class CustomHomeGameCollectionCarouselViewHolder(
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSubjectCollectionItem) {
|
||||
|
||||
fillExposureInSubjectCollection(item, pageConfigure.exposureSourceList, createTrackData(item))
|
||||
|
||||
setSubjectCollectionTitle(item, binding.layoutTitle, childEventHelper)
|
||||
@ -84,7 +80,6 @@ class CustomHomeGameCollectionCarouselViewHolder(
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
adapter.setData(item)
|
||||
bannerController.start()
|
||||
|
||||
@ -34,11 +34,9 @@ class CustomHomeGameCollectionSlideViewHolder(
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override val gameChangedNotifier: IGameChangedNotifier?
|
||||
get() = if (isBigSlide) _adapter else null
|
||||
|
||||
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
if (item is CustomSubjectCollectionItem) {
|
||||
super.bindView(item)
|
||||
@ -56,5 +54,4 @@ class CustomHomeGameCollectionSlideViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import android.view.ViewGroup.MarginLayoutParams
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.databind.BindingAdapters
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
@ -16,6 +17,7 @@ import com.gh.gamecenter.databinding.HomeGameItemCustomBinding
|
||||
import com.gh.gamecenter.feature.entity.CustomPageTrackData
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.IExposureProvider
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.home.custom.CustomPageViewModel
|
||||
@ -33,7 +35,9 @@ import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
|
||||
class CustomHomeGameItemViewHolder(
|
||||
viewModel: CustomPageViewModel,
|
||||
val binding: HomeGameItemCustomBinding
|
||||
) : BaseCustomViewHolder(viewModel, binding.root) {
|
||||
) : BaseCustomViewHolder(viewModel, binding.root), IExposureProvider {
|
||||
|
||||
private var boundedGameEntity: GameEntity? = null
|
||||
|
||||
override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
|
||||
SubjectEventHelper(viewModel)
|
||||
@ -49,9 +53,6 @@ class CustomHomeGameItemViewHolder(
|
||||
) {
|
||||
super.bindView(item)
|
||||
if (item is CustomGameItem) {
|
||||
|
||||
_item.exposureEventList.clear()
|
||||
|
||||
val topMargin = if (item.isFirstLine) {
|
||||
0
|
||||
} else {
|
||||
@ -74,9 +75,11 @@ class CustomHomeGameItemViewHolder(
|
||||
val game = item.data
|
||||
val topVideo = game.topVideo
|
||||
val homeSetting = game.homeSetting
|
||||
game.outerSequence = item.componentPosition
|
||||
|
||||
val event = createExposureEvent(
|
||||
boundedGameEntity = game
|
||||
game.pageLevelString = pageLocation.pageLevelString
|
||||
game.outerSequence = item.componentPosition
|
||||
game.exposureEvent = createExposureEvent(
|
||||
item.data,
|
||||
listOf(
|
||||
ExposureSource(
|
||||
@ -89,8 +92,11 @@ class CustomHomeGameItemViewHolder(
|
||||
item.componentPosition,
|
||||
createTrackData(item)
|
||||
)
|
||||
item.exposureEventList.add(event)
|
||||
item.exposureEvent = event
|
||||
|
||||
if (!game.adGroupId.isEmpty() && !game.isAdRequestReported) {
|
||||
AdHelper.reportAdRequest(game.exposureEvent!!)
|
||||
game.isAdRequestReported = true
|
||||
}
|
||||
|
||||
bindGameInfo(
|
||||
position,
|
||||
@ -230,4 +236,10 @@ class CustomHomeGameItemViewHolder(
|
||||
binding.gameRating.goneIf(!(game.commentCount > 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch == "on"))
|
||||
binding.gameRating2.goneIf(!(game.commentCount > 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch != "on"))
|
||||
}
|
||||
|
||||
override fun provideExposureData(): ExposureEvent? {
|
||||
boundedGameEntity?.updateBoundedExposureEventIfNeeded()
|
||||
return boundedGameEntity?.exposureEvent
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user