feat: 搜索业务-新增搜索发现取代热门标签—客户端 https://jira.shanqu.cc/browse/GHZSCY-5572

This commit is contained in:
曾祥俊
2024-12-09 10:27:39 +08:00
parent 44d93b7527
commit 1002d02f12
12 changed files with 296 additions and 53 deletions

View File

@ -72,6 +72,7 @@ android_build:
only:
- dev
- release
- feat/GHZSCY-6953
# 代码检查
sonarqube_analysis:
@ -157,3 +158,4 @@ oss-upload&send-email:
only:
- dev
- release
- feat/GHZSCY-6953

View File

@ -191,6 +191,7 @@ open class SearchActivity : BaseActivity() {
when (type) {
SearchType.AUTO -> handleAutoSearch(key)
SearchType.DEFAULT -> handleDefaultSearch(key)
SearchType.DISCOVERY -> handleDiscoverySearch(key)
SearchType.RANK -> handleRankSearch(key)
SearchType.HOT -> handleHotSearch(key)
SearchType.HISTORY -> handleHistorySearch(key)
@ -244,6 +245,22 @@ open class SearchActivity : BaseActivity() {
)
}
protected open fun handleDiscoverySearch(key: String?) {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "搜索发现")
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_DISCOVERY,
mSourceEntrance
)
}
protected open fun handleDefaultSearch(key: String?) {
mSearchKey = key
searchEt.setText(key)
@ -391,6 +408,7 @@ open class SearchActivity : BaseActivity() {
SearchType.HISTORY.value -> search(SearchType.HISTORY, search.key)
SearchType.HOT.value -> search(SearchType.HOT, search.key)
SearchType.RANK.value -> search(SearchType.RANK, search.key)
SearchType.DISCOVERY.value -> search(SearchType.DISCOVERY, search.key)
"click" -> DataCollectionUtils.uploadSearchClick(
this, mSearchKey, mSearchType.value, "搜索页面",
@ -435,6 +453,7 @@ open class SearchActivity : BaseActivity() {
const val TRACK_SEARCH_TYPE_DEFAULT = "默认搜索"
const val TRACK_SEARCH_TYPE_HISTORY = "历史搜索"
const val TRACK_SEARCH_TYPE_RANK = "榜单搜索"
const val TRACK_SEARCH_TYPE_DISCOVERY = "搜索发现"
@JvmStatic
fun toTrackSearchType(type: String) = when (type) {
@ -442,6 +461,7 @@ open class SearchActivity : BaseActivity() {
SearchType.MANUAL.value -> TRACK_SEARCH_TYPE_INPUT
SearchType.HISTORY.value -> TRACK_SEARCH_TYPE_HISTORY
SearchType.RANK.value -> TRACK_SEARCH_TYPE_RANK
SearchType.DISCOVERY.value -> TRACK_SEARCH_TYPE_DISCOVERY
else -> TRACK_SEARCH_TYPE_DEFAULT
}
@ -491,7 +511,8 @@ enum class SearchType(var value: String) {
HISTORY("history"),
MANUAL("initiative"),
HOT("remen"),
RANK("rank");
RANK("rank"),
DISCOVERY("dicovery");
fun toChinese() = when (this) {
AUTO -> "自动搜索"
@ -500,6 +521,7 @@ enum class SearchType(var value: String) {
MANUAL -> "主动搜索"
HOT -> "热门搜索"
RANK -> "榜单搜索"
DISCOVERY -> "搜索发现"
}
companion object {

View File

@ -39,8 +39,8 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
override fun initView() {
mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
mBinding.hotTagHeadContainer.root.visibility = View.GONE
mBinding.hotTagFlexContainer.visibility = View.GONE
mBinding.hotAndDiscoveryTagHeadContainer.root.visibility = View.GONE
mBinding.hotAndDiscoveryTagFlexContainer.visibility = View.GONE
if (mEntrance == "论坛首页" || mEntrance == "搜索栏") {
mBinding.hotHeadContainer.headTitle.text = "热门论坛"
mViewModel.getForumSearchHotContent()

View File

@ -1,10 +1,9 @@
package com.gh.gamecenter.search
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Shader
import android.graphics.Typeface
import android.graphics.*
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
@ -14,6 +13,7 @@ import android.widget.CheckedTextView
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.viewpager.widget.PagerAdapter
import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureManager
@ -22,6 +22,7 @@ import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.exposure.ExposureSource
@ -35,6 +36,7 @@ import com.gh.gamecenter.databinding.TabItemSearchDefaultRankBinding
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.feature.entity.DiscoveryTagEntity
import com.gh.gamecenter.feature.entity.HotTagEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
@ -48,6 +50,7 @@ import org.json.JSONObject
open class SearchDefaultFragment : BaseFragment<Any>() {
private var mHotTagList: List<HotTagEntity>? = null
private var mDiscoveryTagList: List<DiscoveryTagEntity>? = null
protected var mRankList: List<SettingsEntity.Search.RankList>? = null
protected lateinit var mBinding: FragmentSearchDefaultBinding
@ -64,10 +67,11 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
// FlexboxLayout:maxLine 不符合需求
protected val mFlexMaxHeight = DisplayUtils.dip2px(57F)
protected val mHotAndDiscoveryFlexMaxHeight = DisplayUtils.dip2px(88F)
private val mDao by lazy { provideDao() }
private val mHotTagClickListener: (Int) -> Unit = {
val tag = mHotTagList!![it]
private val mHotTagClickListener: (HotTagEntity) -> Unit = { tag ->
NewFlatLogUtils.logSearchHotTagClick(
tag.name ?: "",
tag.type ?: "",
@ -90,6 +94,29 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
DirectUtils.directToLinkPage(requireContext(), tag, "(搜索-${tag.name})", "", exposureEvent) // 不需要path
}
private val mDiscoveryTagClickListener: (DiscoveryTagEntity, Int) -> Unit = { tag, position ->
val keyword = tag.keyword
if (keyword.isNotEmpty()) {
PageSwitchDataHelper.pushCurrentPageData(
hashMapOf(
Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-搜索发现"),
Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.text ?: " ")
)
)
SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.text ?: "", "label_id", tag.id ?: "")
SensorsBridge.trackSearchDiscoveryClick(
labelName = tag.text ?: "",
labelId = tag.id ?: "",
searchContent = keyword,
position = position
)
mViewModel?.add(keyword)
EventBus.getDefault().post(EBSearch(SearchType.DISCOVERY.value, keyword))
Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
}
}
override fun getLayoutId(): Int {
return R.layout.fragment_search_default
}
@ -141,15 +168,23 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
mViewModel?.isExistRankList = mRankList?.isNotEmpty() == true
mHotTagList = Config.getSettings()?.search?.hotTag
mViewModel?.isExistHotTag = mHotTagList?.isNotEmpty() == true
mDiscoveryTagList = Config.getSettings()?.search?.discoveryTag
mViewModel?.isExistHotAndDiscoveryTag =
mHotTagList?.isNotEmpty() == true || mDiscoveryTagList?.isNotEmpty() == true
updateHistorySearchView(null)
mViewModel?.historySearchLiveData?.observe(viewLifecycleOwner) {
updateHistorySearchView(it)
}
mBinding.hotTagFlexContainer.setLimitHeight(mFlexMaxHeight)
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
mBinding.hotAndDiscoveryTagFlexContainer.setLimitHeight(mHotAndDiscoveryFlexMaxHeight)
createHotAndDiscoveryFlexContent(
mBinding.hotAndDiscoveryTagFlex,
getHotTagList(),
getDiscoveryTagList(),
hotTagClickListener = mHotTagClickListener,
discoveryTagClickListener = mDiscoveryTagClickListener
)
initHeadView()
initRankViewPager()
}
@ -181,9 +216,9 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
mBinding.hotHeadContainer.headTitle.text = getString(R.string.search_hot)
mBinding.hotHeadContainer.headTitle.textSize = 16F
mBinding.hotHeadContainer.headActionTv.visibility = View.GONE
mBinding.hotTagHeadContainer.headTitle.text = getString(R.string.search_hot_tag)
mBinding.hotTagHeadContainer.headTitle.textSize = 16F
mBinding.hotTagHeadContainer.headActionTv.visibility = View.GONE
mBinding.hotAndDiscoveryTagHeadContainer.headTitle.text = getString(R.string.search_discovery_tag)
mBinding.hotAndDiscoveryTagHeadContainer.headTitle.textSize = 16F
mBinding.hotAndDiscoveryTagHeadContainer.headActionTv.visibility = View.GONE
}
protected open fun initRankViewPager() {
@ -318,8 +353,8 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
mBinding.historyHeadContainer.root.visibility =
if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
mBinding.historyFlex.visibility = if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
mBinding.hotTagHeadContainer.root.layoutParams =
(mBinding.hotTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
mBinding.hotAndDiscoveryTagHeadContainer.root.layoutParams =
(mBinding.hotAndDiscoveryTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
setMargins(
0,
if (mViewModel?.isExistHistory == true) 16F.dip2px() else 0,
@ -331,14 +366,15 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
(mBinding.hotHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
setMargins(
0,
if (mViewModel?.isExistHistory == false && mViewModel?.isExistHotTag == false) 16F.dip2px() else 0,
if (mViewModel?.isExistHistory == false && mViewModel?.isExistHotAndDiscoveryTag == false) 16F.dip2px() else 0,
0,
0
)
}
mBinding.hotTagHeadContainer.root.visibility =
if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
mBinding.hotTagFlex.visibility = if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
mBinding.hotAndDiscoveryTagHeadContainer.root.visibility =
if (mViewModel?.isExistHotAndDiscoveryTag == true) View.VISIBLE else View.GONE
mBinding.hotAndDiscoveryTagFlex.visibility =
if (mViewModel?.isExistHotAndDiscoveryTag == true) View.VISIBLE else View.GONE
mBinding.hotHeadContainer.root.visibility =
if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
mBinding.hotList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
@ -361,20 +397,31 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
}
}
private fun getTagListString(): List<String> {
val list = ArrayList<String>()
private fun getHotTagList(): List<HotTagEntity> {
val list = ArrayList<HotTagEntity>()
if (mHotTagList != null) {
for (entity in mHotTagList!!) {
entity.name?.let { list.add(it) }
if (list.size == 8) break // 最多显示8个热门标签
entity.name?.let { list.add(entity) }
}
}
return list
}
private fun getDiscoveryTagList(): List<DiscoveryTagEntity> {
val list = ArrayList<DiscoveryTagEntity>()
if (mDiscoveryTagList != null) {
for (entity in mDiscoveryTagList!!) {
entity.text?.let { list.add(entity) }
}
}
return list
}
fun createFlexContent(
flexView: FlexboxLayout,
contentList: List<String>?,
isHotTag: Boolean = false,
clickListener: (Int) -> Unit
) {
@ -388,16 +435,12 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px())
flexCell.layoutParams = params
if (isHotTag && !mHotTagList.isNullOrEmpty() && mHotTagList!![index].isGuessSearch) {
createSmartHotTagStyle(flexCell, contentList[index])
} else {
flexCell.setSingleLine()
flexCell.ellipsize = TextUtils.TruncateAt.END
flexCell.gravity = Gravity.CENTER
flexCell.textSize = 12F
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
}
flexCell.setSingleLine()
flexCell.ellipsize = TextUtils.TruncateAt.END
flexCell.gravity = Gravity.CENTER
flexCell.textSize = 12F
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
@ -409,16 +452,84 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
}
}
private fun createSmartHotTagStyle(flexCell: TextView, name: String) {
flexCell.setDrawableStart(R.drawable.ic_smart_search)
private fun createHotAndDiscoveryFlexContent(
flexView: FlexboxLayout,
hotTagList: List<HotTagEntity>,
discoveryTagList: List<DiscoveryTagEntity>,
hotTagClickListener: (HotTagEntity) -> Unit,
discoveryTagClickListener: (DiscoveryTagEntity, Int) -> Unit
) {
if (hotTagList.isEmpty() && discoveryTagList.isEmpty()) return
flexView.removeAllViews()
createHotFlexContent(flexView, hotTagList, hotTagClickListener)
createDiscoveryFlexContent(flexView, discoveryTagList, discoveryTagClickListener)
}
private fun createHotFlexContent(
flexView: FlexboxLayout,
contentList: List<HotTagEntity>?,
clickListener: (HotTagEntity) -> Unit
) {
if (contentList.isNullOrEmpty()) return
for (index in 0 until contentList.count()) {
val flexCell = TextView(context)
flexView.addView(flexCell)
flexCell.layoutParams = FlexboxLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px()
)
createSmartHotTagStyle(flexCell, contentList[index])
flexCell.setOnClickListener {
clickListener.invoke(contentList[index])
}
}
}
private fun createDiscoveryFlexContent(
flexView: FlexboxLayout,
contentList: List<DiscoveryTagEntity>?,
clickListener: (DiscoveryTagEntity, Int) -> Unit
) {
if (contentList.isNullOrEmpty()) return
for (index in 0 until contentList.count()) {
val flexCell = TextView(context)
flexView.addView(flexCell)
flexCell.layoutParams = FlexboxLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px()
)
createSmartDiscoverTagStyle(flexCell, contentList[index])
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
cornerRadius = 999F
} else DrawableView.getStrokeDrawable(com.gh.gamecenter.common.R.color.text_dddddd, 0.5F)
flexCell.setOnClickListener {
clickListener.invoke(contentList[index], index)
}
}
}
private fun createSmartHotTagStyle(flexCell: TextView, entity: HotTagEntity) {
flexCell.compoundDrawablePadding = 4F.dip2px()
flexCell.gravity = Gravity.CENTER_VERTICAL
flexCell.typeface = Typeface.DEFAULT_BOLD
flexCell.textSize = 12F
flexCell.text = StringUtils.shrinkStringWithDot(name, 6)
flexCell.setTextColor(Color.WHITE)
flexCell.text = StringUtils.shrinkStringWithDot(entity.name, 6)
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
val colors =
intArrayOf(com.gh.gamecenter.common.R.color.text_FFB749.toColor(requireContext()), com.gh.gamecenter.common.R.color.text_FF6D3C.toColor(requireContext()))
intArrayOf(
com.gh.gamecenter.common.R.color.text_FFB749.toColor(requireContext()),
com.gh.gamecenter.common.R.color.text_FF6D3C.toColor(requireContext())
)
val position = floatArrayOf(0F, 1F)
val linearGradient = LinearGradient(
0F,
@ -429,10 +540,53 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
position,
Shader.TileMode.CLAMP
)
flexCell.paint.shader = linearGradient
val shapeRadius = floatArrayOf(999F, 999F, 999F, 999F, 999F, 999F, 999F, 999F)
val strokeWidth = 0.5F.dip2px().toFloat()
val shape = RoundRectShape(shapeRadius, RectF(strokeWidth, strokeWidth, strokeWidth, strokeWidth), shapeRadius)
flexCell.background = ShapeDrawable(shape).apply {
paint.shader = linearGradient
}
if (entity.isGuessSearch) {
flexCell.setTextColor(Color.WHITE)
flexCell.typeface = Typeface.DEFAULT_BOLD
flexCell.setDrawableStart(R.drawable.ic_smart_search)
flexCell.paint.shader = linearGradient
} else {
flexCell.setTextColor(
ContextCompat.getColor(
requireContext(),
com.gh.gamecenter.common.R.color.text_secondary
)
)
}
flexCell.invalidate()
}
private fun createSmartDiscoverTagStyle(flexCell: TextView, entity: DiscoveryTagEntity) {
val labelIcon = when (entity.recommendType) {
"hot" -> R.drawable.ic_search_hot
"new" -> R.drawable.ic_search_new
"surge", "rise" -> R.drawable.ic_search_rise
"update" -> R.drawable.ic_search_update
else -> -1
}
if (labelIcon != -1) {
flexCell.setDrawableEnd(labelIcon.toDrawable())
flexCell.compoundDrawablePadding = 4F.dip2px()
}
flexCell.setSingleLine()
flexCell.ellipsize = TextUtils.TruncateAt.END
flexCell.gravity = Gravity.CENTER
flexCell.textSize = 12F
flexCell.text = entity.text
flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
cornerRadius = 999F
} else DrawableView.getStrokeDrawable(com.gh.gamecenter.common.R.color.text_dddddd, 0.5F)
}
private fun postExposureEvent(index: Int) {
mRankList?.safelyGetInRelease(index)?.content?.forEach {
if (it.link.type == "game") {
@ -451,7 +605,13 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
notifyItemRangeChanged(0, itemCount)
}
mViewModel?.historySearchLiveData?.value?.let { updateHistorySearchView(it) }
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
createHotAndDiscoveryFlexContent(
mBinding.hotAndDiscoveryTagFlex,
getHotTagList(),
getDiscoveryTagList(),
hotTagClickListener = mHotTagClickListener,
discoveryTagClickListener = mDiscoveryTagClickListener
)
}
protected open fun provideDao(): ISearchHistoryDao =

View File

@ -11,7 +11,7 @@ class SearchDefaultViewModel(private val dao: ISearchHistoryDao) : ViewModel() {
it
}
var isExistHotSearch: Boolean = false
var isExistHotTag: Boolean = false
var isExistHotAndDiscoveryTag: Boolean = false
var isExistHistory: Boolean = false
var isExistRankList: Boolean = false

View File

@ -36,7 +36,7 @@
</com.gh.gamecenter.common.view.LimitHeightLinearLayout>
<include
android:id="@+id/hotTagHeadContainer"
android:id="@+id/hotAndDiscoveryTagHeadContainer"
layout="@layout/layout_subject_head"
android:layout_width="match_parent"
android:layout_height="48dp"
@ -45,14 +45,14 @@
app:layout_constraintTop_toBottomOf="@id/history_flex_container" />
<com.gh.gamecenter.common.view.LimitHeightLinearLayout
android:id="@+id/hot_tag_flex_container"
android:id="@+id/hot_and_discovery_tag_flex_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ui_surface"
app:layout_constraintTop_toBottomOf="@id/hotTagHeadContainer">
app:layout_constraintTop_toBottomOf="@id/hotAndDiscoveryTagHeadContainer">
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/hot_tag_flex"
android:id="@+id/hot_and_discovery_tag_flex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
@ -68,7 +68,7 @@
android:layout_height="48dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/hot_tag_flex_container" />
app:layout_constraintTop_toBottomOf="@id/hot_and_discovery_tag_flex_container" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hot_list"

View File

@ -38,7 +38,7 @@
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
@ -47,6 +47,7 @@
android:textColor="@color/text_primary"
android:layout_marginEnd="16dp"
app:layout_constrainedWidth="true"
app:layout_constraintWidth_max="wrap"
app:layout_constraintBottom_toTopOf="@id/play_count"
app:layout_constraintEnd_toStartOf="@id/play_container"
app:layout_constraintHorizontal_bias="0"
@ -77,7 +78,10 @@
android:layout_marginEnd="12dp"
app:layout_constraintBottom_toBottomOf="@+id/name"
app:layout_constraintStart_toEndOf="@+id/name"
app:layout_constraintTop_toTopOf="@+id/name" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/name"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"/>
<LinearLayout
android:id="@+id/play_container"

View File

@ -18,7 +18,7 @@
<string name="download_startall">全部開始</string>
<string name="search_searching">搜索中...</string>
<string name="search_hot">熱門搜索</string>
<string name="search_hot_tag">熱門標簽</string>
<string name="search_discovery_tag">搜索發現</string>
<string name="search_history">歷史搜索</string>
<string name="news_concenrn_game_mine">我關註的遊戲</string>
<string name="news_search_input">請輸入搜索關鍵字</string>

View File

@ -18,7 +18,7 @@
<string name="download_startall">全部开始</string>
<string name="search_searching">搜索中...</string>
<string name="search_hot">热门搜索</string>
<string name="search_hot_tag">热门标签</string>
<string name="search_discovery_tag">搜索发现</string>
<string name="search_history">历史搜索</string>
<string name="news_concenrn_game_mine">我关注的游戏</string>
<string name="news_search_input">请输入搜索关键字</string>

View File

@ -88,6 +88,8 @@ object SensorsBridge {
private const val KEY_VERIFICATION_TYPE = "verification_type"
private const val KEY_VIDEO_ID = "video_id"
private const val KEY_PLAY_TYPE = "play_type"
private const val KEY_LABEL_NAME = "label_name"
private const val KEY_LABEL_ID = "label_id"
const val KEY_BOTTOM_TAB = "bottom_tab"
const val KEY_MULTI_TAB_NAME = "several_tab_page_name"
const val KEY_MULTI_TAB_ID = "several_tab_page_id"
@ -291,6 +293,8 @@ object SensorsBridge {
private const val EVENT_COLUMN_TEST_CLICK = "ColumnTestClick"
private const val EVENT_SEARCH_DISCOVERY_CLICK = "SearchDiscoveryClick"
private const val EVENT_BYPASS_BROWSING = "BypassBrowsing"
private const val EVENT_FAIL_BYPASS = "FailBypass"
@ -4996,4 +5000,29 @@ object SensorsBridge {
}
trackEvent(EVENT_APPOINTMENT_GAME_ONLINE_DIALOG_CLICK, json)
}
/**
* 事件IDSearchDiscoveryClick
* 事件名称:搜索发现点击事件
* 触发时机:点击搜索发现时触发
* @param labelName 标签名称
* @param labelId 标签ID
* @param searchContent 搜索内容
* @param position 序号
* @see EVENT_SEARCH_DISCOVERY_CLICK
*/
fun trackSearchDiscoveryClick(
labelName: String,
labelId: String,
searchContent: String,
position: Int
) {
val json = json {
KEY_LABEL_NAME to labelName
KEY_LABEL_ID to labelId
KEY_SEARCH_CONTENT to searchContent
KEY_POSITION to position
}
trackEvent(EVENT_SEARCH_DISCOVERY_CLICK, json)
}
}

View File

@ -0,0 +1,24 @@
package com.gh.gamecenter.feature.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
class DiscoveryTagEntity(
@SerializedName("_id")
var id: String? = "",
var text: String? = "",
@SerializedName("keyword")
var _keyword: String? = "",
@SerializedName("recommend_type")
var recommendType: String = ""
) : Parcelable {
val keyword get(): String {
val keyword = this._keyword
if (keyword.isNullOrEmpty()) {
return text ?: ""
}
return keyword
}
}

View File

@ -70,6 +70,8 @@ class SettingsEntity(
var hotSearch: List<HotSearch>? = listOf(),
@SerializedName("tag")
var hotTag: List<HotTagEntity>? = listOf(),
@SerializedName("discover_tag")
var discoveryTag: List<DiscoveryTagEntity>? = listOf(),
@SerializedName("hot_list")
var rankList: List<RankList>? = listOf(),
@SerializedName("wechat_game_search_list")