feat: 游戏单功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-3397

This commit is contained in:
叶子维
2023-10-13 14:20:25 +08:00
parent 0f9f3dc073
commit ebcf2aaa9e
27 changed files with 418 additions and 198 deletions

View File

@ -37,6 +37,7 @@ import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.discovery.DiscoveryActivity
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
@ -58,6 +59,7 @@ import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActi
import com.gh.gamecenter.game.upload.GameSubmissionActivity
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionListDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
@ -154,7 +156,8 @@ object DirectUtils {
"bbs_video",
"explore_column",
"game_explore",
"column_test_v2"
"column_test_v2",
"game_list_collection"
)
fun directToLinkPage(
@ -444,6 +447,14 @@ object DirectUtils {
"qq_mini_game_column" -> directToQGameHome(context)
"game_list_collection" -> directToGameCollectionListDetail(
context,
linkEntity.link ?: "",
linkEntity.text ?: "",
linkEntity.explain,
entrance
)
"" -> {
// do nothing
}
@ -2101,4 +2112,22 @@ object DirectUtils {
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
.navigation()
}
// 跳转游戏单合集详情
@JvmStatic
fun directToGameCollectionListDetail(
context: Context,
collectionId: String,
collectionName: String,
explain: String,
entrance: String = ""
) {
context.startActivity(
GameCollectionListDetailActivity.getIntent(
context,
GameCollectionListEntity(id = collectionId, name = collectionName, explain = explain),
entrance
)
)
}
}

View File

@ -2327,7 +2327,10 @@ object NewFlatLogUtils {
blockId: String,
collectionName: String,
collectionId: String,
text: String
text: String,
linkType: String = "",
linkId: String = "",
linkText: String = ""
) {
val json = json {
KEY_EVENT to "game_list_collection_click"
@ -2337,6 +2340,9 @@ object NewFlatLogUtils {
"game_list_collection_id" to collectionId
"game_list_collection_name" to collectionName
"text" to text
"link_type" to linkType
"link_id" to linkId
"link_text" to linkText
parseAndPutMeta().invoke(this)
}
log(json)

View File

@ -2,11 +2,11 @@ package com.gh.gamecenter.adapter.viewholder
import android.view.View
import android.view.ViewGroup
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.databinding.GameHeadItemBinding
import com.gh.gamecenter.entity.SubjectEntity
@ -31,12 +31,11 @@ class GameHeadViewHolder(var binding: GameHeadItemBinding) :
binding.arrowIv.visibility = View.GONE
val text = if ("change" == subject.home) {
"换一批"
} else if (subject.type == "game_list_collection" && subject.style?.contains("slide") == true) {
"游戏单广场"
} else {
when (subject.home) {
"more" -> "更多"
"hide" -> ""
"game_list_square" -> "游戏单广场"
else -> "全部"
}
}

View File

@ -13,10 +13,11 @@ data class GameCollectionPlayerCreationEntity(
)
@Parcelize
data class GameCollectionHotListTab(
data class GameCollectionListEntity(
@SerializedName("_id")
val id: String = "",
val name: String = "",
val explain: String = "",
var position: Int = -1
) : Parcelable

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
@ -36,4 +37,8 @@ data class HomeContent(
@SerializedName("ad_icon_active")
val adIconActive: Boolean = false,
var style: String = "",
var home: String = "",
@SerializedName("more_link")
var moreLink: LinkEntity? = null,
var explain: String = "", // 游戏单合集说明
)

View File

@ -99,7 +99,9 @@ data class SubjectEntity(
var outerSequence: Int = -1,
@SerializedName("is_qq_column")
var isQQColumn: Boolean = false
var isQQColumn: Boolean = false,
var explain: String = "" // 游戏单合集说明
) : Parcelable {
@IgnoredOnParcel

View File

@ -1286,6 +1286,7 @@ class GameFragmentAdapter(
val buttonType = when (column.home) {
"change" -> "换一批"
"more" -> "更多"
"game_list_square" -> "游戏单广场"
else -> "全部"
}
val moreLink = column.moreLink
@ -1301,12 +1302,62 @@ class GameFragmentAdapter(
}
"more" -> {
if (column.type == "game_list_collection") {
NewFlatLogUtils.logGameListCollectionClick(
"版块内容列表",
mViewModel.blockData?.text ?: "",
mViewModel.blockData?.link ?: "",
column.name ?: "",
column.id ?: "",
"更多",
column.moreLink?.type ?: "",
column.moreLink?.link ?: "",
column.moreLink?.text ?: ""
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "版块"
"block_name" to mViewModel.blockData?.text
"block_id" to mViewModel.blockData?.link
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "更多"
"link_type" to column.moreLink?.type
"link_id" to column.moreLink?.link
"link_text" to column.moreLink?.text
})
}
setPageSwitchData()
column.moreLink?.let { link ->
DirectUtils.directToLinkPage(it.context, link, "(板块)", "(游戏-专题:" + column.name + "-全部)")
}
}
"game_list_square" -> {
NewFlatLogUtils.logGameListCollectionClick(
"版块内容列表",
mViewModel.blockData?.name ?: "",
mViewModel.blockData?.link ?: "",
column.name ?: "",
column.id ?: "",
"游戏单广场"
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "版块"
"block_name" to mViewModel.blockData?.text
"block_id" to mViewModel.blockData?.link
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "游戏单广场"
})
DirectUtils.directToGameCollectionSquare(
mContext,
"版块内容列表",
mViewModel.blockData?.name ?: "",
collectionName = column.name ?: "",
collectionId = column.id ?: ""
)
}
else -> {
setPageSwitchData()
when (column.type) {
@ -1378,28 +1429,12 @@ class GameFragmentAdapter(
}
"game_list_collection" -> {
NewFlatLogUtils.logGameListCollectionClick(
"版块内容列表",
mViewModel.blockData?.name ?: "",
mViewModel.blockData?.link ?: "",
column.name ?: "",
column.id ?: "",
"游戏单广场"
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "版块"
"block_name" to mViewModel.blockData?.text
"block_id" to mViewModel.blockData?.link
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "游戏单广场"
})
DirectUtils.directToGameCollectionSquare(
DirectUtils.directToGameCollectionListDetail(
mContext,
"版块内容列表",
mViewModel.blockData?.name ?: "",
collectionName = column.name ?: "",
collectionId = column.id ?: ""
column.id ?: "",
column.name ?: "",
column.explain,
"版块内容列表"
)
}

View File

@ -1033,7 +1033,10 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
type = subjectEntity.type,
name = subjectEntity.name,
adIconActive = subjectEntity.adIconActive,
style = subjectEntity.style
style = subjectEntity.style,
home = subjectEntity.home ?: "",
moreLink = subjectEntity.moreLink,
explain = subjectEntity.explain
)
mItemDataListCache.add(head)
}

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.gamecollection.hotlist
import android.content.Context
import android.graphics.Typeface
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
@ -23,56 +24,63 @@ import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.ItemGameCollectionHotListBinding
import com.gh.gamecenter.entity.GameCollectionHotListTab
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
class GameCollectionHotListAdapter(
context: Context,
private val mPosition: Int,
private val mTabEntity: GameCollectionHotListTab? = null,
private val mGameCollectionListEntity: GameCollectionListEntity? = null,
private val mViewModel: GameCollectionHotListViewModel,
private val mIsFromDetail: Boolean = false,
private val mEntrance: String,
private val mPath: String,
private val mBasicExposureSource: List<ExposureSource>
) : ListAdapter<GameCollectionListItemData>(context), IExposable {
private val mCoverWidth = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 2
override fun getItemViewType(position: Int): Int {
return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY
return if (isShowHeaderItem() && position == 0) ItemViewType.ITEM_HEADER else if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY
}
private fun isShowHeaderItem() = !mGameCollectionListEntity?.explain.isNullOrEmpty()
private fun getHeaderItemCount() = if (mGameCollectionListEntity?.explain.isNullOrEmpty()) 0 else 1
private fun getRealPosition(position: Int) = position - getHeaderItemCount()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == ItemViewType.ITEM_FOOTER) {
FooterViewHolder(
mLayoutInflater.inflate(
R.layout.refresh_footerview,
parent,
false
return when (viewType) {
ItemViewType.ITEM_FOOTER ->
FooterViewHolder(
mLayoutInflater.inflate(
R.layout.refresh_footerview,
parent,
false
)
)
ItemViewType.ITEM_HEADER -> GameCollectionPlayerCreationAdapter.GameCollectionPlayerCreationHeaderItemViewHolder(
parent.toBinding()
)
} else {
GameCollectionHotListItemViewHolder(parent.toBinding())
else -> GameCollectionHotListItemViewHolder(parent.toBinding())
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is GameCollectionHotListItemViewHolder) {
val itemData = mEntityList[position]
itemData.exposureEvent = ExposureEvent.createEventWithSourceConcat(
GameEntity().apply {
outerSequence = mTabEntity?.position
sequence = position
},
mBasicExposureSource,
listOf(
ExposureSource(
"游戏单",
"${itemData.gameCollectionItem?.title} + ${itemData.gameCollectionItem?.id}"
)
)
)
if (holder is GameCollectionPlayerCreationAdapter.GameCollectionPlayerCreationHeaderItemViewHolder) {
holder.binding.run {
root.setPadding(0, if (mIsFromDetail) 16F.dip2px() else 0, 0, 12F.dip2px())
tipsIv.visibility = View.GONE
tipsTv.text = mGameCollectionListEntity?.explain
tipsTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
}
}
if (holder is GameCollectionHotListItemViewHolder) {
val realPosition = getRealPosition(position)
val itemData = mEntityList[realPosition]
val entity = itemData.gameCollectionItem
holder.binding.run {
root.background = R.drawable.background_shape_white_radius_8.toDrawable(mContext)
@ -80,18 +88,18 @@ class GameCollectionHotListAdapter(
userTv.setTextColor(R.color.text_subtitle.toColor(mContext))
gameCountTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
rankIv.goneIf(position > 2) {
rankIv.goneIf(realPosition > 2 || mIsFromDetail) {
rankIv.setImageResource(
when (position) {
when (realPosition) {
0 -> R.drawable.icon_leaderboard_1
1 -> R.drawable.icon_leaderboard_2
else -> R.drawable.icon_leaderboard_3
}
)
}
rankTv.goneIf(position < 3) {
rankTv.goneIf(realPosition < 3 || mIsFromDetail) {
rankTv.typeface = Typeface.createFromAsset(mContext.assets, "fonts/d_din_bold_only_number.ttf")
rankTv.text = "${position + 1}"
rankTv.text = "${realPosition + 1}"
}
stampIv.goneIf(entity?.stamp.isNullOrEmpty())
stampIv.setBackgroundResource(if (entity?.stamp == "official") R.drawable.label_game_collection_official else R.drawable.label_game_collection_special_choice)
@ -103,23 +111,39 @@ class GameCollectionHotListAdapter(
val gameIcons = arrayListOf(gameImage1, gameImage2, gameImage3)
val games = entity?.games ?: arrayListOf()
val exposureEventList = arrayListOf<ExposureEvent>()
gameIcons.forEachIndexed { index, gameIcon ->
gameIcon.goneIf(games.size < index + 1) {
val gameEntity = games[index].toGameEntity()
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
gameEntity.apply {
outerSequence = mGameCollectionListEntity?.position
sequence = realPosition
},
mBasicExposureSource,
listOf(
ExposureSource(
"游戏单",
"${itemData.gameCollectionItem?.title} + ${itemData.gameCollectionItem?.id}"
)
)
)
exposureEventList.add(exposureEvent)
gameIcon.displayGameIcon(gameEntity)
gameIcon.setBorderColor(R.color.background_white)
gameIcon.setOnClickListener {
NewFlatLogUtils.logGameCollectionHotListClick(
mTabEntity?.name ?: "",
mTabEntity?.id ?: "",
mTabEntity?.name ?: "",
mGameCollectionListEntity?.name ?: "",
mGameCollectionListEntity?.id ?: "",
mGameCollectionListEntity?.name ?: "",
"游戏"
)
SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
"position" to mPosition
"tab_content" to mTabEntity?.name
"game_list_collection_name" to mTabEntity?.name
"game_list_collection_id" to mTabEntity?.id
"tab_content" to mGameCollectionListEntity?.name
"game_list_collection_name" to mGameCollectionListEntity?.name
"game_list_collection_id" to mGameCollectionListEntity?.id
"text" to "游戏"
"game_name" to gameEntity.name
"game_id" to gameEntity.id
@ -128,11 +152,12 @@ class GameCollectionHotListAdapter(
mContext,
gameEntity.id,
BaseActivity.mergeEntranceAndPath(mEntrance, mPath),
itemData.exposureEvent
exposureEvent
)
}
}
}
itemData.exposureEventList = exposureEventList
gameCountTv.goneIf(games.isEmpty())
titleTv.maxLines = if (games.isEmpty()) 2 else 1
titleTv.layoutParams = (titleTv.layoutParams as ConstraintLayout.LayoutParams).apply {
@ -142,16 +167,16 @@ class GameCollectionHotListAdapter(
listOf(userIv, userTv).forEach {
it.setOnClickListener {
NewFlatLogUtils.logGameCollectionHotListClick(
mTabEntity?.name ?: "",
mTabEntity?.id ?: "",
mTabEntity?.name ?: "",
mGameCollectionListEntity?.name ?: "",
mGameCollectionListEntity?.id ?: "",
mGameCollectionListEntity?.name ?: "",
"个人主页"
)
SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
"position" to mPosition
"tab_content" to mTabEntity?.name
"game_list_collection_name" to mTabEntity?.name
"game_list_collection_id" to mTabEntity?.id
"tab_content" to mGameCollectionListEntity?.name
"game_list_collection_name" to mGameCollectionListEntity?.name
"game_list_collection_id" to mGameCollectionListEntity?.id
"text" to "个人主页"
"mongold_id" to entity?.user?.id
})
@ -160,16 +185,16 @@ class GameCollectionHotListAdapter(
}
root.setOnClickListener {
NewFlatLogUtils.logGameCollectionHotListClick(
mTabEntity?.name ?: "",
mTabEntity?.id ?: "",
mTabEntity?.name ?: "",
mGameCollectionListEntity?.name ?: "",
mGameCollectionListEntity?.id ?: "",
mGameCollectionListEntity?.name ?: "",
"游戏单"
)
SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
"position" to mPosition
"tab_content" to mTabEntity?.name
"game_list_collection_name" to mTabEntity?.name
"game_list_collection_id" to mTabEntity?.id
"tab_content" to mGameCollectionListEntity?.name
"game_list_collection_name" to mGameCollectionListEntity?.name
"game_list_collection_id" to mGameCollectionListEntity?.id
"text" to "游戏单"
"game_collect_title" to entity?.title
"game_collect_id" to entity?.id
@ -179,7 +204,16 @@ class GameCollectionHotListAdapter(
entity?.id ?: "",
mEntrance,
mPath,
itemData.exposureEvent
ExposureEvent.createEventWithSourceConcat(
null,
mBasicExposureSource,
listOf(
ExposureSource(
"游戏单",
"${itemData.gameCollectionItem?.title} + ${itemData.gameCollectionItem?.id}"
)
)
)
)
}
}
@ -195,14 +229,23 @@ class GameCollectionHotListAdapter(
}
}
override fun getItemCount(): Int = if (mEntityList.isNotEmpty()) mEntityList.size + 1 else 0
override fun getItemCount(): Int =
if (mEntityList.isNotEmpty()) mEntityList.size + FOOTER_ITEM_COUNT + getHeaderItemCount() else 0
override fun getEventByPosition(pos: Int): ExposureEvent? {
return mEntityList[pos].exposureEvent
return if (getRealPosition(pos) in 0 until mEntityList.size) {
mEntityList[pos].exposureEvent
} else {
null
}
}
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
return mEntityList[pos].exposureEventList
return if (getRealPosition(pos) in 0 until mEntityList.size) {
mEntityList[pos].exposureEventList
} else {
null
}
}
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
@ -211,7 +254,7 @@ class GameCollectionHotListAdapter(
if (layoutManager is GridLayoutManager) {
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (getItemViewType(position) == ItemViewType.ITEM_FOOTER) {
if (getItemViewType(position) == ItemViewType.ITEM_FOOTER || getItemViewType(position) == ItemViewType.ITEM_HEADER) {
return layoutManager.spanCount
}
return 1

View File

@ -17,7 +17,7 @@ import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.FixGridLayoutManager
import com.gh.gamecenter.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.core.utils.TimeElapsedHelper
import com.gh.gamecenter.entity.GameCollectionHotListTab
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, GameCollectionHotListViewModel>() {
@ -25,9 +25,9 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
private lateinit var mExposureListener: ExposureListener
private lateinit var mViewModel: GameCollectionHotListViewModel
private var mAdapter: GameCollectionHotListAdapter? = null
private var mTabEntity: GameCollectionHotListTab? = null
private var mGameCollectionListEntity: GameCollectionListEntity? = null
private val mElapsedHelper by lazy { TimeElapsedHelper() }
private var mIsLoadDone = false
private var mCanShowList = false
private var mPosition = -1
override fun provideListAdapter(): GameCollectionHotListAdapter {
@ -35,8 +35,9 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
mAdapter = GameCollectionHotListAdapter(
requireContext(),
mPosition,
mTabEntity,
mGameCollectionListEntity,
mViewModel,
requireActivity() is GameCollectionListDetailActivity,
mEntrance,
arguments?.getString(EntranceConsts.KEY_PATH) ?: "",
mBasicExposureSource
@ -46,16 +47,23 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
}
override fun provideListViewModel(): GameCollectionHotListViewModel {
mViewModel = viewModelProvider(GameCollectionHotListViewModel.Factory(mTabEntity?.id ?: ""))
mViewModel = viewModelProvider(GameCollectionHotListViewModel.Factory(mGameCollectionListEntity?.id ?: ""))
return mViewModel
}
override fun onCreate(savedInstanceState: Bundle?) {
mTabEntity = requireArguments().getParcelable(EntranceConsts.KEY_TAB)
mCanShowList = requireActivity() is GameCollectionListDetailActivity
mGameCollectionListEntity = requireArguments().getParcelable(GameCollectionListEntity::class.java.simpleName)
mPosition = requireArguments().getInt(EntranceConsts.KEY_POSITION)
mBasicExposureSource =
listOf(ExposureSource("游戏单热榜", ""), ExposureSource("游戏单合集", mTabEntity?.id ?: ""))
mBasicExposureSource = if (requireActivity() is GameCollectionListDetailActivity) {
listOf(ExposureSource("游戏单合集", mGameCollectionListEntity?.id ?: ""), ExposureSource("合集详情", ""))
} else {
listOf(ExposureSource("游戏单热榜", ""), ExposureSource("游戏单合集", mGameCollectionListEntity?.id ?: ""))
}
super.onCreate(savedInstanceState)
if (requireActivity() is GameCollectionListDetailActivity) {
setNavigationTitle(mGameCollectionListEntity?.name)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -75,7 +83,13 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
}
override fun getItemDecoration(): RecyclerView.ItemDecoration {
return GridSpacingItemDecoration(2, 8F.dip2px(), false, 0)
return GridSpacingItemDecoration(
2,
8F.dip2px(),
false,
0,
if (mGameCollectionListEntity?.explain.isNullOrEmpty()) 0 else 1
)
}
override fun onPause() {
@ -84,16 +98,16 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
if (mElapsedHelper.elapsedTime >= 3) {
NewFlatLogUtils.logGameCollectionHotListTabView(
mElapsedHelper.elapsedTime,
mTabEntity?.name ?: "",
mTabEntity?.id ?: "",
mTabEntity?.name ?: ""
mGameCollectionListEntity?.name ?: "",
mGameCollectionListEntity?.id ?: "",
mGameCollectionListEntity?.name ?: ""
)
SensorsBridge.trackEvent("ViewGameCollectHotRankTab", json {
"stay_length" to mElapsedHelper.elapsedTime
"position" to mPosition
"tab_content" to mTabEntity?.name
"game_list_collection_name" to mTabEntity?.name
"game_list_collection_id" to mTabEntity?.id
"tab_content" to mGameCollectionListEntity?.name
"game_list_collection_name" to mGameCollectionListEntity?.name
"game_list_collection_id" to mGameCollectionListEntity?.id
})
}
}
@ -103,17 +117,15 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
mElapsedHelper.resetCounting()
mElapsedHelper.resumeCounting()
if (mIsLoadDone) {
onChanged(mViewModel.obsListData.value)
if (!mCanShowList) {
mCanShowList = true
mViewModel.obsListData.value?.let { onChanged(it) }
}
}
override fun onChanged(ts: MutableList<GameCollectionListItemData>?) {
if (ts != null) {
if (mIsLoadDone) {
super.onChanged(ts)
}
mIsLoadDone = true
if (ts != null && mCanShowList) {
super.onChanged(ts)
}
}

View File

@ -18,7 +18,7 @@ import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.FragmentGameCollectionHotListWrapperBinding
import com.gh.gamecenter.entity.GameCollectionHotListTab
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import kotlin.math.abs
@ -28,7 +28,7 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
private lateinit var mBinding: FragmentGameCollectionHotListWrapperBinding
private lateinit var mViewModel: GameCollectionHotListWrapperViewModel
private val mTabEntityList = arrayListOf<GameCollectionHotListTab>()
private val mTabEntityList = arrayListOf<GameCollectionListEntity>()
private var mAdapter: FragmentStateAdapter? = null
@ -55,7 +55,7 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
mViewModel.hotListTabListLiveData.observe(this) {
if (it != null) {
mTabEntityList.clear()
mTabEntityList.add(GameCollectionHotListTab(name = PLAYER_CREATION_TAB_NAME, position = 0))
mTabEntityList.add(GameCollectionListEntity(name = PLAYER_CREATION_TAB_NAME, position = 0))
mTabEntityList.addAll(it)
initViewPager()
@ -76,6 +76,8 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
override fun initRealView() {
super.initRealView()
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
changeToolbarStyle(mIsCollapsed)
mBinding.run {
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
(toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
@ -88,21 +90,15 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
collapsingToolbar.scrimShownAction = {
mIsCollapsed = it
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && it)
changeToolbarStyle(it)
if (mIsCollapsed != it) {
mIsCollapsed = it
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && it)
changeToolbarStyle(it)
}
}
appbar.addOnOffsetChangedListener { _, verticalOffset ->
val absOffset = abs(verticalOffset)
val invisibleOffset = DisplayUtils.dip2px(30F)
if (absOffset <= invisibleOffset) {
titleTv.alpha = 1 - (absOffset.toFloat() / invisibleOffset)
} else {
titleTv.alpha = 0F
}
val currentFragment = childFragmentManager.findFragmentByTag("f${mBinding.viewPager.currentItem}")
if (currentFragment is GameCollectionPlayerCreationFragment) {
currentFragment.setListRefreshEnable(absOffset <= 2)
@ -216,7 +212,7 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
} else {
GameCollectionHotListFragment().with(
bundleOf(
EntranceConsts.KEY_TAB to tabEntity,
GameCollectionListEntity::class.java.simpleName to tabEntity,
EntranceConsts.KEY_POSITION to position,
EntranceConsts.KEY_ENTRANCE to mEntrance,
EntranceConsts.KEY_PATH to "游戏单热榜"
@ -234,6 +230,7 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
override fun onDarkModeChanged() {
super.onDarkModeChanged()
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
changeToolbarStyle(mIsCollapsed)
for (i in 0 until mBinding.tabLayout.tabCount) {
val tab = mBinding.tabLayout.getTabAt(i)
if (tab != null) {

View File

@ -3,18 +3,16 @@ package com.gh.gamecenter.gamecollection.hotlist
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.entity.GameCollectionHotListTab
import com.gh.gamecenter.entity.GameCollectionPlayerCreationEntity
import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import retrofit2.HttpException
class GameCollectionHotListWrapperViewModel(application: Application) : AndroidViewModel(application) {
private val mApi = RetrofitManager.getInstance().api
val hotListTabListLiveData = MutableLiveData<List<GameCollectionHotListTab>?>()
val hotListTabListLiveData = MutableLiveData<List<GameCollectionListEntity>?>()
init {
getGameCollectionHotListTab()
@ -23,11 +21,11 @@ class GameCollectionHotListWrapperViewModel(application: Application) : AndroidV
fun getGameCollectionHotListTab() {
mApi.gameCollectionHotListTab
.compose(observableToMain())
.subscribe(object : Response<List<GameCollectionHotListTab>>() {
override fun onResponse(response: List<GameCollectionHotListTab>?) {
.subscribe(object : Response<List<GameCollectionListEntity>>() {
override fun onResponse(response: List<GameCollectionListEntity>?) {
super.onResponse(response)
response?.let {
val hotListTabList = ArrayList<GameCollectionHotListTab>()
val hotListTabList = ArrayList<GameCollectionListEntity>()
it.forEachIndexed { index, entity ->
hotListTabList.add(entity.apply {
position = index + 1

View File

@ -0,0 +1,36 @@
package com.gh.gamecenter.gamecollection.hotlist
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.entity.GameCollectionListEntity
class GameCollectionListDetailActivity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
updateStatusBarColor()
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
updateStatusBarColor()
}
companion object {
fun getIntent(context: Context, entity: GameCollectionListEntity, entrance: String): Intent {
val bundle = Bundle()
bundle.putParcelable(GameCollectionListEntity::class.java.simpleName, entity)
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
bundle.putString(EntranceConsts.KEY_PATH, "游戏单合集详情")
return getTargetIntent(
context,
GameCollectionListDetailActivity::class.java,
GameCollectionHotListFragment::class.java,
bundle
)
}
}
}

View File

@ -47,7 +47,7 @@ import java.lang.ref.WeakReference
class GameCollectionSquareAdapter(
context: Context,
private val isHome: Boolean = false,
private val mIsHome: Boolean = false,
private val mFragment: GameCollectionSquareFragment,
private val mViewModel: GameCollectionSquareViewModel,
private var mBasicExposureSource: List<ExposureSource>,
@ -65,7 +65,7 @@ class GameCollectionSquareAdapter(
}
// 避免首页游戏单广场刷新列表后出现异常跳转位置
if (isHome && mEntityList.size == 2 && updateData.size > mEntityList.size) {
if (mIsHome && mEntityList.size == 2 && updateData.size > mEntityList.size) {
mEntityList = ArrayList(updateData)
notifyItemRangeInserted(2, updateData.size - 1)
return
@ -82,21 +82,21 @@ class GameCollectionSquareAdapter(
}
fun setAmwayList(amwayList: List<AmwayCommentEntity>) {
if (isHome && mEntityList.isNotEmpty() && mEntityList[0].amwayListItem.isNullOrEmpty()) {
if (mIsHome && mEntityList.isNotEmpty() && mEntityList[0].amwayListItem.isNullOrEmpty()) {
mEntityList[0].amwayListItem = amwayList
notifyItemChanged(0)
}
}
fun setBannerList(bannerList: List<CarouselEntity>) {
if (isHome && mEntityList.isNotEmpty() && mEntityList[0].carouselListItem.isNullOrEmpty()) {
if (mIsHome && mEntityList.isNotEmpty() && mEntityList[0].carouselListItem.isNullOrEmpty()) {
mEntityList[0].carouselListItem = bannerList
notifyItemChanged(0)
}
}
fun setHotListTabName(tabName: String) {
if (isHome && mEntityList.isNotEmpty() && mEntityList[0].hotListTabName.isEmpty()) {
if (mIsHome && mEntityList.isNotEmpty() && mEntityList[0].hotListTabName.isEmpty()) {
mEntityList[0].hotListTabName = tabName
notifyItemChanged(0)
}
@ -125,7 +125,7 @@ class GameCollectionSquareAdapter(
override fun getItemViewType(position: Int): Int {
if (isHome) {
if (mIsHome) {
if (position == 0) return ItemViewType.ITEM_HEADER
if (position == 1) return ITEM_FILTER
if (position == itemCount - 1) return ItemViewType.ITEM_FOOTER
@ -191,7 +191,7 @@ class GameCollectionSquareAdapter(
}
itemData.exposureEventList = exposureEventList
itemData.gameCollectionItem?.let {
holder.bindGameCollection(mViewModel, it, itemData, isHome, ArrayList(mBasicExposureSource).apply {
holder.bindGameCollection(mViewModel, it, itemData, ArrayList(mBasicExposureSource).apply {
addAll(exposureSource)
})
}
@ -209,7 +209,7 @@ class GameCollectionSquareAdapter(
}
override fun getItemCount() =
if (mEntityList.isNullOrEmpty()) 0 else if (isHome && mEntityList.size == 2) mEntityList.size else mEntityList.size + 1
if (mEntityList.isNullOrEmpty()) 0 else if (mIsHome && mEntityList.size == 2) mEntityList.size else mEntityList.size + 1
class GameCollectionHeaderItemViewHolder(val binding: ItemGameCollectionHeaderBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -431,7 +431,6 @@ class GameCollectionSquareAdapter(
viewModel: GameCollectionSquareViewModel,
gamesCollectionEntity: GamesCollectionEntity,
itemData: GameCollectionListItemData,
isHome: Boolean,
exposureSource: List<ExposureSource>
) {
binding.run {
@ -557,7 +556,7 @@ class GameCollectionSquareAdapter(
GameCollectionDetailActivity.getIntent(
context,
gamesCollectionEntity.id,
isFromSquare = !isHome,
isFromSquare = true,
exposureSourceList = ArrayList(exposureSource)
)
)

View File

@ -132,8 +132,8 @@ class GameCollectionSquareViewModel(application: Application) :
private fun getGameCollectionHotListTab() {
mApi.gameCollectionHotListTab
.compose(observableToMain())
.subscribe(object : Response<List<GameCollectionHotListTab>>() {
override fun onResponse(response: List<GameCollectionHotListTab>?) {
.subscribe(object : Response<List<GameCollectionListEntity>>() {
override fun onResponse(response: List<GameCollectionListEntity>?) {
super.onResponse(response)
response?.firstOrNull()?.let {
hotListFirstTab.postValue(it.name)

View File

@ -771,20 +771,6 @@ class DescAdapter(
rightMargin = 0
}
containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)
val exposureEventList = arrayListOf<ExposureEvent>()
recommendGameList.forEachIndexed { index, entity ->
val event = ExposureEvent.createEvent(
gameEntity = GameEntity().apply {
sequence = index
},
source = listOf(
ExposureSource("游戏详情", "$mGameName+$mGameId"),
ExposureSource("游戏单", "${entity.title}+${entity.id}")
)
)
exposureEventList.add(event)
ExposureManager.log(event)
}
layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
if (adapter == null) {

View File

@ -2,16 +2,19 @@ package com.gh.gamecenter.gamedetail.desc
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.ExposureManager
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.GamedetailItemGameCollectionBinding
import com.gh.gamecenter.entity.GameDetailRecommendGameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
class GameCollectionAdapter(
private val mRecommendGameList: ArrayList<GameDetailRecommendGameEntity>,
@ -45,8 +48,27 @@ class GameCollectionAdapter(
val games = RegionSettingHelper.filterSimpleGame(entity.games)
gameIcons.forEachIndexed { index, gameIcon ->
gameIcon.goneIf(games.size < index + 1) {
gameIcon.displayGameIcon(games[index].toGameEntity())
val gameEntity = games[index].toGameEntity()
val event = ExposureEvent.createEvent(
gameEntity = gameEntity.apply {
sequence = position
},
source = listOf(
ExposureSource("游戏详情", "$mGameName+$mGameId"),
ExposureSource("游戏单", "${entity.title}+${entity.id}")
)
)
ExposureManager.log(event)
gameIcon.displayGameIcon(gameEntity)
gameIcon.setBorderColor(R.color.background_white)
gameIcon.setOnClickListener {
GameDetailActivity.startGameDetailActivity(
root.context,
games[index].id ?: "",
BaseActivity.mergeEntranceAndPath(mEntrance, "游戏详情"),
event
)
}
}
}
gameCountTv.text = "+${entity.count.game - games.size}"

View File

@ -933,7 +933,10 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
type = linkType,
name = homeContent.linkText,
adIconActive = adIconActive,
style = homeContent.style
style = homeContent.style,
home = homeContent.home,
moreLink = homeContent.moreLink,
explain = homeContent.explain
)
mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData)
mSnapshotItemList.add(head)

View File

@ -694,6 +694,7 @@ class LegacyHomeFragmentAdapterAssistant(
val buttonType = when (column.home) {
"change" -> "换一批"
"more" -> "更多"
"game_list_square" -> "游戏单广场"
else -> "全部"
}
val moreLink = column.moreLink
@ -709,9 +710,53 @@ class LegacyHomeFragmentAdapterAssistant(
(mAdapter as HomeFragmentAdapter).viewModel.changeSubjectGame(column.id!!)
}
} else if ("more" == column.home) {
if (column.type == "game_list_collection") {
NewFlatLogUtils.logGameListCollectionClick(
"首页内容列表",
"",
"",
column.name ?: "",
column.id ?: "",
"更多",
column.moreLink?.type ?: "",
column.moreLink?.link ?: "",
column.moreLink?.text ?: ""
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "首页"
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "更多"
"link_type" to column.moreLink?.type
"link_id" to column.moreLink?.link
"link_text" to column.moreLink?.text
})
}
column.moreLink?.let { link ->
DirectUtils.directToLinkPage(it.context, link, "(首页)", "(游戏-专题:" + column.name + "-全部)")
}
} else if ("game_list_square" == column.home) {
NewFlatLogUtils.logGameListCollectionClick(
"首页内容列表",
"",
"",
column.name ?: "",
column.id ?: "",
"游戏单广场"
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "首页"
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "游戏单广场"
})
DirectUtils.directToGameCollectionSquare(
mContext,
"首页内容列表",
column.name ?: "",
collectionId = column.id ?: "",
collectionName = column.name ?: ""
)
} else {
setPageSwitchData()
if (column.type == "column_collection") {
@ -768,26 +813,12 @@ class LegacyHomeFragmentAdapterAssistant(
text = "全部"
)
} else if (column.type == "game_list_collection") {
NewFlatLogUtils.logGameListCollectionClick(
"首页内容列表",
"",
"",
column.name ?: "",
column.id ?: "",
"游戏单广场"
)
SensorsBridge.trackEvent("GameListCollectionClick", json {
"location" to "首页"
"game_list_collection_name" to column.name
"game_list_collection_id" to column.id
"text" to "游戏单广场"
})
DirectUtils.directToGameCollectionSquare(
DirectUtils.directToGameCollectionListDetail(
mContext,
"首页内容列表",
column.id ?: "",
column.name ?: "",
collectionId = column.id ?: "",
collectionName = column.name ?: ""
column.explain,
"首页内容列表"
)
} else if (column.type == "column_test_v2") {
//跳转到新游开测页面

View File

@ -19,11 +19,8 @@ import com.gh.gamecenter.entity.BlockEntity;
import com.gh.gamecenter.entity.CarouselEntity;
import com.gh.gamecenter.entity.CatalogEntity;
import com.gh.gamecenter.entity.CategoryEntity;
import com.gh.gamecenter.feature.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.CommentnumEntity;
import com.gh.gamecenter.entity.CommonCollectionContentEntity;
import com.gh.gamecenter.entity.CommonCollectionEntity;
import com.gh.gamecenter.feature.entity.ConcernEntity;
import com.gh.gamecenter.entity.DefaultAvatar;
import com.gh.gamecenter.entity.DeviceDialogEntity;
import com.gh.gamecenter.entity.DialogEntity;
@ -37,7 +34,7 @@ import com.gh.gamecenter.entity.ForumDetailEntity;
import com.gh.gamecenter.entity.ForumEntity;
import com.gh.gamecenter.entity.ForumUnreadEntity;
import com.gh.gamecenter.entity.GameCollectionCoverEntity;
import com.gh.gamecenter.entity.GameCollectionHotListTab;
import com.gh.gamecenter.entity.GameCollectionListEntity;
import com.gh.gamecenter.entity.GameCollectionPlayerCreationEntity;
import com.gh.gamecenter.entity.GameCollectionTagEntity;
import com.gh.gamecenter.entity.GameColumnCollection;
@ -55,10 +52,6 @@ import com.gh.gamecenter.entity.HomeItemTestV2Entity;
import com.gh.gamecenter.entity.ImageInfoEntity;
import com.gh.gamecenter.entity.InterestedGameEntity;
import com.gh.gamecenter.entity.LibaoDetailEntity;
import com.gh.gamecenter.feature.entity.LibaoEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MessageUnreadCount;
import com.gh.gamecenter.feature.entity.MessageUnreadEntity;
import com.gh.gamecenter.entity.MyVideoEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
@ -93,7 +86,6 @@ import com.gh.gamecenter.entity.VideoDataOverViewEntity;
import com.gh.gamecenter.entity.VideoDraftEntity;
import com.gh.gamecenter.entity.VideoEntity;
import com.gh.gamecenter.entity.VideoTagEntity;
import com.gh.gamecenter.feature.entity.ViewsEntity;
import com.gh.gamecenter.entity.VoteEntity;
import com.gh.gamecenter.feature.entity.AnswerEntity;
import com.gh.gamecenter.feature.entity.ApkEntity;
@ -102,8 +94,15 @@ import com.gh.gamecenter.feature.entity.ArticleEntity;
import com.gh.gamecenter.feature.entity.AuthDialogEntity;
import com.gh.gamecenter.feature.entity.AvatarBorderEntity;
import com.gh.gamecenter.feature.entity.BackgroundImageEntity;
import com.gh.gamecenter.feature.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.CommentnumEntity;
import com.gh.gamecenter.feature.entity.ConcernEntity;
import com.gh.gamecenter.feature.entity.ForumVideoEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.LibaoEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MessageUnreadCount;
import com.gh.gamecenter.feature.entity.MessageUnreadEntity;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.feature.entity.PersonalEntity;
import com.gh.gamecenter.feature.entity.QuestionDraftEntity;
@ -111,11 +110,11 @@ import com.gh.gamecenter.feature.entity.Questions;
import com.gh.gamecenter.feature.entity.ServerCalendarEntity;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.entity.ViewsEntity;
import com.gh.gamecenter.gamedetail.entity.BigEvent;
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.personalhome.rating.MyRating;
import com.gh.gamecenter.qa.entity.TopCommunityCategory;
import com.gh.gamecenter.qa.entity.AnswerDetailEntity;
import com.gh.gamecenter.qa.entity.AnswerDraftEntity;
import com.gh.gamecenter.qa.entity.ArticleDetailEntity;
@ -124,6 +123,7 @@ import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity;
import com.gh.gamecenter.qa.entity.InviteEntity;
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity;
import com.gh.gamecenter.qa.entity.QuestionsIndexEntity;
import com.gh.gamecenter.qa.entity.TopCommunityCategory;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@ -3112,7 +3112,7 @@ public interface ApiService {
* 游戏单热榜-游戏单榜单tab
*/
@GET("game_lists/collections/hot_list/tab")
Observable<List<GameCollectionHotListTab>> getGameCollectionHotListTab();
Observable<List<GameCollectionListEntity>> getGameCollectionHotListTab();
/**
* 游戏单热榜-玩家创作榜