diff --git a/app/src/main/java/com/gh/common/util/LogUtils.java b/app/src/main/java/com/gh/common/util/LogUtils.java index 85772e4f8a..6ccc1d848a 100644 --- a/app/src/main/java/com/gh/common/util/LogUtils.java +++ b/app/src/main/java/com/gh/common/util/LogUtils.java @@ -844,7 +844,7 @@ public class LogUtils { object.put("entrance", entrance); object.put("recommend_name", recommendName); object.put("link_type", linkType); - object.put("link_title", linkTitle); + object.put("link_text", linkTitle); object.put("sequence", sequence); } catch (JSONException e) { e.printStackTrace(); @@ -992,7 +992,7 @@ public class LogUtils { object.put("event", "top_tab_click"); object.put("tab_name", tabName); object.put("link_type", linkType); - object.put("link_title", linkTitle); + object.put("link_text", linkTitle); object.put("sequence", sequence); object.put("meta", getMetaObject()); object.put("timestamp", System.currentTimeMillis() / 1000); diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index 359e5b35f8..9ee5f5df5e 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -1896,6 +1896,7 @@ object NewLogUtils { displayType: String, columnName: String, columnId: String, + linkId: String, linkType: String, linkText: String, location: String, @@ -1906,7 +1907,7 @@ object NewLogUtils { "display_type" to displayType "column_name" to columnName "column_id" to columnId - "link_id" to columnId + "link_id" to linkId if (linkType.isNotEmpty()) { "link_type" to linkType } @@ -2051,7 +2052,7 @@ object NewLogUtils { title: String, linkType: String, linkId: String, - linkTitle: String, + linkText: String, categoryName: String, categoryId: String, ) { @@ -2059,7 +2060,7 @@ object NewLogUtils { "event" to "common_category_detail_content_click" "title" to title "link_type" to linkType - "link_title" to linkTitle + "link_text" to linkText "link_id" to linkId "category_name" to categoryName "category_id" to categoryId diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index 31b8d74eb4..9b67fd5c81 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -256,7 +256,7 @@ class GameFragmentAdapter( ?: "", gallery.name, "(游戏-专题)" ) NewLogUtils.logColumnPictureClick( - "显示图集", gallery.name ?: "", gallery.id ?: "", "column", + "显示图集", gallery.name ?: "", gallery.id ?: "", gallery.id ?: "", "column", gallery.name ?: "", "板块", mViewModel.blockData?.name ?: "" ) } @@ -388,7 +388,10 @@ class GameFragmentAdapter( } val rankCollection = mItemDataList[position].rankCollection - val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) + val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) { + NewLogUtils.logColumnCategoryHomeContentClick(it.name ?: "", it.id ?: "", rankCollection.name ?: "", + rankCollection.id ?: "","版块",mViewModel.blockData?.name?:"") + } val exposureEventList = arrayListOf() rankCollection.columns.let { @@ -502,7 +505,7 @@ class GameFragmentAdapter( ) DirectUtils.directToLinkPage(mContext, linkEntity, "(游戏-专题:" + entity?.name + "-大图)", "首页游戏", entity?.exposureEvent) NewLogUtils.logColumnPictureClick( - "大图", entity?.name ?: "", entity?.id ?: "", "游戏专题", + "大图", entity?.name ?: "", entity?.id ?: "", entity?.id ?: "", "column", entity?.name ?: "", "板块", mViewModel.blockData?.name ?: "" ) } @@ -606,7 +609,7 @@ class GameFragmentAdapter( ?: "", mItemDataList[position].exposureEvent ) NewLogUtils.logColumnPictureClick( - "大图", entity.name ?: "", entity.id, "游戏专题", + "大图", entity.name ?: "", entity.id, entity.id, "column", entity.name ?: "", "板块", mViewModel.blockData?.name ?: "" ) } @@ -742,7 +745,7 @@ class GameFragmentAdapter( it.outerSequence = position }, basicSource = mBasicExposureSource, - source = listOf() + source = listOf(ExposureSource("推荐入口", if (Config.isShowPlugin()) entity.name ?: "" else entity.nameNormal ?: "")) ) event.payload.controlType = "推荐入口" event.payload.controlName = if (Config.isShowPlugin()) entity.name else entity.nameNormal @@ -761,7 +764,7 @@ class GameFragmentAdapter( it.outerSequence = position }, basicSource = mBasicExposureSource, - source = listOf() + source = listOf(ExposureSource("轮播图")) ) event.payload.controlType = "轮播图" event.payload.controlName = entity.name @@ -991,6 +994,11 @@ class GameFragmentAdapter( "more" -> "更多" else -> "全部" } + val moreLink = column.moreLink + NewLogUtils.logColumnListClickButton( + buttonType, column.name ?: "", column.id ?: "", moreLink?.type ?: "", + moreLink?.name ?: "", "版块", mViewModel.blockData?.name ?: "" + ) when (column.home) { "change" -> { MtaHelper.onEvent("游戏专题", "换一批", column.name) @@ -1010,7 +1018,7 @@ class GameFragmentAdapter( MtaHelper.onEvent("游戏专题合集", "全部", column.name) DirectUtils.directToColumnCollection(mContext, column.id!!, -1, "(推荐入口)") NewLogUtils.logColumnCategoryHomeButtonClick( - buttonType, column.name ?: "", column.id ?: "", "板块", "" + buttonType, column.name ?: "", column.id ?: "", "板块", mViewModel.blockData?.name ?: "" ) } "common_collection" -> { @@ -1061,11 +1069,6 @@ class GameFragmentAdapter( ) } MtaHelper.onEvent("游戏专题", "全部", column.name) - val moreLink = column.moreLink - NewLogUtils.logColumnListClickButton( - buttonType, column.name ?: "", column.id ?: "", moreLink?.type ?: "", - moreLink?.name ?: "", "版块", mViewModel.blockData?.name ?: "" - ) } } } diff --git a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt index 7c4aede84d..5010aabfb1 100644 --- a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt @@ -83,24 +83,31 @@ class ColumnCollectionDetailFragment : LazyListFragment() for (link in linkEntityList) { - subjectDataList.add(SubjectData( + subjectDataList.add( + SubjectData( subjectId = link.link, subjectName = link.name, isOrder = false, requireUpdateSetting = true, filter = "type:全部" // 默认显示大图 - )) + ) + ) } val fragment = childFragmentManager.findFragmentByTag(SubjectTabFragment::class.java.simpleName) - ?: SubjectTabFragment() + ?: SubjectTabFragment() val bundle = arguments + mListViewModel.columnCollection.value?.let { + bundle?.putString(EntranceConsts.KEY_GAME_COLLECTION_ID, it.id) + bundle?.putString(EntranceConsts.KEY_GAME_COLLECTION_TITLE, it.name) + } bundle?.putParcelableArrayList(EntranceConsts.KEY_DATA, subjectDataList) bundle?.putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true) fragment.arguments = bundle mBinding?.placeholder?.visibility = View.VISIBLE - childFragmentManager.beginTransaction().replace(R.id.placeholder, fragment, SubjectTabFragment::class.java.simpleName).commitAllowingStateLoss() + childFragmentManager.beginTransaction().replace(R.id.placeholder, fragment, SubjectTabFragment::class.java.simpleName) + .commitAllowingStateLoss() } override fun provideListAdapter(): ColumnCollectionDetailAdapter { @@ -120,8 +127,10 @@ class ColumnCollectionDetailFragment : LazyListFragmentUnit ) : BaseRecyclerAdapter(context) { private val mViewHolderList = SparseArray() @@ -59,6 +60,7 @@ class RankCollectionAdapter( } rankTitle.text = column.name rankTitle.setOnClickListener { + clickClosure.invoke(column) DirectUtils.directToColumnCollection( mContext, mSubjectEntity.id ?: "", diff --git a/app/src/main/java/com/gh/gamecenter/game/rank/RankCollectionViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/rank/RankCollectionViewHolder.kt index fbb661c28b..a79bf99e09 100644 --- a/app/src/main/java/com/gh/gamecenter/game/rank/RankCollectionViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/rank/RankCollectionViewHolder.kt @@ -7,14 +7,14 @@ import com.gh.gamecenter.entity.SubjectEntity class RankCollectionViewHolder(val binding: RankCollectionListBinding) : BaseRecyclerViewHolder(binding.root) { - fun bindRankCollection(collection: SubjectEntity): RankCollectionAdapter { + fun bindRankCollection(collection: SubjectEntity, clickClosure: (SubjectEntity) -> Unit): RankCollectionAdapter { binding.recyclerView.apply { isNestedScrollingEnabled = false if (adapter is RankCollectionAdapter) { (adapter as RankCollectionAdapter).checkResetData(collection) } else { layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) - adapter = RankCollectionAdapter(context, collection) + adapter = RankCollectionAdapter(context, collection, clickClosure) } return adapter as RankCollectionAdapter } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt index 9e2f16731f..e22be8f049 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt @@ -4,6 +4,8 @@ import android.annotation.SuppressLint import android.content.Context import android.graphics.Color import android.graphics.drawable.ColorDrawable +import android.os.Handler +import android.os.HandlerThread import android.text.TextUtils import android.util.SparseBooleanArray import android.util.SparseIntArray @@ -18,25 +20,24 @@ import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.callback.OnListClickListener import com.gh.common.DefaultUrlHandler -import com.gh.gamecenter.common.constant.Constants import com.gh.common.databind.BindingAdapters import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureManager import com.gh.common.exposure.ExposureSource -import com.gh.common.util.* import com.gh.common.util.DialogUtils +import com.gh.common.util.DirectUtils import com.gh.common.util.LogUtils import com.gh.common.util.NewLogUtils -import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration -import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration import com.gh.gamecenter.GameNewsActivity import com.gh.gamecenter.R import com.gh.gamecenter.SuggestionActivity import com.gh.gamecenter.adapter.viewholder.FooterViewHolder -import com.gh.gamecenter.common.* +import com.gh.gamecenter.common.callback.OnListClickListener +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration +import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.* import com.gh.gamecenter.entity.CommunityEntity @@ -70,6 +71,13 @@ class DescAdapter( private val mCustomColumnTagsExpandStatusSparseBooleanArray = SparseBooleanArray() private val mDefaultHorizontalPadding by lazy { R.dimen.game_detail_item_horizontal_padding.toPx() } + private var mHandlerThread: HandlerThread = HandlerThread("GH_EXPOSURE_LOG_THREAD") + private var mHandler: Handler + + init { + mHandlerThread.start() + mHandler = Handler(mHandlerThread.looper) + } @SuppressLint("NotifyDataSetChanged") fun updateDescItemList(descItemList: ArrayList) { @@ -99,19 +107,19 @@ class DescAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - COMMENTS -> GameDetailCommentsViewHolder(parent.toBinding()) - CUSTOM_COLUMN -> GameDetailCustomColumnViewHolder(parent.toBinding()) - IMAGE -> GameDetailRecommendImageViewHolder(parent.toBinding()) - VIDEOS -> GameVideoGalleryViewHolder(parent.toBinding()) - IMAGE_GALLERY -> GameImageGalleryViewHolder(parent.toBinding()) - UPDATE_CONTENT -> GameUpdateContentViewHolder(parent.toBinding()) - LATEST_SERVICE -> GameLatestServiceViewHolder(parent.toBinding()) - INFO_RAIDERS -> GameRaidersGalleryViewHolder(parent.toBinding()) - LIBAO -> GameLibaoGalleryViewHolder(parent.toBinding()) - RELATED_VERSION -> GameDetailRelatedVersionViewHolder(parent.toBinding()) - GAME_DETAIL -> GameDetailInfoViewHolder(parent.toBinding()) - RECOMMENDED_GAMES -> GamesRecommendedGalleryViewHolder(parent.toBinding()) - NOTICE -> GameDetailNoticeViewHolder(parent.toBinding()) + COMMENTS -> GameDetailCommentsViewHolder(parent.toBinding(), mHandler) + CUSTOM_COLUMN -> GameDetailCustomColumnViewHolder(parent.toBinding(), mHandler) + IMAGE -> GameDetailRecommendImageViewHolder(parent.toBinding(), mHandler) + VIDEOS -> GameVideoGalleryViewHolder(parent.toBinding(), mHandler) + IMAGE_GALLERY -> GameImageGalleryViewHolder(parent.toBinding(), mHandler) + UPDATE_CONTENT -> GameUpdateContentViewHolder(parent.toBinding(), mHandler) + LATEST_SERVICE -> GameLatestServiceViewHolder(parent.toBinding(), mHandler) + INFO_RAIDERS -> GameRaidersGalleryViewHolder(parent.toBinding(), mHandler) + LIBAO -> GameLibaoGalleryViewHolder(parent.toBinding(), mHandler) + RELATED_VERSION -> GameDetailRelatedVersionViewHolder(parent.toBinding(), mHandler) + GAME_DETAIL -> GameDetailInfoViewHolder(parent.toBinding(), mHandler) + RECOMMENDED_GAMES -> GamesRecommendedGalleryViewHolder(parent.toBinding(), mHandler) + NOTICE -> GameDetailNoticeViewHolder(parent.toBinding(), mHandler) else -> { val view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false) FooterViewHolder(view) @@ -259,9 +267,6 @@ class DescAdapter( } titleTv.text = "大家都在玩" moreTv.visibility = View.GONE - mViewModel.game?.let { - NewLogUtils.logGameDetailPopularView(it.name ?: "", it.id) - } } } @@ -290,10 +295,9 @@ class DescAdapter( EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING)) MtaHelper.onEvent(MTA_KEY_GAME_NEW, "玩家评论_点击全部", mGameName) MtaHelper.onEvent(MTA_KEY_GAME_NEW, "玩家评论_更多按钮", mGameName) + NewLogUtils.logGameDetailCommentClick(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "", "更多") } - mViewModel.game?.let { - NewLogUtils.logGameDetailCommentView(it.name ?: "", it.id) - } + } commentsAdapter.comments = comments @@ -469,10 +473,6 @@ class DescAdapter( } historyVersionTv.visibility = if (updateContent.historyApkStatus == "on" && updateContent.historyApkCount >= 1) View.VISIBLE else View.GONE - contentTv.setExpandCallback { - MtaHelper.onEvent(MTA_KEY_GAME_NEW, "展开更新内容", mGameName) - } - NewLogUtils.logGameDetailUpdatedView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") } } @@ -487,7 +487,7 @@ class DescAdapter( if (!server.calendar.isNullOrEmpty()) { serviceRv.visibility = View.VISIBLE if (serviceRv.adapter == null) { - val serviceAdapter = GameLatestServiceAdapter(mContext, server.calendar) + val serviceAdapter = GameLatestServiceAdapter(mContext, mViewModel.game, server.calendar) val itemDecoration = HorizontalDividerItemDecoration.Builder(mContext) .size(12F.dip2px()) .color(R.color.transparent.toColor(mContext)) @@ -602,9 +602,6 @@ class DescAdapter( } titleTv.text = "游戏礼包" moreTv.visibility = View.GONE - mViewModel.game?.let { - NewLogUtils.logGameDetailGiftView(it.name ?: "", it.id) - } } } @@ -902,17 +899,64 @@ class DescAdapter( const val MTA_KEY_GAME_NEW = "游戏详情_新" // 保留已弃用的 MTA 事件是为了以后加自有日志的时候不用再痛苦地找代码,实际上 MTA 的相关代码会在编译期移除,所以不用担心 } - class GameDetailNoticeViewHolder(var binding: GamedetailItemDescNoticeBinding) : RecyclerView.ViewHolder(binding.root) - class GameDetailRecommendImageViewHolder(var binding: GamedetailItemImageBinding) : RecyclerView.ViewHolder(binding.root) - class GameDetailCommentsViewHolder(var binding: GamedetailItemCommentsBinding) : RecyclerView.ViewHolder(binding.root) - class GameDetailCustomColumnViewHolder(var binding: GamedetailItemCustomColumnBinding) : RecyclerView.ViewHolder(binding.root) - class GameDetailRelatedVersionViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) - class GameVideoGalleryViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) - class GameImageGalleryViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) - class GameUpdateContentViewHolder(var binding: GameUpdateContentBinding) : RecyclerView.ViewHolder(binding.root) - class GameLatestServiceViewHolder(var binding: GameLatestServiceListBinding) : RecyclerView.ViewHolder(binding.root) - class GameRaidersGalleryViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) - class GameLibaoGalleryViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) - class GameDetailInfoViewHolder(var binding: GameDetailInfoBinding) : RecyclerView.ViewHolder(binding.root) - class GamesRecommendedGalleryViewHolder(var binding: GameGalleryListBinding) : RecyclerView.ViewHolder(binding.root) + open class ExposureViewHolder(view: View, val handler: Handler) : RecyclerView.ViewHolder(view) { + + private var mLogRunnable: Runnable? = null + + fun startDelayLogRunnable() { + if (mLogRunnable == null) { + mLogRunnable = Runnable { + exposureLog() + } + handler.postDelayed(mLogRunnable!!, 3000) + } + } + + open fun exposureLog() { + + } + + fun removeLogRunnable() { + if (mLogRunnable != null) { + handler.removeCallbacks(mLogRunnable!!) + mLogRunnable = null + } + } + } + + class GameDetailNoticeViewHolder(var binding: GamedetailItemDescNoticeBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + class GameDetailRecommendImageViewHolder(var binding: GamedetailItemImageBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + inner class GameDetailCommentsViewHolder(var binding: GamedetailItemCommentsBinding, handler: Handler) : + ExposureViewHolder(binding.root, handler) { + override fun exposureLog() { + NewLogUtils.logGameDetailCommentView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") + } + } + + class GameDetailCustomColumnViewHolder(var binding: GamedetailItemCustomColumnBinding, handler: Handler) : + ExposureViewHolder(binding.root, handler) + + class GameDetailRelatedVersionViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + class GameVideoGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + class GameImageGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + inner class GameUpdateContentViewHolder(var binding: GameUpdateContentBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) { + override fun exposureLog() { + NewLogUtils.logGameDetailUpdatedView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") + } + } + + class GameLatestServiceViewHolder(var binding: GameLatestServiceListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + class GameRaidersGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + inner class GameLibaoGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) { + override fun exposureLog() { + NewLogUtils.logGameDetailGiftView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") + } + } + + class GameDetailInfoViewHolder(var binding: GameDetailInfoBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) + inner class GamesRecommendedGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) { + override fun exposureLog() { + NewLogUtils.logGameDetailPopularView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt index 18365c7db4..788beb5e93 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt @@ -2,23 +2,28 @@ package com.gh.gamecenter.gamedetail.desc import android.app.Activity import android.content.Intent +import android.graphics.Rect import android.os.Bundle import android.view.View import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.base.fragment.BaseFragment -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.core.iinterface.IScrollable -import com.gh.common.util.* +import com.gh.common.util.DirectUtils +import com.gh.common.util.OnSyncCallBack +import com.gh.common.util.SyncDataBetweenPageHelper import com.gh.gamecenter.LibaoDetailActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.BaseFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.observeNonNull import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.common.utils.viewModelProviderFromParent -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.core.iinterface.IScrollable +import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.RunningUtils +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.FragmentDescBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.LibaoEntity @@ -91,12 +96,9 @@ class DescFragment : BaseFragment(), IScrollable { override fun onCreate(savedInstanceState: Bundle?) { mGameEntity = arguments?.getParcelable(GameEntity.TAG) - openVideoStreaming = arguments?.getBoolean(EntranceConsts.KEY_OPEN_VIDEO_STREAMING, false) - ?: false - mScrollToLibao = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, false) - ?: false - mScrollToServer = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_SERVER, false) - ?: false + openVideoStreaming = arguments?.getBoolean(EntranceConsts.KEY_OPEN_VIDEO_STREAMING, false) ?: false + mScrollToLibao = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, false) ?: false + mScrollToServer = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_SERVER, false) ?: false val gameDetailFactory = GameDetailViewModel.Factory(HaloApp.getInstance().application, mGameEntity?.id, mGameEntity) val gameDetailViewModel: GameDetailViewModel = viewModelProviderFromParent(gameDetailFactory) @@ -180,8 +182,46 @@ class DescFragment : BaseFragment(), IScrollable { if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { EventBus.getDefault().post(EBTypeChange(GameDetailFragment.EB_SCROLLING, 0)) } + + exposureScroll(newState) } }) + exposureScroll(RecyclerView.SCROLL_STATE_IDLE) + } + + private fun exposureScroll(newState: Int) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + val layoutManager = mBinding.recyclerview.layoutManager as? LinearLayoutManager + val firstVisibleItem = layoutManager?.findFirstCompletelyVisibleItemPosition() ?: -1 + val lastVisibleItem = layoutManager?.findLastCompletelyVisibleItemPosition() ?: -1 + val childCount = mBinding.recyclerview.adapter?.itemCount ?: 0 + if (firstVisibleItem == -1 || lastVisibleItem == -1) return + for (i in 0 until childCount) { + val viewHolder = mBinding.recyclerview.findViewHolderForAdapterPosition(i) + if (viewHolder != null && viewHolder is DescAdapter.ExposureViewHolder) { + if (i in firstVisibleItem..lastVisibleItem) { + val rect = Rect() + viewHolder.itemView.getLocalVisibleRect(rect) + if (rect.top == 0 && rect.bottom == viewHolder.itemView.height) { + viewHolder.startDelayLogRunnable() + } + } else { + viewHolder.removeLogRunnable() + } + } + } + } + } + + override fun onPause() { + super.onPause() + val childCount = mBinding.recyclerview.adapter?.itemCount ?: 0 + for (i in 0 until childCount) { + val viewHolder = mBinding.recyclerview.findViewHolderForAdapterPosition(i) + if (viewHolder is DescAdapter.ExposureViewHolder) { + viewHolder.removeLogRunnable() + } + } } override fun onDestroy() { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLatestServiceAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLatestServiceAdapter.kt index 0779c73f77..c69d5219f5 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLatestServiceAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLatestServiceAdapter.kt @@ -7,14 +7,17 @@ import android.view.View.MeasureSpec import android.view.ViewGroup import android.view.ViewTreeObserver import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.NewLogUtils import com.gh.gamecenter.core.utils.TimeUtils import com.gh.gamecenter.common.utils.safelyGetInRelease import com.gh.gamecenter.common.utils.toBinding import com.gh.gamecenter.databinding.ItemGameDetailLatestServiceBinding import com.gh.gamecenter.databinding.ItemGameDetailMoreBinding +import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.ServerCalendarEntity -class GameLatestServiceAdapter(val context: Context, val datas: ArrayList) : RecyclerView.Adapter() { +class GameLatestServiceAdapter(val context: Context, val gameEntity: GameEntity?, val datas: ArrayList) : + RecyclerView.Adapter() { private val mShowItemCount: Int = 3 private val mMaxItemCount: Int = 10 private var mIsExpand = false @@ -109,6 +112,9 @@ class GameLatestServiceAdapter(val context: Context, val datas: ArrayList { + val intent = RatingReplyActivity.getIntent( + mContext, + amway.game.id, + amway.comment.id, + false, + path, + "" + ) + mContext.startActivity(intent) + NewLogUtils.logHomeShareWallCardClick(amway.game.name ?: "", amway.game.id, "评论内容") + } + R.id.user_icon_container -> { + DirectUtils.directToHomeActivity(mContext, amway.comment.user.id, path, "") + NewLogUtils.logHomeShareWallCardClick(amway.game.name ?: "", amway.game.id, "用户信息") + } + else -> { + GameDetailActivity.startGameDetailActivity( + mContext, + amway.game.id, + path, + homeItemData.exposureEventList?.safelyGetInRelease(itemPosition) + ) + NewLogUtils.logHomeShareWallCardClick(amway.game.name ?: "", amway.game.id, "游戏信息") + } } } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeRecommendItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeRecommendItemViewHolder.kt index 9db2338a9c..b6a3fd48fd 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeRecommendItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeRecommendItemViewHolder.kt @@ -45,7 +45,7 @@ class HomeRecommendItemViewHolder(val binding: HomeRecommendItemBinding) : BaseR val exposureEvent = ExposureEvent.createEventWithSourceConcat( gameEntity = GameEntity().also { it.sequence = index }, basicSource = basicExposureSource, - source = listOf() + source = listOf(ExposureSource("推荐入口", homeRecommend.name)) ) exposureEvent.payload.controlType = "推荐入口" exposureEvent.payload.controlName = homeRecommend.name diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt index 0e51582a6a..473625feb3 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt @@ -243,7 +243,7 @@ class LegacyHomeFragmentAdapterAssistant( DirectUtils.directToLinkPage(mContext, LinkEntity(link = data.link, type = data.type), "(首页游戏)", "游戏-专题") } NewLogUtils.logColumnPictureClick( - "大图", columnCollection.name ?: "", columnCollection.id ?: "","游戏专题", + "大图", columnCollection.name ?: "", columnCollection.id ?: "", columnCollection.id ?: "", "游戏专题", columnCollection.name ?: "", "新首页", "" ) } @@ -473,7 +473,7 @@ class LegacyHomeFragmentAdapterAssistant( setPageSwitchData() DirectUtils.directToLinkPage(mContext, linkEntity, "(游戏-专题:$name-大图)", "首页游戏") NewLogUtils.logColumnPictureClick( - "大图", entity.name ?: "", entity.id, "游戏专题", + "大图", entity.name ?: "", entity.id, entity.id, "column", entity.name ?: "", "新首页", "" ) } @@ -747,7 +747,7 @@ class LegacyHomeFragmentAdapterAssistant( ?: "", item.gallery?.name, "(游戏-专题)" ) NewLogUtils.logColumnPictureClick( - "图集", item.gallery?.name ?: "", item.gallery?.id ?: "", "游戏专题", + "图集", item.gallery?.name ?: "", item.gallery?.id ?: "", item.gallery?.id ?: "", "column", item.gallery?.name ?: "", "新首页", "" ) } @@ -808,7 +808,12 @@ class LegacyHomeFragmentAdapterAssistant( private fun bindRankCollection(holder: RankCollectionViewHolder, item: LegacyHomeItemData) { val rankCollection = item.rankCollection - val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) + val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) { + NewLogUtils.logColumnCategoryHomeContentClick( + it.name ?: "", it.id ?: "", rankCollection.name ?: "", + rankCollection.id ?: "", "新首页", "" + ) + } val exposureEventList = arrayListOf() rankCollection.columns.let { diff --git a/app/src/main/java/com/gh/gamecenter/home/amway/HomeAmwayAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/amway/HomeAmwayAdapter.kt index 22a82e9b25..1d0b35d862 100644 --- a/app/src/main/java/com/gh/gamecenter/home/amway/HomeAmwayAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/amway/HomeAmwayAdapter.kt @@ -5,6 +5,7 @@ import android.view.View import android.view.ViewGroup import com.gh.common.util.* import com.gh.gamecenter.common.callback.ConfirmListener +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.common.utils.ImageUtils import com.gh.gamecenter.core.utils.MtaHelper @@ -67,6 +68,10 @@ class HomeAmwayAdapter( } }) } + userIconContainer.setOnClickListener { + itemClick.invoke(it, position, amway) + } + userName.setOnClickListener { userIconContainer.performClick() } all.setOnClickListener { DirectUtils.directToAmway(mContext, null, "(游戏-专题:安利墙-全部)", "") diff --git a/app/src/main/java/com/gh/gamecenter/home/slide/HomeSlideListAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/slide/HomeSlideListAdapter.kt index b498f6fe1f..890623c94e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/slide/HomeSlideListAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/slide/HomeSlideListAdapter.kt @@ -78,7 +78,7 @@ class HomeSlideListAdapter( exposureEvent = ExposureEvent.createEventWithSourceConcat( gameEntity = homeSlide.linkGame?.apply { sequence = actualPosition }, basicSource = basicExposureSource, - source = listOf() + source = listOf(ExposureSource("轮播图", "")) ) exposureEvent?.payload?.controlType = "轮播图" exposureEvent?.payload?.controlName = homeSlide.title diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt index a74d362eb9..e2943488dc 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt @@ -13,6 +13,7 @@ import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureSource import com.gh.common.exposure.IExposable import com.gh.common.util.* +import com.gh.common.util.NewLogUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.FooterViewHolder @@ -30,11 +31,13 @@ import com.gh.gamecenter.game.GameItemViewHolder import com.lightgame.download.DownloadEntity import java.util.* -class SubjectAdapter(context: Context, - private val mViewModel: SubjectListViewModel, - private val mSubjectViewModel: SubjectViewModel?, - private val mEntrance: String?, - private val mIsColumnCollection: Boolean) : ListAdapter(context), IExposable { +class SubjectAdapter( + context: Context, + private val mViewModel: SubjectListViewModel, + private val mSubjectViewModel: SubjectViewModel?, + private val mEntrance: String?, + private val mIsColumnCollection: Boolean +) : ListAdapter(context), IExposable { private val mExposureEventSparseArray: SparseArray = SparseArray() private val subjectData = mViewModel.subjectData @@ -66,7 +69,8 @@ class SubjectAdapter(context: Context, return ItemViewType.ITEM_FOOTER } if (position == 0 && mEntityList != null && mEntityList.size > 0 - && !TextUtils.isEmpty(mEntityList[0].image)) { + && !TextUtils.isEmpty(mEntityList[0].image) + ) { return ItemViewType.GAME_IMAGE } return ItemViewType.GAME_NORMAL @@ -198,35 +202,41 @@ class SubjectAdapter(context: Context, DataCollectionUtils.uploadClick(mContext, "列表", subjectData.subjectName, gameEntity.name) GameDetailActivity.startGameDetailActivity( - mContext, - gameEntity, - StringUtils.buildString(mEntrance, - "+(", - subjectData.subjectName, - ":列表[", subjectData.filter, - "=", - if (subjectData.sort.contains("publish")) "最新" - else "最热", - "=", (humanReadablePosition).toString(), "])"), - traceEvent = exposureEvent) + mContext, + gameEntity, + StringUtils.buildString( + mEntrance, + "+(", + subjectData.subjectName, + ":列表[", subjectData.filter, + "=", + if (subjectData.sort.contains("publish")) "最新" + else "最热", + "=", (humanReadablePosition).toString(), "])" + ), + traceEvent = exposureEvent + ) } DownloadItemUtils.setOnClickListener( - mContext, - holder.binding.downloadBtn, - gameEntity, - position, - this, - StringUtils.buildString(mEntrance, - "+(", - subjectData.subjectName, - ":列表[", subjectData.filter, - "=", - if (subjectData.sort.contains("publish")) "最新" - else "最热", - "=", (humanReadablePosition).toString(), "])"), - StringUtils.buildString(subjectData.subjectName, ":", gameEntity.name), - exposureEvent) + mContext, + holder.binding.downloadBtn, + gameEntity, + position, + this, + StringUtils.buildString( + mEntrance, + "+(", + subjectData.subjectName, + ":列表[", subjectData.filter, + "=", + if (subjectData.sort.contains("publish")) "最新" + else "最热", + "=", (humanReadablePosition).toString(), "])" + ), + StringUtils.buildString(subjectData.subjectName, ":", gameEntity.name), + exposureEvent + ) DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true, subjectData.briefStyle) } else if (holder is GameImageViewHolder) { @@ -280,11 +290,20 @@ class SubjectAdapter(context: Context, linkEntity.name = gameEntity.name linkEntity.display = gameEntity.display linkEntity.community = gameEntity.community - PageSwitchDataHelper.pushCurrentPageData(hashMapOf( + PageSwitchDataHelper.pushCurrentPageData( + hashMapOf( Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏专题-头图"), - Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, subjectData.subjectName ?: ""))) - DirectUtils.directToLinkPage(mContext, linkEntity, - mEntrance + "(" + subjectData.subjectName + ":头图)", "游戏专题", mExposureEventSparseArray.get(position)) + Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, subjectData.subjectName ?: "") + ) + ) + DirectUtils.directToLinkPage( + mContext, linkEntity, + mEntrance + "(" + subjectData.subjectName + ":头图)", "游戏专题", mExposureEventSparseArray.get(position) + ) + NewLogUtils.logColumnPictureClick( + "头图", subjectData.subjectName ?: "", subjectData.subjectId ?: "", + linkEntity.link ?: "", linkEntity.type ?: "", linkEntity.text ?: "", "专题详情", "" + ) } } else if (holder is FooterViewHolder) { holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver) diff --git a/app/src/main/java/com/gh/gamecenter/subject/tab/SubjectTabFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/tab/SubjectTabFragment.kt index abdce5a9f9..eff4569c25 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/tab/SubjectTabFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/tab/SubjectTabFragment.kt @@ -9,6 +9,7 @@ import android.widget.TextView import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentStatePagerAdapter import androidx.viewpager.widget.ViewPager +import com.gh.common.util.NewLogUtils import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.R import com.gh.gamecenter.common.constant.EntranceConsts @@ -40,16 +41,16 @@ class SubjectTabFragment : BaseFragment() { if (mSubjectList.isNullOrEmpty()) { // 专题详情 val subjectData = arguments?.getParcelable(EntranceConsts.KEY_SUBJECT_DATA) - ?: return + ?: return val settingsEntity = arguments?.getParcelable(SubjectSettingEntity::class.java.simpleName) - ?: return + ?: return tagList = settingsEntity.typeEntity.content as ArrayList if (tagList.size > 1) { mBinding.subjectTabContainer.visibility = View.VISIBLE } tagList.forEachIndexed { index, tag -> val element = childFragmentManager.findFragmentByTag("${fragmentTag}$index") - ?: SubjectListFragment() + ?: SubjectListFragment() val bundle = arguments?.clone() as Bundle? val copyData = subjectData.deepCopy() copyData.filter = if (tag == "全部") { @@ -66,16 +67,16 @@ class SubjectTabFragment : BaseFragment() { // 排行榜 mBinding.subjectTabContainer.visibility = View.VISIBLE - mSubjectList.filterIndexed { index, subjectData -> + mSubjectList.filterIndexed { index, subject -> val element = childFragmentManager.findFragmentByTag("${fragmentTag}$index") - ?: SubjectListFragment() + ?: SubjectListFragment() val bundle = arguments?.clone() as Bundle? - bundle?.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData) + bundle?.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subject) bundle?.putString(EntranceConsts.KEY_SUBJECT_TYPE, "tab") element.arguments = bundle fragments.add(element) - tagList.add(subjectData.subjectName ?: "") + tagList.add(subject.subjectName ?: "") } mBinding.subjectViewpager.post { @@ -92,10 +93,18 @@ class SubjectTabFragment : BaseFragment() { } } } + val categoryId = requireArguments().getString(EntranceConsts.KEY_GAME_COLLECTION_ID, "") + val categoryName = requireArguments().getString(EntranceConsts.KEY_GAME_COLLECTION_TITLE, "") mBinding.subjectViewpager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() { override fun onPageSelected(position: Int) { - MtaHelper.onEvent("游戏专题合集", "详情Tab", mSubjectList[position].subjectName) + mSubjectList[position]?.let { + MtaHelper.onEvent("游戏专题合集", "详情Tab", it.subjectName) + NewLogUtils.logColumnCategoryDetailContentClick( + it.subjectName ?: "", it.subjectId ?: "", categoryName, categoryId + ) + } + } }) } @@ -175,8 +184,12 @@ class SubjectTabFragment : BaseFragment() { super.onNightModeChange() for (i in 0 until mBinding.subjectTab.tabCount) { val tab = mBinding.subjectTab.getTabAt(i) ?: continue - tab.customView?.background = if (tab.isSelected) R.drawable.border_round_theme_14.toDrawable(requireContext()) else R.drawable.border_round_eee_14.toDrawable(requireContext()) - tab.customView?.findViewById(R.id.tab_title)?.setTextColor(if (tab.isSelected) R.color.theme_font.toColor() else R.color.text_title.toColor()) + tab.customView?.background = + if (tab.isSelected) R.drawable.border_round_theme_14.toDrawable(requireContext()) else R.drawable.border_round_eee_14.toDrawable( + requireContext() + ) + tab.customView?.findViewById(R.id.tab_title) + ?.setTextColor(if (tab.isSelected) R.color.theme_font.toColor() else R.color.text_title.toColor()) } } }