diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dd5b1a051c..d82054ae2a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -591,6 +591,14 @@
android:name=".simulatorgame.SimulatorManagementActivity"
android:screenOrientation="portrait" />
+
+
+
+
diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt
index c0c7cf1d5d..9d9f092d3d 100644
--- a/app/src/main/java/com/gh/common/util/DirectUtils.kt
+++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt
@@ -22,6 +22,7 @@ import com.gh.common.exposure.ExposureType
import com.gh.common.util.EntranceUtils.*
import com.gh.gamecenter.*
import com.gh.gamecenter.amway.AmwayActivity
+import com.gh.gamecenter.catalog.CatalogActivity
import com.gh.gamecenter.category.CategoryDirectoryActivity
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
@@ -132,7 +133,9 @@ object DirectUtils {
"server",
"top_game_comment",
"wechat_bind",
- "video")
+ "video",
+ "catalog"
+ )
fun directToLinkPage(context: Context,
linkEntity: LinkEntity,
@@ -199,6 +202,8 @@ object DirectUtils {
"category", "分类" -> directCategoryDirectory(context, linkEntity.link!!, linkEntity.text!!)
+ "catalog" -> directCatalog(context, linkEntity.link!!, linkEntity.text!!)
+
"block", "版块" -> {
if (linkEntity.link.isNullOrEmpty()) return
directToBlock(context,
@@ -887,6 +892,21 @@ object DirectUtils {
jumpActivity(context, bundle)
}
+ /**
+ * 跳转新分类
+ */
+ @JvmStatic
+ fun directCatalog(context: Context, catalogId: String, catalogTitle: String, entrance: String? = null, path: String? = "") {
+ if (catalogId.isEmpty()) return
+ val bundle = Bundle()
+ bundle.putString(KEY_TO, CatalogActivity::class.java.name)
+ bundle.putString(KEY_CATALOG_ID, catalogId)
+ bundle.putString(KEY_CATALOG_TITLE, catalogTitle)
+ bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
+ bundle.putString(KEY_PATH, path)
+ jumpActivity(context, bundle)
+ }
+
/**
* 跳转到问题标签详情
*/
diff --git a/app/src/main/java/com/gh/common/util/EntranceUtils.java b/app/src/main/java/com/gh/common/util/EntranceUtils.java
index a957e24945..e32bd4e42c 100644
--- a/app/src/main/java/com/gh/common/util/EntranceUtils.java
+++ b/app/src/main/java/com/gh/common/util/EntranceUtils.java
@@ -216,6 +216,10 @@ public class EntranceUtils {
public static final String KEY_DIAGNOSIS = "diagnosis";
public static final String KEY_SIMULATOR = "simulator";
public static final String KEY_MARKET_DETAILS = "market_details";
+ public static final String KEY_CATALOG_ID = "catalogId";
+ public static final String KEY_PRIMARY_CATALOG_ID = "primaryCatalogId";
+ public static final String KEY_CATALOG_TITLE = "catalog_title";
+ public static final String KEY_CATALOG_INIT_TITLE = "catalog_init_title";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
diff --git a/app/src/main/java/com/gh/common/view/CatalogFilterView.kt b/app/src/main/java/com/gh/common/view/CatalogFilterView.kt
new file mode 100644
index 0000000000..21e02d6ef4
--- /dev/null
+++ b/app/src/main/java/com/gh/common/view/CatalogFilterView.kt
@@ -0,0 +1,320 @@
+package com.gh.common.view
+
+import android.content.Context
+import android.graphics.Color
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.PopupWindow
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import com.gh.common.util.toColor
+import com.gh.common.util.visibleIf
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.CatalogSwitch
+import com.gh.gamecenter.entity.SubCatalogEntity
+import com.gh.gamecenter.entity.SubjectSettingEntity
+import com.google.android.flexbox.FlexboxLayout
+
+class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) {
+
+ private var mTypeTv: TextView
+ private var mCatalogTv: TextView
+ private var mSizeTv: TextView
+ private var mTypeContainer: View
+ private var mCatalogContainer: View
+ private var mSizeContainer: View
+
+ private var mTypeFilterArray = ArrayList()
+ private var mCatalogFilterArray = ArrayList()
+ private var sizeFilterArray: ArrayList? = null
+
+ private var mOnCatalogFilterSetupListener: OnCatalogFilterSetupListener? = null
+
+ init {
+ View.inflate(context, R.layout.layout_catalog_filter, this)
+
+ mTypeTv = findViewById(R.id.type_tv)
+ mCatalogTv = findViewById(R.id.catalog_tv)
+ mSizeTv = findViewById(R.id.size_tv)
+ mTypeContainer = findViewById(R.id.container_type)
+ mCatalogContainer = findViewById(R.id.container_catalog)
+ mSizeContainer = findViewById(R.id.container_size)
+
+ mTypeContainer.setOnClickListener {
+ showSelectTypePopupWindow(this, mTypeTv, mTypeTv.text.toString())
+ }
+
+ mCatalogContainer.setOnClickListener {
+ showSelectCatalogPopupWindow(this, mCatalogTv, mCatalogTv.text.toString())
+ }
+
+ mSizeContainer.setOnClickListener {
+ showSelectSizePopupWindow(this, mSizeTv, mSizeTv.text.toString())
+ }
+
+// ratingTv.setOnClickListener {
+// mOnConfigFilterSetupListener?.onSetupSortType(SortType.RATING)
+// toggleHighlightedTextView(ratingTv, true)
+// toggleHighlightedTextView(newestTv, false)
+// toggleHighlightedTextView(recommendedTv, false)
+// }
+//
+// newestTv.setOnClickListener {
+// mOnConfigFilterSetupListener?.onSetupSortType(SortType.NEWEST)
+// toggleHighlightedTextView(ratingTv, false)
+// toggleHighlightedTextView(newestTv, true)
+// toggleHighlightedTextView(recommendedTv, false)
+// }
+//
+// recommendedTv.setOnClickListener {
+// mOnConfigFilterSetupListener?.onSetupSortType(SortType.RECOMMENDED)
+// toggleHighlightedTextView(ratingTv, false)
+// toggleHighlightedTextView(newestTv, false)
+// toggleHighlightedTextView(recommendedTv, true)
+// }
+ }
+
+ fun setTypeList(switch: CatalogSwitch) {
+ switch.run {
+ if ("on" == hotSort) mTypeFilterArray.add(SortType.RECOMMENDED)
+ if ("on" == newSort) mTypeFilterArray.add(SortType.NEWEST)
+ if ("on" == starSort) mTypeFilterArray.add(SortType.RATING)
+ }
+ if (mTypeFilterArray.isNotEmpty()) mTypeTv.text = mTypeFilterArray[0].value
+ }
+
+ fun setCatalogList(subCatalogList: List, initCatalogName: String) {
+ mCatalogFilterArray = ArrayList(subCatalogList)
+ mCatalogTv.text = initCatalogName
+ }
+
+ fun setOnConfigSetupListener(onCatalogFilterSetupListener: OnCatalogFilterSetupListener) {
+ mOnCatalogFilterSetupListener = onCatalogFilterSetupListener
+ }
+
+ private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
+ if (highlightIt) {
+ targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
+ targetTextView.setTextColor(Color.WHITE)
+ } else {
+ targetTextView.background = null
+ targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
+ }
+ }
+
+ private fun showSelectTypePopupWindow(containerView: View, typeTv: TextView, typeText: String) {
+ val drawableUp = ContextCompat.getDrawable(typeTv.context, R.drawable.ic_filter_arrow_up)
+ val drawableDown = ContextCompat.getDrawable(typeTv.context, R.drawable.ic_filter_arrow_down)
+ drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
+ drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
+
+ typeTv.setTextColor(R.color.theme_font.toColor())
+ typeTv.setCompoundDrawables(null, null, drawableUp, null)
+
+ val inflater = LayoutInflater.from(typeTv.context)
+ val layout = inflater.inflate(R.layout.layout_filter_size, null)
+ val popupWindow = PopupWindow(
+ layout,
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.WRAP_CONTENT)
+
+ val flexboxLayout = layout.findViewById(R.id.flexbox)
+ val backgroundView = layout.findViewById(R.id.background)
+
+ backgroundView.setOnClickListener {
+ popupWindow.dismiss()
+ }
+
+ for (type in mTypeFilterArray) {
+ val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
+
+ // 单列 3 个,强行设置宽度为屏幕的 1/3
+ val width = typeTv.context.resources.displayMetrics.widthPixels / 3
+ val height = item.layoutParams.height
+
+ item.layoutParams = ViewGroup.LayoutParams(width, height)
+ flexboxLayout.addView(item)
+
+ val tv = item.findViewById(R.id.size_tv)
+ tv.text = type.value
+
+ toggleHighlightedTextView(tv, typeText == type.value)
+
+ tv.tag = type.value
+
+ item.setOnClickListener {
+ toggleHighlightedTextView(tv, true)
+ popupWindow.dismiss()
+ typeTv.text = type.value
+
+ mOnCatalogFilterSetupListener?.onSetupSortType(type)
+ }
+ }
+
+ popupWindow.setOnDismissListener {
+ typeTv.setTextColor(R.color.text_757575.toColor())
+ typeTv.setCompoundDrawables(null, null, drawableDown, null)
+ }
+
+ popupWindow.isTouchable = true
+ popupWindow.isFocusable = true
+ popupWindow.showAsDropDown(containerView, 0, 0)
+ }
+
+ private fun showSelectCatalogPopupWindow(containerView: View, catalogTv: TextView, catalogText: String) {
+ val drawableUp = ContextCompat.getDrawable(catalogTv.context, R.drawable.ic_filter_arrow_up)
+ val drawableDown = ContextCompat.getDrawable(catalogTv.context, R.drawable.ic_filter_arrow_down)
+ drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
+ drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
+
+ catalogTv.setTextColor(R.color.theme_font.toColor())
+ catalogTv.setCompoundDrawables(null, null, drawableUp, null)
+
+ val inflater = LayoutInflater.from(catalogTv.context)
+ val layout = inflater.inflate(R.layout.layout_filter_size, null)
+ val popupWindow = PopupWindow(
+ layout,
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.WRAP_CONTENT)
+
+ val flexboxLayout = layout.findViewById(R.id.flexbox)
+ val backgroundView = layout.findViewById(R.id.background)
+
+ backgroundView.setOnClickListener {
+ popupWindow.dismiss()
+ }
+
+ for (entity in mCatalogFilterArray) {
+ val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
+
+ // 单列 3 个,强行设置宽度为屏幕的 1/3
+ val width = catalogTv.context.resources.displayMetrics.widthPixels / 3
+ val height = item.layoutParams.height
+
+ item.layoutParams = ViewGroup.LayoutParams(width, height)
+ flexboxLayout.addView(item)
+
+ val tv = item.findViewById(R.id.size_tv)
+ val iv = item.findViewById(R.id.recommend_iv)
+ tv.text = entity.name
+ iv.visibleIf(entity.recommended)
+
+ toggleHighlightedTextView(tv, catalogText == entity.name)
+
+ tv.tag = entity.name
+
+ item.setOnClickListener {
+ toggleHighlightedTextView(tv, true)
+ popupWindow.dismiss()
+ catalogTv.text = entity.name
+
+ mOnCatalogFilterSetupListener?.onSetupSortCatalog(entity)
+ }
+ }
+
+ popupWindow.setOnDismissListener {
+ catalogTv.setTextColor(R.color.text_757575.toColor())
+ catalogTv.setCompoundDrawables(null, null, drawableDown, null)
+ }
+
+ popupWindow.isTouchable = true
+ popupWindow.isFocusable = true
+ popupWindow.showAsDropDown(containerView, 0, 0)
+ }
+
+ private fun showSelectSizePopupWindow(containerView: View, sizeTv: TextView, sizeText: String) {
+ val drawableUp = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_up)
+ val drawableDown = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_down)
+ drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
+ drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
+
+ sizeTv.setTextColor(R.color.theme_font.toColor())
+ sizeTv.setCompoundDrawables(null, null, drawableUp, null)
+
+ val inflater = LayoutInflater.from(sizeTv.context)
+ val layout = inflater.inflate(R.layout.layout_filter_size, null)
+ val popupWindow = PopupWindow(
+ layout,
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.WRAP_CONTENT)
+
+ val flexboxLayout = layout.findViewById(R.id.flexbox)
+ val backgroundView = layout.findViewById(R.id.background)
+
+ sizeFilterArray = if (sizeFilterArray == null) {
+ getDefaultSizeFilterArray()
+ } else {
+ sizeFilterArray?.apply {
+ if (firstOrNull()?.text != "全部大小") {
+ add(0, SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
+ }
+ }
+ }
+
+ backgroundView.setOnClickListener {
+ popupWindow.dismiss()
+ }
+
+ for (size in sizeFilterArray!!) {
+ val item = inflater.inflate(R.layout.item_filter_size, flexboxLayout, false)
+
+ // 单列 3 个,强行设置宽度为屏幕的 1/3
+ val width = sizeTv.context.resources.displayMetrics.widthPixels / 3
+ val height = item.layoutParams.height
+
+ item.layoutParams = ViewGroup.LayoutParams(width, height)
+ flexboxLayout.addView(item)
+
+ val tv = item.findViewById(R.id.size_tv)
+ tv.text = size.text
+
+ toggleHighlightedTextView(tv, sizeText == size.text)
+
+ tv.tag = size.text
+
+ item.setOnClickListener {
+ toggleHighlightedTextView(tv, true)
+ popupWindow.dismiss()
+ sizeTv.text = size.text
+
+ mOnCatalogFilterSetupListener?.onSetupSortSize(size)
+ }
+ }
+
+ popupWindow.setOnDismissListener {
+ sizeTv.setTextColor(R.color.text_757575.toColor())
+ sizeTv.setCompoundDrawables(null, null, drawableDown, null)
+ }
+
+ popupWindow.isTouchable = true
+ popupWindow.isFocusable = true
+ popupWindow.showAsDropDown(containerView, 0, 0)
+ }
+
+ private fun getDefaultSizeFilterArray(): ArrayList {
+ return arrayListOf().apply {
+ add(SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
+ add(SubjectSettingEntity.Size(min = -1, max = 100, text = "100M以下"))
+ add(SubjectSettingEntity.Size(min = 100, max = 300, text = "100-300M"))
+ add(SubjectSettingEntity.Size(min = 300, max = 500, text = "300-500M"))
+ add(SubjectSettingEntity.Size(min = 500, max = 1000, text = "100M-1G"))
+ add(SubjectSettingEntity.Size(min = 1000, max = -1, text = "1G以上"))
+ }
+ }
+
+ interface OnCatalogFilterSetupListener {
+ fun onSetupSortSize(sortSize: SubjectSettingEntity.Size)
+ fun onSetupSortType(sortType: SortType)
+ fun onSetupSortCatalog(sortCatalog: SubCatalogEntity)
+ }
+
+ enum class SortType(val value: String) {
+ RECOMMENDED("热门推荐"),
+ NEWEST("最新上线"),
+ RATING("最高评分")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/view/ConfigFilterView.kt b/app/src/main/java/com/gh/common/view/ConfigFilterView.kt
index cec37b79a6..e0460afa1e 100644
--- a/app/src/main/java/com/gh/common/view/ConfigFilterView.kt
+++ b/app/src/main/java/com/gh/common/view/ConfigFilterView.kt
@@ -12,7 +12,7 @@ import android.widget.PopupWindow
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
-import com.gh.common.util.DisplayUtils
+import com.gh.common.util.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.google.android.flexbox.FlexboxLayout
@@ -69,16 +69,13 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
mOnConfigFilterSetupListener = onConfigFilterSetupListener
}
- fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
+ private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
if (highlightIt) {
- targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.text_blue_background)
+ targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
targetTextView.setTextColor(Color.WHITE)
} else {
- val colorDrawable = GradientDrawable()
- colorDrawable.setColor(Color.WHITE)
- colorDrawable.cornerRadius = DisplayUtils.dip2px(1.5f).toFloat()
- targetTextView.background = colorDrawable
- targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_3a3a3a))
+ targetTextView.background = null
+ targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
}
}
@@ -88,8 +85,8 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
+ sizeTv.setTextColor(R.color.theme_font.toColor())
sizeTv.setCompoundDrawables(null, null, drawableUp, null)
- sizeTv.text = "收起"
val inflater = LayoutInflater.from(sizeTv.context)
val layout = inflater.inflate(R.layout.layout_filter_size, null)
@@ -146,10 +143,8 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
popupWindow.setOnDismissListener {
+ sizeTv.setTextColor(R.color.text_757575.toColor())
sizeTv.setCompoundDrawables(null, null, drawableDown, null)
- if (sizeTv.text == "收起") {
- sizeTv.text = sizeText
- }
}
popupWindow.isTouchable = true
@@ -160,11 +155,11 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
private fun getDefaultSizeFilterArray(): ArrayList {
return arrayListOf().apply {
add(SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"))
- add(SubjectSettingEntity.Size(min = -1, max = 20, text = "20M以下"))
- add(SubjectSettingEntity.Size(min = 20, max = 50, text = "20-50M"))
- add(SubjectSettingEntity.Size(min = 50, max = 100, text = "50-100M"))
- add(SubjectSettingEntity.Size(min = 100, max = 500, text = "100-500M"))
- add(SubjectSettingEntity.Size(min = 500, max = -1, text = "500M以上"))
+ add(SubjectSettingEntity.Size(min = -1, max = 100, text = "100M以下"))
+ add(SubjectSettingEntity.Size(min = 100, max = 300, text = "100-300M"))
+ add(SubjectSettingEntity.Size(min = 300, max = 500, text = "300-500M"))
+ add(SubjectSettingEntity.Size(min = 500, max = 1000, text = "100M-1G"))
+ add(SubjectSettingEntity.Size(min = 1000, max = -1, text = "1G以上"))
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt b/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt
new file mode 100644
index 0000000000..e25e53dbb5
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt
@@ -0,0 +1,33 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.NormalActivity
+import com.gh.gamecenter.R
+
+class CatalogActivity : NormalActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setToolbarMenu(R.menu.menu_download)
+ }
+
+ override fun showDownloadMenu(): Boolean {
+ return true
+ }
+
+ override fun provideNormalIntent(): Intent {
+ return getTargetIntent(this, CatalogActivity::class.java, CatalogFragment::class.java)
+ }
+
+ companion object {
+ fun getIntent(context: Context, catalogId: String, catalogTitle: String): Intent {
+ val bundle = Bundle()
+ bundle.putString(EntranceUtils.KEY_CATALOG_ID, catalogId)
+ bundle.putString(EntranceUtils.KEY_CATALOG_TITLE, catalogTitle)
+ return getTargetIntent(context, CatalogActivity::class.java, CatalogFragment::class.java, bundle)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/CatalogAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/CatalogAdapter.kt
new file mode 100644
index 0000000000..48e98e28a9
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/CatalogAdapter.kt
@@ -0,0 +1,47 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.toColor
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.CatalogItemBinding
+import com.gh.gamecenter.entity.SubCatalogEntity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class CatalogAdapter(context: Context, private val mFragment: CatalogFragment, private val mList: List) : BaseRecyclerAdapter(context) {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CatalogItemViewHolder {
+ val view = mLayoutInflater.inflate(R.layout.catalog_item, parent, false)
+ return CatalogItemViewHolder(CatalogItemBinding.bind(view))
+ }
+
+ override fun getItemCount(): Int {
+ return mList.size
+ }
+
+ override fun onBindViewHolder(holder: CatalogItemViewHolder, position: Int) {
+ holder.binding.run {
+ val catalogEntity = mList[position]
+ entity = catalogEntity
+ executePendingBindings()
+ if (catalogEntity.name == mFragment.selectedCatalogName) {
+ selectedTag.visibility = View.VISIBLE
+ root.setBackgroundColor(R.color.white.toColor())
+ } else {
+ selectedTag.visibility = View.GONE
+ root.setBackgroundColor(R.color.text_F5F5F5.toColor())
+ }
+ root.setOnClickListener {
+ if (catalogEntity.name != mFragment.selectedCatalogName) {
+ mFragment.selectedCatalogName = catalogEntity.name
+ mFragment.changeCatalog(position)
+ notifyDataSetChanged()
+ }
+ }
+ }
+ }
+
+ class CatalogItemViewHolder(val binding: CatalogItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/CatalogFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/CatalogFragment.kt
new file mode 100644
index 0000000000..196cbb03d2
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/CatalogFragment.kt
@@ -0,0 +1,119 @@
+package com.gh.gamecenter.catalog
+
+import android.os.Bundle
+import android.view.View
+import android.widget.LinearLayout
+import androidx.core.os.bundleOf
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.EntranceUtils
+import com.gh.common.util.viewModelProvider
+import com.gh.common.view.FixLinearLayoutManager
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.CatalogEntity
+import com.gh.gamecenter.entity.SubCatalogEntity
+import com.gh.gamecenter.normal.NormalFragment
+import kotterknife.bindView
+
+class CatalogFragment : NormalFragment() {
+
+ private val mReuseLoading by bindView(R.id.reuse_ll_loading)
+ private val mReuseNoConnection by bindView(R.id.reuse_no_connection)
+ private val mReuseNoData by bindView(R.id.reuse_none_data)
+ private val mCatalogContainer by bindView(R.id.container_catalog)
+ private val mCatalogRv by bindView(R.id.rv_catalog)
+
+ private lateinit var mViewModel: CatalogViewModel
+ private lateinit var mEntity: CatalogEntity
+ private lateinit var mSpecialCatalogFragment: SpecialCatalogFragment
+ private lateinit var mSubCatalogFragment: SubCatalogFragment
+ private var mCatalogId: String = ""
+ private var mSelectedPosition = 0
+ var selectedCatalogName: String = ""
+
+ override fun getLayoutId() = R.layout.fragment_catalog
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
+ mViewModel = viewModelProvider(CatalogViewModel.Factory(mCatalogId))
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ setNavigationTitle(arguments?.getString(EntranceUtils.KEY_CATALOG_TITLE))
+ mViewModel.catalogs.observe(viewLifecycleOwner, Observer {
+ mReuseLoading.visibility = View.GONE
+ if (it != null) {
+ mReuseNoConnection.visibility = View.GONE
+ if (it.subCatalog.isNotEmpty()) {
+ mCatalogContainer.visibility = View.VISIBLE
+ mReuseNoData.visibility = View.GONE
+ mEntity = it
+ if (mEntity.hasSpecial) {
+ val specialEntity = SubCatalogEntity(name = "精选")
+ (mEntity.subCatalog as ArrayList).add(0, specialEntity)
+ }
+ initView()
+ } else {
+ mCatalogContainer.visibility = View.GONE
+ mReuseNoData.visibility = View.VISIBLE
+ }
+ } else {
+ mCatalogContainer.visibility = View.GONE
+ mReuseNoData.visibility = View.GONE
+ mReuseNoConnection.visibility = View.VISIBLE
+ mReuseNoConnection.setOnClickListener {
+ mReuseLoading.visibility = View.VISIBLE
+ mViewModel.getCatalogs()
+ }
+ }
+ })
+ }
+
+ private fun initView() {
+ mEntity.run {
+ if (subCatalog.isNotEmpty()) {
+ selectedCatalogName = subCatalog[0].name
+ mCatalogRv.layoutManager = FixLinearLayoutManager(requireContext())
+ mCatalogRv.adapter = CatalogAdapter(requireContext(), this@CatalogFragment, subCatalog)
+
+ if (hasSpecial) {
+ mSpecialCatalogFragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.simpleName) as? SpecialCatalogFragment ?: SpecialCatalogFragment()
+ mSpecialCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id)
+ childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSpecialCatalogFragment, SpecialCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
+ } else {
+ mSubCatalogFragment = childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.simpleName) as? SubCatalogFragment ?: SubCatalogFragment()
+ mSubCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id, EntranceUtils.KEY_PRIMARY_CATALOG_ID to subCatalog[0].id)
+ childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSubCatalogFragment, SubCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+ }
+
+ }
+ }
+
+ fun changeCatalog(position: Int) {
+ mEntity.run {
+ if (hasSpecial) {
+ if (mSelectedPosition == 0) {
+ mSubCatalogFragment = childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.simpleName) as? SubCatalogFragment ?: SubCatalogFragment()
+ mSubCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id, EntranceUtils.KEY_PRIMARY_CATALOG_ID to subCatalog[position].id)
+ childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSubCatalogFragment, SubCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
+ } else {
+ if (position == 0) {
+ mSpecialCatalogFragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.simpleName) as? SpecialCatalogFragment ?: SpecialCatalogFragment()
+ mSpecialCatalogFragment.arguments = bundleOf(EntranceUtils.KEY_CATALOG_ID to mEntity.id)
+ childFragmentManager.beginTransaction().replace(R.id.container_sub_catalog, mSpecialCatalogFragment, SpecialCatalogFragment::class.java.simpleName).commitAllowingStateLoss()
+ } else {
+ mSubCatalogFragment.changeSubCatalog(subCatalog[position].id)
+ }
+ }
+ } else {
+ mSubCatalogFragment.changeSubCatalog(subCatalog[position].id)
+ }
+ mSelectedPosition = position
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/CatalogViewModel.kt b/app/src/main/java/com/gh/gamecenter/catalog/CatalogViewModel.kt
new file mode 100644
index 0000000000..1db2a7bb14
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/CatalogViewModel.kt
@@ -0,0 +1,47 @@
+package com.gh.gamecenter.catalog
+
+import android.annotation.SuppressLint
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.gh.gamecenter.entity.CatalogEntity
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+
+class CatalogViewModel(application: Application, private val catalogId: String) : AndroidViewModel(application) {
+
+ private val api = RetrofitManager.getInstance(getApplication()).api
+ var catalogs = MutableLiveData()
+
+ init {
+ getCatalogs()
+ }
+
+ @SuppressLint("CheckResult")
+ fun getCatalogs() {
+ api.getCatalogs(catalogId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: CatalogEntity) {
+ catalogs.postValue(data)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ catalogs.postValue(null)
+ }
+ })
+ }
+
+ class Factory(private val catalogId: String) : ViewModelProvider.NewInstanceFactory() {
+ override fun create(modelClass: Class): T {
+ return CatalogViewModel(HaloApp.getInstance().application, catalogId) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt
new file mode 100644
index 0000000000..9f49914251
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt
@@ -0,0 +1,33 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.NormalActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.CatalogEntity
+
+class NewCatalogListActivity : NormalActivity() {
+
+ companion object {
+ fun getIntent(context: Context, catalogTitle: String, catalog: CatalogEntity, initTitle: String): Intent {
+ val bundle = Bundle()
+ bundle.putParcelable(EntranceUtils.KEY_DATA, catalog)
+ bundle.putString(EntranceUtils.KEY_NAME, catalog.name)
+ bundle.putString(EntranceUtils.KEY_CATALOG_TITLE, catalogTitle)
+ bundle.putString(EntranceUtils.KEY_CATALOG_INIT_TITLE, initTitle)
+ return getTargetIntent(context, NewCatalogListActivity::class.java, NewCatalogListFragment::class.java, bundle)
+ }
+ }
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setToolbarMenu(R.menu.menu_download)
+ }
+
+ override fun showDownloadMenu(): Boolean {
+ return true
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListAdapter.kt
new file mode 100644
index 0000000000..d8223befa7
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListAdapter.kt
@@ -0,0 +1,168 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.util.SparseArray
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.constant.ItemViewType
+import com.gh.common.exposure.ExposureEvent
+import com.gh.common.exposure.ExposureSource
+import com.gh.common.exposure.ExposureType
+import com.gh.common.exposure.IExposable
+import com.gh.common.util.DownloadItemUtils
+import com.gh.common.util.StringUtils
+import com.gh.common.util.dip2px
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.adapter.viewholder.GameViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.baselist.LoadType
+import com.gh.gamecenter.databinding.GameItemBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.game.GameItemViewHolder
+import com.lightgame.download.DownloadEntity
+import java.util.*
+
+class NewCatalogListAdapter(context: Context,
+ private val mViewModel: NewCatalogListViewModel,
+ private val mEntrance: String?) : ListAdapter(context), IExposable {
+
+ private val mExposureEventSparseArray: SparseArray = SparseArray()
+
+ val positionAndPackageMap = HashMap()
+
+ override fun setListData(updateData: MutableList?) {
+ // 记录游戏位置
+ if (updateData != null) {
+ for (i in 0 until updateData.size) {
+ val gameEntity = updateData[i]
+ var packages = gameEntity.id
+ for (apkEntity in gameEntity.getApk()) {
+ packages += apkEntity.packageName
+ }
+ positionAndPackageMap[packages + i] = i
+ }
+ }
+ super.setListData(updateData)
+ }
+
+ fun clearPositionAndPackageMap() {
+ positionAndPackageMap.clear()
+ }
+
+ override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
+ return oldItem?.id == newItem?.id
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ if (position == itemCount - 1) {
+ return ItemViewType.ITEM_FOOTER
+ }
+ return ItemViewType.GAME_NORMAL
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ItemViewType.GAME_NORMAL -> {
+ GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false)))
+ }
+ else -> {
+ FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is GameItemViewHolder) {
+ val gameEntity = mEntityList[position]
+
+ holder.binding.game = gameEntity
+ holder.initServerType(gameEntity)
+ holder.binding.hideSize = true
+ holder.binding.executePendingBindings()
+
+ val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
+ holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
+
+ gameEntity.sequence = position + 1
+
+ val sortType = mViewModel.sortType.value
+ val toolbarTitle = mViewModel.title
+ val categoryTitle = mViewModel.categoryTitle
+ val selectedCatalogName = mViewModel.selectedCatalog.name
+
+ val exposureSources = ArrayList()
+ exposureSources.add(ExposureSource(categoryTitle, selectedCatalogName))
+ exposureSources.add(ExposureSource("二级分类", "$selectedCatalogName+$sortType"))
+ gameEntity.sequence = position + 1
+
+ val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
+ mExposureEventSparseArray.put(position, event)
+
+ holder.itemView.setOnClickListener {
+ GameDetailActivity.startGameDetailActivity(
+ mContext,
+ gameEntity,
+ StringUtils.buildString(mEntrance, "+(", toolbarTitle, ":列表[", selectedCatalogName, "=", sortType, "=", (position + 1).toString(), "])"),
+ event)
+ }
+ DownloadItemUtils.setOnClickListener(mContext,
+ holder.binding.downloadBtn,
+ gameEntity,
+ position,
+ this,
+ StringUtils.buildString(StringUtils.buildString(mEntrance, "+(", toolbarTitle, ":列表[", selectedCatalogName, "=", sortType, "=", (position + 1).toString(), "])")),
+ StringUtils.buildString(selectedCatalogName, ":", gameEntity.name),
+ event)
+
+ DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true, "star&brief")
+ } else if (holder is FooterViewHolder) {
+ holder.initItemPadding()
+ holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
+ holder.itemView.setOnClickListener {
+ if (mIsNetworkError) {
+ mViewModel.load(LoadType.RETRY)
+ }
+ }
+ }
+ }
+
+ fun notifyItemByDownload(download: DownloadEntity) {
+ for (key in positionAndPackageMap.keys) {
+ if (key.contains(download.packageName) && key.contains(download.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && mEntityList != null && position < mEntityList.size) {
+ mEntityList[position].getEntryMap()[download.platform] = download
+ notifyItemChanged(position)
+ }
+ }
+ }
+ }
+
+ fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
+ for (key in positionAndPackageMap.keys) {
+ if (key.contains(status.packageName) && key.contains(status.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && mEntityList != null && position < mEntityList.size) {
+ mEntityList[position].getEntryMap().remove(status.platform)
+ notifyItemChanged(position)
+ }
+ }
+ }
+ }
+
+ override fun getEventByPosition(pos: Int): ExposureEvent? {
+ return mExposureEventSparseArray.get(pos)
+ }
+
+ override fun getEventListByPosition(pos: Int): List? {
+ return null
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt
new file mode 100644
index 0000000000..08bb2be07d
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt
@@ -0,0 +1,154 @@
+package com.gh.gamecenter.catalog
+
+import android.os.Bundle
+import android.view.View
+import com.ethanhua.skeleton.Skeleton
+import com.gh.common.constant.Constants
+import com.gh.common.exposure.ExposureListener
+import com.gh.common.util.*
+import com.gh.common.view.CatalogFilterView
+import com.gh.common.xapk.XapkInstaller
+import com.gh.common.xapk.XapkUnzipStatus
+import com.gh.download.DownloadManager
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.entity.*
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.eventbus.EBPackage
+import com.lightgame.download.DataWatcher
+import com.lightgame.download.DownloadEntity
+import kotterknife.bindView
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class NewCatalogListFragment : ListFragment() {
+
+ private val mSkeletonView by bindView(R.id.list_skeleton)
+ private val mFilterView by bindView(R.id.filter_container)
+
+ private var mPrimeCatalog: CatalogEntity? = null
+ private var mSubCatalogList = arrayListOf()
+ private var mInitCatalogName = ""
+
+ private var mAdapter: NewCatalogListAdapter? = null
+ private val mDataWatcher = object : DataWatcher() {
+ override fun onDataChanged(downloadEntity: DownloadEntity) {
+ mAdapter?.notifyItemByDownload(downloadEntity)
+
+ if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
+ showUnzipFailureDialog(downloadEntity)
+ }
+ }
+ }
+
+ private lateinit var mExposureListener: ExposureListener
+ private lateinit var mViewModel: NewCatalogListViewModel
+
+ override fun getLayoutId() = R.layout.fragment_catalog_list
+
+ override fun provideListViewModel() = viewModelProvider()
+
+ override fun provideListAdapter() = mAdapter ?: NewCatalogListAdapter(requireContext(), mViewModel, mEntrance).apply { mAdapter = this }
+
+ override fun getItemDecoration() = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ mViewModel = provideListViewModel()
+
+ mViewModel.title = arguments?.getString(EntranceUtils.KEY_NAME) ?: ""
+ mViewModel.categoryTitle = arguments?.getString(EntranceUtils.KEY_CATALOG_TITLE) ?: ""
+ mEntrance = arguments?.getString(EntranceUtils.KEY_ENTRANCE) ?: Constants.ENTRANCE_UNKNOWN
+ mPrimeCatalog = arguments?.getParcelable(EntranceUtils.KEY_DATA)
+ mSubCatalogList = mPrimeCatalog?.subCatalog as ArrayList
+
+ mInitCatalogName = arguments?.getString(EntranceUtils.KEY_CATALOG_INIT_TITLE) ?: ""
+
+ mViewModel.selectedCatalog = mSubCatalogList.find { entity -> entity.name == mInitCatalogName }
+ ?: SubCatalogEntity()
+
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ setNavigationTitle(mViewModel.title)
+
+ initFilterView()
+
+ mViewModel.refresh.observeNonNull(this) { onRefresh() }
+
+ mExposureListener = ExposureListener(this, mAdapter!!)
+ mListRv.addOnScrollListener(mExposureListener)
+
+ mSkeletonScreen = Skeleton.bind(mSkeletonView).shimmer(false).load(R.layout.fragment_subject_skeleton).show()
+ }
+
+ private fun initFilterView() {
+ mFilterView.run {
+ visibility = View.VISIBLE
+ setTypeList(mPrimeCatalog?.switch ?: CatalogSwitch())
+ setCatalogList(mSubCatalogList, mInitCatalogName)
+ setOnConfigSetupListener(object : CatalogFilterView.OnCatalogFilterSetupListener {
+ override fun onSetupSortSize(sortSize: SubjectSettingEntity.Size) {
+ mViewModel.updateSortConfig(sortSize = sortSize)
+ }
+
+ override fun onSetupSortType(sortType: CatalogFilterView.SortType) {
+ mViewModel.updateSortConfig(sortType = sortType)
+ }
+
+ override fun onSetupSortCatalog(sortCatalog: SubCatalogEntity) {
+ mViewModel.updateSortConfig(sortCatalog = sortCatalog)
+ }
+ })
+ }
+
+ }
+
+ override fun onResume() {
+ if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
+ super.onResume()
+ DownloadManager.getInstance(context).addObserver(mDataWatcher)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ DownloadManager.getInstance(context).removeObserver(mDataWatcher)
+ }
+
+ override fun onRefresh() {
+ mAdapter?.clearPositionAndPackageMap()
+
+ super.onRefresh()
+ }
+
+ // 下载被删除事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(status: EBDownloadStatus) {
+ if ("delete" == status.status) {
+ mAdapter?.notifyItemAndRemoveDownload(status)
+ }
+ }
+
+ // 安装/卸载 事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(busFour: EBPackage) {
+ if ("安装" == busFour.type || "卸载" == busFour.type) {
+ mAdapter?.notifyDataSetChanged()
+ }
+ }
+
+ fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
+ val data = mAdapter?.positionAndPackageMap ?: return
+ for (gameAndPosition in data) {
+ if (gameAndPosition.key.contains(downloadEntity.packageName)) {
+ val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
+ if (targetView != null) {
+ DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
+ return
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListViewModel.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListViewModel.kt
new file mode 100644
index 0000000000..65971afac2
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListViewModel.kt
@@ -0,0 +1,82 @@
+package com.gh.gamecenter.catalog
+
+import android.app.Application
+import androidx.lifecycle.MutableLiveData
+import com.gh.common.util.UrlFilterUtils
+import com.gh.common.view.CatalogFilterView
+import com.gh.gamecenter.baselist.ListViewModel
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.entity.SubCatalogEntity
+import com.gh.gamecenter.entity.SubjectSettingEntity
+import com.gh.gamecenter.retrofit.RetrofitManager
+import io.reactivex.Observable
+import io.reactivex.Single
+
+class NewCatalogListViewModel(application: Application) : ListViewModel(application) {
+
+ var title = "" // 显示在 Toolbar 的标题
+ var categoryTitle = "" // 跳转进来的分类的标题
+
+ val refresh = MutableLiveData()
+
+ var selectedCatalog = SubCatalogEntity()
+ var sortType = CatalogFilterView.SortType.RECOMMENDED
+ private var mSortSize = SubjectSettingEntity.Size()
+ private val api = RetrofitManager.getInstance(getApplication()).api
+
+ override fun provideDataObservable(page: Int): Observable>? = null
+
+ override fun provideDataSingle(page: Int): Single> {
+ return if (selectedCatalog.link.type == "column") {
+ api.getColumn(selectedCatalog.link.link, getSortType(), getSortSize(), page)
+ } else {
+ api.getGamesWithSpecificTag(getSortSize(), getSortType(), page)
+ }
+ }
+
+ override fun mergeResultLiveData() {
+ mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
+ }
+
+ fun updateSortConfig(sortSize: SubjectSettingEntity.Size? = null,
+ sortType: CatalogFilterView.SortType? = null,
+ sortCatalog: SubCatalogEntity? = null) {
+ when {
+ sortSize != null && sortSize != mSortSize -> {
+ mSortSize = sortSize
+ refresh.postValue(true)
+ }
+
+ sortType != null && sortType != this.sortType -> {
+ this.sortType = sortType
+ refresh.postValue(true)
+ }
+
+ sortCatalog != null && sortCatalog != selectedCatalog -> {
+ selectedCatalog = sortCatalog
+ refresh.postValue(true)
+ }
+ }
+ }
+
+ private fun getSortSize(): String? {
+ return if (selectedCatalog.link.type == "column") {
+ UrlFilterUtils.getFilterQuery(
+ "min_size", mSortSize.min.toString(),
+ "max_size", mSortSize.max.toString())
+ } else {
+ UrlFilterUtils.getFilterQuery(
+ "tag_id", selectedCatalog.link.link,
+ "min_size", mSortSize.min.toString(),
+ "max_size", mSortSize.max.toString())
+ }
+ }
+
+ private fun getSortType(): String? {
+ return when (sortType) {
+ CatalogFilterView.SortType.RECOMMENDED -> "download:-1"
+ CatalogFilterView.SortType.NEWEST -> "publish:-1"
+ CatalogFilterView.SortType.RATING -> "star:-1"
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogAdapter.kt
new file mode 100644
index 0000000000..a945c52e5d
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogAdapter.kt
@@ -0,0 +1,192 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.constant.ItemViewType
+import com.gh.common.util.DirectUtils
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.CatalogHeaderItemBinding
+import com.gh.gamecenter.databinding.CatalogImageItemBinding
+import com.gh.gamecenter.databinding.CatalogSubjectCollectionItemBinding
+import com.gh.gamecenter.databinding.CatalogSubjectItemBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.subject.SubjectActivity.Companion.startSubjectActivity
+
+class SpecialCatalogAdapter(context: Context) : ListAdapter(context) {
+
+ override fun getItemCount() = if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT
+
+ override fun areItemsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
+ return when {
+ oldItem?.header != null && newItem?.header != null -> {
+ oldItem.header.id == newItem.header.id
+ }
+
+ oldItem?.bigImage != null && newItem?.bigImage != null -> {
+ oldItem.bigImage.id == newItem.bigImage.id
+ }
+
+ oldItem?.subject != null && newItem?.subject != null -> {
+ oldItem.subject.id == newItem.subject.id
+ }
+
+ oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
+ oldItem.subjectCollection.id == newItem.subjectCollection.id
+ }
+
+ else -> super.areItemsTheSame(oldItem, newItem)
+ }
+ }
+
+ override fun areContentsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
+ return when {
+ oldItem?.header != null && newItem?.header != null -> {
+ oldItem.header.id == newItem.header.id
+ }
+
+ oldItem?.bigImage != null && newItem?.bigImage != null -> {
+ oldItem.bigImage.id == newItem.bigImage.id
+ }
+
+ oldItem?.subject != null && newItem?.subject != null -> {
+ oldItem.subject.id == newItem.subject.id
+ }
+
+ oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
+ oldItem.subjectCollection.id == newItem.subjectCollection.id
+ }
+
+ else -> super.areItemsTheSame(oldItem, newItem)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ val view: View
+ return when (viewType) {
+ ItemViewType.ITEM_FOOTER -> {
+ view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
+ FooterViewHolder(view)
+ }
+
+ TYPE_HEADER -> CatalogHeaderItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_header_item, parent, false))
+
+ TYPE_BIG_IMAGE -> CatalogImageItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_image_item, parent, false))
+
+ TYPE_SUBJECT -> CatalogSubjectItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_item, parent, false))
+
+ TYPE_SUBJECT_COLLECTION -> CatalogSubjectCollectionItemHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_collection_item, parent, false))
+
+ else -> throw NullPointerException()
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is CatalogImageItemHolder -> {
+ val imageEntity = mEntityList[position].bigImage!!
+ holder.binding.run {
+ entity = imageEntity.image
+ root.setOnClickListener { DirectUtils.directToLinkPage(mContext, imageEntity.link, "新分类-精选分类", "图片") }
+ }
+ }
+
+ is CatalogHeaderItemHolder -> {
+ val entity = mEntityList[position].header!!
+ val specialLink = entity.link
+ holder.binding.run {
+ link = specialLink
+ headMore.setOnClickListener {
+ if (entity.type == "专题合集") {
+ DirectUtils.directToColumnCollection(mContext, specialLink.link ?: "", -1, "(游戏-专题:" + specialLink.text + "-全部)")
+ } else {
+ startSubjectActivity(mContext, specialLink.link, specialLink.text, false, "(游戏-专题:" + specialLink.text + "-全部)")
+ }
+ }
+ }
+ }
+
+ is CatalogSubjectItemHolder -> {
+ val subject = mEntityList[position].subject!!
+ holder.bindSubject(subject.link.data)
+ }
+
+ is CatalogSubjectCollectionItemHolder -> {
+ val subjectCollection = mEntityList[position].subjectCollection!!
+ holder.bindSubjectCollection(subjectCollection.link.data)
+ }
+
+ is FooterViewHolder -> {
+ holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
+ }
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return if (position == itemCount - 1) {
+ ItemViewType.ITEM_FOOTER
+ } else {
+ val item = mEntityList[position]
+ when {
+ item.header != null -> TYPE_HEADER
+ item.bigImage != null -> TYPE_BIG_IMAGE
+ item.subject != null -> TYPE_SUBJECT
+ item.subjectCollection != null -> TYPE_SUBJECT_COLLECTION
+ else -> TYPE_SUBJECT_COLLECTION
+ }
+ }
+ }
+
+ class CatalogImageItemHolder(val binding: CatalogImageItemBinding) : BaseRecyclerViewHolder(binding.root)
+
+ class CatalogHeaderItemHolder(val binding: CatalogHeaderItemBinding) : BaseRecyclerViewHolder(binding.root)
+
+ class CatalogSubjectItemHolder(val binding: CatalogSubjectItemBinding) : BaseRecyclerViewHolder(binding.root) {
+
+ fun bindSubject(gameList: List) {
+ binding.gameList.run {
+ var subjectAdapter = adapter
+ if (subjectAdapter is SpecialCatalogSubjectAdapter) {
+ subjectAdapter.checkResetData(gameList)
+ return
+ }
+ subjectAdapter = SpecialCatalogSubjectAdapter(context, gameList)
+ layoutManager = GridLayoutManager(context, 3)
+ adapter = subjectAdapter
+ }
+ }
+ }
+
+ class CatalogSubjectCollectionItemHolder(val binding: CatalogSubjectCollectionItemBinding) : BaseRecyclerViewHolder(binding.root) {
+
+ fun bindSubjectCollection(subjectCollection: List) {
+ binding.subjectCollectionList.run {
+ var collectionAdapter = adapter
+ if (collectionAdapter is SpecialCatalogSubjectCollectionAdapter) {
+ collectionAdapter.checkResetData(subjectCollection)
+ return
+ }
+ collectionAdapter = SpecialCatalogSubjectCollectionAdapter(context, subjectCollection)
+ layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
+ adapter = collectionAdapter
+ }
+ }
+ }
+
+ companion object {
+ private const val TYPE_HEADER = 900
+
+ private const val TYPE_BIG_IMAGE = 901
+
+ private const val TYPE_SUBJECT = 902
+
+ private const val TYPE_SUBJECT_COLLECTION = 903
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt
new file mode 100644
index 0000000000..40a28cd5b5
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt
@@ -0,0 +1,32 @@
+package com.gh.gamecenter.catalog
+
+import android.graphics.Color
+import android.os.Bundle
+import android.view.View
+import com.gh.common.util.*
+import com.gh.gamecenter.baselist.ListFragment
+
+class SpecialCatalogFragment : ListFragment() {
+
+ private var mCatalogId = ""
+
+ private var mAdapter: SpecialCatalogAdapter? = null
+
+ override fun provideListViewModel() = viewModelProvider(SpecialCatalogViewModel.Factory(mCatalogId))
+
+ override fun provideListAdapter() = mAdapter ?: SpecialCatalogAdapter(requireContext()).apply { mAdapter = this }
+
+ override fun getItemDecoration() = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
+
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ mListRv.setBackgroundColor(Color.WHITE)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogItemData.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogItemData.kt
new file mode 100644
index 0000000000..3f39494efc
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogItemData.kt
@@ -0,0 +1,10 @@
+package com.gh.gamecenter.catalog
+
+import com.gh.gamecenter.entity.SpecialCatalogEntity
+
+data class SpecialCatalogItemData(
+ val header: SpecialCatalogEntity? = null,
+ val bigImage: SpecialCatalogEntity? = null,
+ val subject: SpecialCatalogEntity? = null,
+ val subjectCollection: SpecialCatalogEntity? = null
+)
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectAdapter.kt
new file mode 100644
index 0000000000..d7a99b660d
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectAdapter.kt
@@ -0,0 +1,57 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.CatalogSubjectGameItemBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class SpecialCatalogSubjectAdapter(context: Context, private var mList: List) : BaseRecyclerAdapter(context) {
+
+ private val mEntrance = "精选分类"
+ private var countAndKey: Pair? = null
+
+ init {
+ var dataIds = ""
+ mList.forEach {
+ dataIds += it.id
+ }
+ if (dataIds.isNotEmpty()) countAndKey = Pair(mList.size, dataIds)
+ }
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = CatalogSubjectGameItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_game_item, parent, false))
+
+ override fun onBindViewHolder(holder: CatalogSubjectGameItemViewHolder, position: Int) {
+ holder.binding.run {
+ val entity = mList[position]
+ game = entity
+ root.setOnClickListener {
+ GameDetailActivity.startGameDetailActivity(mContext, entity, "(${mEntrance})")
+ }
+ }
+ }
+
+ fun checkResetData(update: List) {
+ var dataIds = ""
+ mList.forEach { dataIds += it.id }
+
+ mList = update
+ if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
+ notifyItemRangeChanged(0, itemCount)
+ } else if (countAndKey?.first != update.size) { // 数量发生改变
+ notifyDataSetChanged()
+ }
+
+ // 重新刷新数据标识
+ countAndKey = Pair(update.size, dataIds)
+ }
+
+ class CatalogSubjectGameItemViewHolder(val binding: CatalogSubjectGameItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectCollectionAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectCollectionAdapter.kt
new file mode 100644
index 0000000000..c85d2e7ba7
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogSubjectCollectionAdapter.kt
@@ -0,0 +1,61 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.ImageUtils
+import com.gh.common.util.dip2px
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.CatalogSubjectCollectionListItemBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.entity.LinkEntity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class SpecialCatalogSubjectCollectionAdapter(context: Context, private var mList: List) : BaseRecyclerAdapter(context) {
+
+ private var countAndKey: Pair? = null
+
+ init {
+ var dataIds = ""
+ mList.forEach {
+ dataIds += it.id
+ }
+ if (dataIds.isNotEmpty()) countAndKey = Pair(mList.size, dataIds)
+ }
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = CatalogSubjectCollectionListItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.catalog_subject_collection_list_item, parent, false))
+
+
+ override fun onBindViewHolder(holder: CatalogSubjectCollectionListItemViewHolder, position: Int) {
+ holder.binding.run {
+ root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
+ leftMargin = if (position == 0) 16F.dip2px() else 0
+ }
+ val entity = mList[position]
+ ImageUtils.display(subjectCollectionImage, entity.image)
+ root.setOnClickListener { DirectUtils.directToLinkPage(mContext, LinkEntity(link = entity.link, type = entity.type), "精选分类", "专题合集") }
+ }
+ }
+
+ fun checkResetData(update: List) {
+ var dataIds = ""
+ mList.forEach { dataIds += it.id }
+
+ mList = update
+ if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
+ notifyItemRangeChanged(0, itemCount)
+ } else if (countAndKey?.first != update.size) { // 数量发生改变
+ notifyDataSetChanged()
+ }
+
+ // 重新刷新数据标识
+ countAndKey = Pair(update.size, dataIds)
+ }
+
+ class CatalogSubjectCollectionListItemViewHolder(val binding: CatalogSubjectCollectionListItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogViewModel.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogViewModel.kt
new file mode 100644
index 0000000000..fcb1147d03
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogViewModel.kt
@@ -0,0 +1,50 @@
+package com.gh.gamecenter.catalog
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.gh.gamecenter.baselist.ListViewModel
+import com.gh.gamecenter.entity.SpecialCatalogEntity
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.Observable
+import io.reactivex.Single
+
+class SpecialCatalogViewModel(application: Application, private val catalogId: String): ListViewModel(application) {
+
+ override fun provideDataObservable(page: Int): Observable>? = null
+
+ override fun provideDataSingle(page: Int): Single> {
+ return RetrofitManager.getInstance(getApplication())
+ .sensitiveApi
+ .getSpecialCatalogs(catalogId, page)
+ }
+
+ override fun mergeResultLiveData() {
+ mResultLiveData.addSource(mListLiveData) { list ->
+ val itemDataList = arrayListOf()
+ list.forEach {
+ when (it.type) {
+ "图片" -> itemDataList.add(SpecialCatalogItemData(bigImage = it))
+
+ "专题" -> {
+ itemDataList.add(SpecialCatalogItemData(header = it))
+ itemDataList.add(SpecialCatalogItemData(subject = it))
+ }
+
+ "专题合集" -> {
+ itemDataList.add(SpecialCatalogItemData(header = it))
+ itemDataList.add(SpecialCatalogItemData(subjectCollection = it))
+ }
+ }
+ }
+ mResultLiveData.postValue(itemDataList)
+ }
+ }
+
+ class Factory(private val catalogId: String) : ViewModelProvider.NewInstanceFactory() {
+ override fun create(modelClass: Class): T {
+ return SpecialCatalogViewModel(HaloApp.getInstance().application, catalogId) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogAdapter.kt b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogAdapter.kt
new file mode 100644
index 0000000000..fed4d6a710
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogAdapter.kt
@@ -0,0 +1,35 @@
+package com.gh.gamecenter.catalog
+
+import android.content.Context
+import android.view.ViewGroup
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.SubCatalogItemBinding
+import com.gh.gamecenter.entity.CatalogEntity
+import com.gh.gamecenter.entity.SubCatalogEntity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class SubCatalogAdapter(context: Context, private val mPrimaryCatalog: CatalogEntity, private var mList: List) : BaseRecyclerAdapter(context) {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubCatalogItemViewHolder {
+ val view = mLayoutInflater.inflate(R.layout.sub_catalog_item, parent, false)
+ return SubCatalogItemViewHolder(SubCatalogItemBinding.bind(view))
+ }
+
+ override fun getItemCount(): Int {
+ return mList.size
+ }
+
+ override fun onBindViewHolder(holder: SubCatalogItemViewHolder, position: Int) {
+ holder.binding.run {
+ val catalogEntity = mList[position]
+ entity = catalogEntity
+ executePendingBindings()
+ root.setOnClickListener {
+ root.context.startActivity(NewCatalogListActivity.getIntent(mContext, catalogEntity.name, mPrimaryCatalog, catalogEntity.name))
+ }
+ }
+ }
+
+ class SubCatalogItemViewHolder(val binding: SubCatalogItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogFragment.kt
new file mode 100644
index 0000000000..42b4c21163
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogFragment.kt
@@ -0,0 +1,84 @@
+package com.gh.gamecenter.catalog
+
+import android.os.Bundle
+import android.view.View
+import android.widget.LinearLayout
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.EntranceUtils
+import com.gh.common.util.viewModelProvider
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.CatalogEntity
+import com.gh.gamecenter.normal.NormalFragment
+import kotterknife.bindView
+
+class SubCatalogFragment : NormalFragment() {
+
+ private val mReuseLoading by bindView(R.id.reuse_ll_loading)
+ private val mReuseNoConnection by bindView(R.id.reuse_no_connection)
+ private val mReuseNoData by bindView(R.id.reuse_none_data)
+ private val mSubCatalogRv by bindView(R.id.rv_sub_catalog)
+
+ private lateinit var mViewModel: SubCatalogViewModel
+ private lateinit var mSubCatalogAdapter: SubCatalogAdapter
+ private lateinit var mEntity: CatalogEntity
+ private var mCatalogId: String = ""
+ private var mPrimaryCatalogId: String = ""
+
+ override fun getLayoutId() = R.layout.fragment_sub_catalog
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ mCatalogId = arguments?.getString(EntranceUtils.KEY_CATALOG_ID) ?: ""
+ mPrimaryCatalogId = arguments?.getString(EntranceUtils.KEY_PRIMARY_CATALOG_ID) ?: ""
+ mViewModel = viewModelProvider(SubCatalogViewModel.Factory(mCatalogId))
+ mViewModel.getSubCatalogs(mPrimaryCatalogId)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ mViewModel.catalogs.observe(viewLifecycleOwner, Observer {
+ mReuseLoading.visibility = View.GONE
+ if (it != null) {
+ mReuseNoConnection.visibility = View.GONE
+ if (it.subCatalog.isNotEmpty()) {
+ mSubCatalogRv.visibility = View.VISIBLE
+ mReuseNoData.visibility = View.GONE
+ mEntity = it
+ initView()
+ } else {
+ mSubCatalogRv.visibility = View.GONE
+ mReuseNoData.visibility = View.VISIBLE
+ }
+ } else {
+ mSubCatalogRv.visibility = View.GONE
+ mReuseNoData.visibility = View.GONE
+ mReuseNoConnection.visibility = View.VISIBLE
+ mReuseNoConnection.setOnClickListener {
+ mReuseLoading.visibility = View.VISIBLE
+ mViewModel.getSubCatalogs(mPrimaryCatalogId)
+ }
+ }
+ })
+ }
+
+ private fun initView() {
+ mEntity.run {
+ mSubCatalogRv.layoutManager = GridLayoutManager(requireContext(), 3)
+ mSubCatalogAdapter = SubCatalogAdapter(requireContext(), mEntity, subCatalog)
+ mSubCatalogRv.adapter = mSubCatalogAdapter
+ }
+ }
+
+ fun changeSubCatalog(primaryCatalogId: String) {
+ mPrimaryCatalogId = primaryCatalogId
+ mSubCatalogRv.visibility = View.GONE
+ mReuseNoData.visibility = View.GONE
+ mReuseNoConnection.visibility = View.GONE
+ mReuseLoading.visibility = View.VISIBLE
+ mViewModel.getSubCatalogs(mPrimaryCatalogId)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogViewModel.kt b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogViewModel.kt
new file mode 100644
index 0000000000..12acf47463
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/catalog/SubCatalogViewModel.kt
@@ -0,0 +1,44 @@
+package com.gh.gamecenter.catalog
+
+import android.annotation.SuppressLint
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.gh.gamecenter.entity.CatalogEntity
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+
+class SubCatalogViewModel(application: Application, private val catalogId: String): AndroidViewModel(application) {
+
+ private val api = RetrofitManager.getInstance(getApplication()).api
+ var catalogs = MutableLiveData()
+
+
+ @SuppressLint("CheckResult")
+ fun getSubCatalogs(primaryCatalogId: String) {
+ api.getSubCatalogs(catalogId, primaryCatalogId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: CatalogEntity) {
+ catalogs.postValue(data)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ catalogs.postValue(null)
+ }
+ })
+ }
+
+ class Factory(private val catalogId: String) : ViewModelProvider.NewInstanceFactory() {
+ override fun create(modelClass: Class): T {
+ return SubCatalogViewModel(HaloApp.getInstance().application, catalogId) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt
index faf8d247c3..e528b19922 100644
--- a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt
@@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.common.util.EntranceUtils
-import com.gh.download.DownloadManager
import com.gh.gamecenter.NormalActivity
import com.gh.gamecenter.R
diff --git a/app/src/main/java/com/gh/gamecenter/category/NewCategoryHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/category/NewCategoryHorizontalAdapter.kt
index 430bdfd80b..cd078096e8 100644
--- a/app/src/main/java/com/gh/gamecenter/category/NewCategoryHorizontalAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/category/NewCategoryHorizontalAdapter.kt
@@ -27,21 +27,16 @@ class NewCategoryHorizontalAdapter(context: Context,
override fun onBindViewHolder(holder: TagsViewHolder, position: Int) {
val categoryEntity = mCategoryList[position]
- val gradientDrawable = GradientDrawable()
- gradientDrawable.shape = GradientDrawable.RECTANGLE
if (mViewModel.selectedCategory.name == categoryEntity.name) {
- gradientDrawable.setColor(ContextCompat.getColor(mContext, R.color.theme))
- gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
+ holder.tagTv.background = ContextCompat.getDrawable(mContext, R.drawable.bg_tag_text)
holder.tagTv.setTextColor(Color.WHITE)
} else {
- gradientDrawable.setColor(Color.WHITE)
- gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
- holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_3a3a3a))
+ holder.tagTv.background = null
+ holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_757575))
}
holder.tagTv.text = categoryEntity.name
- holder.tagTv.background = gradientDrawable
holder.tagTv.setOnClickListener {
mViewModel.changeSelectedCategory(categoryEntity)
notifyDataSetChanged()
diff --git a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListAdapter.kt b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListAdapter.kt
index affa700591..6143b0e9cb 100644
--- a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListAdapter.kt
@@ -11,6 +11,7 @@ import com.gh.common.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.StringUtils
+import com.gh.common.util.dip2px
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
@@ -85,6 +86,9 @@ class NewCategoryListAdapter(context: Context,
holder.initServerType(gameEntity)
holder.binding.executePendingBindings()
+ val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
+ holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
+
gameEntity.sequence = position + 1
val sortType = if ("download:-1" == mViewModel.getSortType()) "最热" else "最新"
diff --git a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
index c0be80e13e..b40ef98c2f 100644
--- a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
@@ -114,6 +114,8 @@ class NewCategoryListFragment : ListFragment = emptyList()
+): Parcelable
+
+@Parcelize
+data class SubCatalogEntity(
+ @SerializedName("_id")
+ var id: String = "",
+ var name: String = "",
+ var icon: String = "",
+ var link: LinkEntity = LinkEntity(),
+ var recommended: Boolean = false
+): Parcelable
+
+@Parcelize
+data class CatalogSwitch(
+ @SerializedName("sort_hot")
+ var hotSort: String = "",
+ @SerializedName("sort_new")
+ var newSort: String = "",
+ @SerializedName("sort_star")
+ var starSort: String = ""
+): Parcelable
+
+@Parcelize
+data class SpecialCatalogEntity(
+ @SerializedName("_id")
+ var id: String = "",
+ var type: String = "",
+ var link: SpecialLink = SpecialLink(),
+ var image: Image = Image()
+): Parcelable
+
+@Parcelize
+data class SpecialLink(
+ @SerializedName("_id")
+ var id: String = "",
+ var data: List = emptyList()
+): LinkEntity(), Parcelable
+
+@Parcelize
+data class Image(
+ var url: String = "",
+ var title: String = ""
+): Parcelable
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 cd18696a01..0786ca9217 100644
--- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
@@ -24,6 +24,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.ImagePagerAdapter
import com.gh.gamecenter.adapter.viewholder.*
import com.gh.gamecenter.baselist.LoadStatus
+import com.gh.gamecenter.catalog.CatalogActivity
import com.gh.gamecenter.category.CategoryDirectoryActivity
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.CommunityEntity
@@ -419,6 +420,7 @@ class GameFragmentAdapter(context: Context,
entity.type == "column_collection" -> DirectUtils.directToColumnCollection(mContext, entity.link!!, -1, "(推荐入口)")
entity.type == "block" -> mContext.startActivity(BlockActivity.getIntent(mContext, entity, "(推荐入口)"))
entity.type == "category" -> mContext.startActivity(CategoryDirectoryActivity.getIntent(mContext, entity.link!!, entity.text!!))
+ entity.type == "catalog" -> mContext.startActivity(CatalogActivity.getIntent(mContext, entity.link!!, entity.text!!))
entity.type == "column" -> {
SubjectActivity.startSubjectActivity(mContext, entity.link, entity.text, entity.order
, StringUtils.buildString("(游戏-专题:", entity.name, "[1-", (data + 1).toString(), "]", ")"))
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
index d215037396..d4246f3c25 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
@@ -273,7 +273,7 @@ class UserHomeFragment : NormalFragment() {
?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count)
val fragmentList = listOf(commentFragment, qaFragment, videoFragment)
- val titleList = listOf("游戏评论", "问答", "视频")
+ val titleList = listOf("游戏评论", "我的论坛", "视频")
val countList = listOf(count.gameComment, count.getQaCount(), count.video)
viewpager.offscreenPageLimit = fragmentList.size
diff --git a/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskWrapperFragment.java b/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskWrapperFragment.java
index cfa97d81f6..800b729c1e 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskWrapperFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskWrapperFragment.java
@@ -44,7 +44,7 @@ public class MyAskWrapperFragment extends BaseFragment_TabLayout {
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- setNavigationTitle(R.string.myask);
+ setNavigationTitle(R.string.my_forum);
initMenu(R.menu.menu_my_ask_wrapper);
}
diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
index 091c532484..91f5e75235 100644
--- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
+++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
@@ -11,6 +11,7 @@ import com.gh.gamecenter.entity.AuthDialogEntity;
import com.gh.gamecenter.entity.AvatarBorderEntity;
import com.gh.gamecenter.entity.BackgroundImageEntity;
import com.gh.gamecenter.entity.BadgeEntity;
+import com.gh.gamecenter.entity.CatalogEntity;
import com.gh.gamecenter.entity.CategoryEntity;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.CommentnumEntity;
@@ -60,6 +61,7 @@ import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SignEntity;
import com.gh.gamecenter.entity.SimpleGameEntity;
import com.gh.gamecenter.entity.SimulatorEntity;
+import com.gh.gamecenter.entity.SpecialCatalogEntity;
import com.gh.gamecenter.entity.SubjectEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.SubjectRefreshEntity;
@@ -304,7 +306,7 @@ public interface ApiService {
* 获取专题数据
*/
@GET("columns/{column_id}/games")
- Observable> getColumn(@Path("column_id") String column_id, @Query("sort") String sort, @Query("filter") String order, @Query("page") int page);
+ Single> getColumn(@Path("column_id") String column_id, @Query("sort") String sort, @Query("filter") String order, @Query("page") int page);
/**
* 获取专题数据标题
@@ -2725,6 +2727,7 @@ public interface ApiService {
Single> getSimulatorGames(@Path("device_id") String deviceId, @Query("page") int page, @Query("filter") String filter);
/**
+<<<<<<< HEAD
* 搜索用户
*/
@GET("./users:search")
@@ -2759,4 +2762,22 @@ public interface ApiService {
*/
@GET("packages/{package}/redirect")
Single redirectGameDetail(@Path("package") String packageName);
+
+ /**
+ * 获取一级分类数据
+ */
+ @GET("catalogs/{catalog_id}")
+ Single getCatalogs(@Path("catalog_id") String catalogId);
+
+ /**
+ * 获取一级分类数据 及其 二级分类数据
+ */
+ @GET("catalogs/{catalog_id}/{primary_catalog_id}")
+ Single getSubCatalogs(@Path("catalog_id") String catalogId, @Path("primary_catalog_id") String primaryCatalogId);
+
+ /**
+ * 获取精选分类
+ */
+ @GET("catalogs/{catalog_id}/special")
+ Single> getSpecialCatalogs(@Path("catalog_id") String catalogId, @Query("page") int page);
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt
index cff3003518..a4fd1131cf 100644
--- a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt
@@ -125,21 +125,22 @@ open class SearchDefaultFragment : BaseFragment() {
val flexCell = TextView(context)
flexView.addView(flexCell)
- val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 25F.dip2px())
+ val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
params.setMargins(0, 0, 16F.dip2px(), 16F.dip2px())
flexCell.layoutParams = params
flexCell.setSingleLine()
flexCell.ellipsize = TextUtils.TruncateAt.END
- flexCell.textSize = 13f
+ flexCell.textSize = 12F
flexCell.gravity = Gravity.CENTER
flexCell.text = contentList[index]
- flexCell.setTextColor(Color.WHITE)
- flexCell.setPadding(10F.dip2px(), 0, 10F.dip2px(), 0)
+ flexCell.maxEms = 6
+ flexCell.setTextColor(R.color.text_666666.toColor())
+ if (!isHistoryFlex) flexCell.setPadding(8F.dip2px(), 6F.dip2px(), 8F.dip2px(), 6F.dip2px())
flexCell.background = if (isHistoryFlex) {
- DrawableView.getOvalDrawable(R.color.text_d5d5d5)
+ null
} else {
- DrawableView.getOvalDrawable(R.color.theme)
+ DrawableView.getOvalDrawable(R.color.text_F5F5F5)
}
flexCell.setOnClickListener {
clickListener.invoke(index)
diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
index ff35b8c683..be2be22431 100644
--- a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt
@@ -14,18 +14,18 @@ import com.gh.common.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.*
+import com.gh.common.view.DrawableView
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.adapter.viewholder.SearchHistoryViewHolder
import com.gh.gamecenter.baselist.ListAdapter
-import com.gh.gamecenter.databinding.GameItemBinding
+import com.gh.gamecenter.databinding.SearchGameIndexItemBinding
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBSearch
-import com.gh.gamecenter.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus
@@ -66,8 +66,8 @@ class SearchGameIndexAdapter(context: Context,
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == ItemViewType.GAME_NORMAL) {
val itemView = LayoutInflater.from(viewGroup.context)
- .inflate(R.layout.game_item, viewGroup, false)
- GameItemViewHolder(GameItemBinding.bind(itemView))
+ .inflate(R.layout.search_game_index_item, viewGroup, false)
+ SearchGameIndexItemViewHolder(SearchGameIndexItemBinding.bind(itemView))
} else {
val itemView = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.fm_search_history_item, viewGroup, false)
@@ -87,19 +87,11 @@ class SearchGameIndexAdapter(context: Context,
ExposureType.EXPOSURE)
exposureEventArray!!.put(position, exposureEvent)
- if (holder is GameItemViewHolder) {
- if (position == 0) {
- holder.itemView.setPadding(
- DisplayUtils.dip2px(16f), DisplayUtils.dip2px(20f),
- DisplayUtils.dip2px(20f), DisplayUtils.dip2px(8f))
- } else {
- holder.itemView.setPadding(
- DisplayUtils.dip2px(16f), DisplayUtils.dip2px(8f),
- DisplayUtils.dip2px(20f), DisplayUtils.dip2px(8f))
- }
-
+ if (holder is SearchGameIndexItemViewHolder) {
val binding = holder.binding
- binding.game = gameEntity
+ binding.gameItemIncluded.game = gameEntity
+ binding.divider.goneIf(position == 0)
+ binding.gameItemIncluded.root.setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 16F.dip2px())
holder.initServerType(gameEntity)
binding.executePendingBindings()
@@ -126,7 +118,7 @@ class SearchGameIndexAdapter(context: Context,
DownloadItemUtils.setOnClickListenerWithInvokeCallbackForAllState(
mContext,
- binding.downloadBtn,
+ binding.gameItemIncluded.downloadBtn,
gameEntity,
holder.adapterPosition,
this,
@@ -134,7 +126,7 @@ class SearchGameIndexAdapter(context: Context,
"搜索-列表:" + gameEntity.name!!,
exposureEvent, object : EmptyCallback {
override fun onCallback() {
- Util_System_Keyboard.hideSoftKeyboardByIBinder(mContext, binding.downloadBtn.windowToken)
+ Util_System_Keyboard.hideSoftKeyboardByIBinder(mContext, binding.gameItemIncluded.downloadBtn.windowToken)
if (searchMap[gameEntity.id] == null) {
EventBus.getDefault().post(EBSearch("search", gameEntity.id, gameEntity.name))
@@ -150,10 +142,9 @@ class SearchGameIndexAdapter(context: Context,
}
)
- DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(binding), true)
+ DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(binding.gameItemIncluded), true)
} else if (holder is SearchHistoryViewHolder) {
holder.searchHistoryName.text = gameEntity.name
- holder.searchHistoryLine.visibility = View.GONE
holder.itemView.setOnClickListener {
if (searchMap[gameEntity.id] == null) {
EventBus.getDefault().post(EBSearch("search", gameEntity.id, gameEntity.name))
@@ -215,4 +206,25 @@ class SearchGameIndexAdapter(context: Context,
}
}
}
+
+ class SearchGameIndexItemViewHolder(var binding: SearchGameIndexItemBinding) : RecyclerView.ViewHolder(binding.root) {
+ fun initServerType(gameEntity: GameEntity) {
+ val serverLabel = gameEntity.serverLabel
+ when {
+ gameEntity.test != null -> {
+ binding.gameItemIncluded.gameKaifuType.visibility = View.GONE
+ binding.gameItemIncluded.gameKaifuType.text = ""
+ }
+ serverLabel != null -> {
+ binding.gameItemIncluded.gameKaifuType.visibility = View.VISIBLE
+ binding.gameItemIncluded.gameKaifuType.text = serverLabel.value
+ binding.gameItemIncluded.gameKaifuType.background = DrawableView.getServerDrawable(serverLabel.color)
+ }
+ else -> binding.gameItemIncluded.gameKaifuType.visibility = View.GONE
+ }
+
+ // 由于RecyclerView的复用机制 需要每次测量gameName的宽
+ binding.gameItemIncluded.gameName.requestLayout()
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt
index 24ed674125..77c65c6b18 100644
--- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt
@@ -12,6 +12,7 @@ import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
+import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
@@ -23,7 +24,9 @@ class SubjectListViewModel(application: Application,
var selectedLabelList = arrayListOf()
var selectedFilterSize = SubjectSettingEntity.Size(text = "全部大小")
- override fun provideDataObservable(page: Int): Observable> {
+ override fun provideDataObservable(page: Int): Observable>? = null
+
+ override fun provideDataSingle(page: Int): Single> {
return RetrofitManager.getInstance(getApplication()).sensitiveApi.getColumn(
subjectData.subjectId,
subjectData.sort,
diff --git a/app/src/main/java/com/gh/gamecenter/tag/TagsHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/tag/TagsHorizontalAdapter.kt
index 0c5d7da21f..c68ae9a698 100644
--- a/app/src/main/java/com/gh/gamecenter/tag/TagsHorizontalAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/tag/TagsHorizontalAdapter.kt
@@ -2,14 +2,12 @@ package com.gh.gamecenter.tag
import android.content.Context
import android.graphics.Color
-import android.graphics.drawable.GradientDrawable
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import butterknife.BindView
import com.gh.base.BaseRecyclerViewHolder
-import com.gh.common.util.DisplayUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.TagEntity
import com.lightgame.adapter.BaseRecyclerAdapter
@@ -26,21 +24,16 @@ class TagsHorizontalAdapter(context: Context,
override fun onBindViewHolder(holder: TagsViewHolder, position: Int) {
val tagEntity = mTagList[position]
- val gradientDrawable = GradientDrawable()
- gradientDrawable.shape = GradientDrawable.RECTANGLE
if (mViewModel.selectedTag.name == tagEntity.name) {
- gradientDrawable.setColor(ContextCompat.getColor(mContext, R.color.theme))
- gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
+ holder.tagTv.background = ContextCompat.getDrawable(mContext, R.drawable.bg_tag_text)
holder.tagTv.setTextColor(Color.WHITE)
} else {
- gradientDrawable.setColor(Color.WHITE)
- gradientDrawable.cornerRadius = DisplayUtils.dip2px(999f).toFloat()
- holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_3a3a3a))
+ holder.tagTv.background = null
+ holder.tagTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_757575))
}
holder.tagTv.text = tagEntity.name
- holder.tagTv.background = gradientDrawable
holder.tagTv.setOnClickListener {
mViewModel.changeSelectedTag(tagEntity)
notifyDataSetChanged()
diff --git a/app/src/main/java/com/gh/gamecenter/tag/TagsListAdapter.kt b/app/src/main/java/com/gh/gamecenter/tag/TagsListAdapter.kt
index 5aa69e1f41..83d913e38d 100644
--- a/app/src/main/java/com/gh/gamecenter/tag/TagsListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/tag/TagsListAdapter.kt
@@ -9,6 +9,7 @@ import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.IExposable
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.StringUtils
+import com.gh.common.util.dip2px
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
@@ -82,6 +83,9 @@ class TagsListAdapter(context: Context,
holder.initServerType(gameEntity)
holder.binding.executePendingBindings()
+ val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
+ holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
+
gameEntity.sequence = position + 1
val exposureSource = ExposureSource("标签详情", "${mViewModel.selectedTag.name} + ${mViewModel.getSortTypeInChinese()}")
diff --git a/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt b/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt
index 522d781cfd..899aa3bd5b 100644
--- a/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt
@@ -121,6 +121,8 @@ class TagsListFragment : ListFragment() {
DownloadManager.getInstance(context).removeObserver(mDataWatcher)
}
+ override fun getItemDecoration() = null
+
override fun getLayoutId(): Int {
return R.layout.fragment_tags
}
diff --git a/app/src/main/res/drawable-xhdpi/ic_filter_arrow_down.png b/app/src/main/res/drawable-xhdpi/ic_filter_arrow_down.png
deleted file mode 100644
index 3efcaad3eb..0000000000
Binary files a/app/src/main/res/drawable-xhdpi/ic_filter_arrow_down.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_filter_arrow_up.png b/app/src/main/res/drawable-xhdpi/ic_filter_arrow_up.png
deleted file mode 100644
index f7b2f0d52a..0000000000
Binary files a/app/src/main/res/drawable-xhdpi/ic_filter_arrow_up.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/search_history_delete.png b/app/src/main/res/drawable-xhdpi/search_history_delete.png
deleted file mode 100644
index b1803b9e40..0000000000
Binary files a/app/src/main/res/drawable-xhdpi/search_history_delete.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_catalog_selected.png b/app/src/main/res/drawable-xxhdpi/ic_catalog_selected.png
new file mode 100755
index 0000000000..08fdeaa2d3
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_catalog_selected.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_down.png b/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_down.png
new file mode 100755
index 0000000000..cd1d3b5f3b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_down.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_up.png b/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_up.png
new file mode 100755
index 0000000000..c8abc870f0
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_filter_arrow_up.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_recommend.png b/app/src/main/res/drawable-xxhdpi/ic_recommend.png
new file mode 100755
index 0000000000..17285800a7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_recommend.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/search_history_delete.png b/app/src/main/res/drawable-xxhdpi/search_history_delete.png
new file mode 100755
index 0000000000..420fcc7e15
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/search_history_delete.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_catalog_selected.png b/app/src/main/res/drawable-xxxhdpi/ic_catalog_selected.png
new file mode 100755
index 0000000000..c08b758478
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_catalog_selected.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_down.png b/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_down.png
new file mode 100755
index 0000000000..8e70509fa2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_down.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_up.png b/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_up.png
new file mode 100755
index 0000000000..39fcfcbaf4
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_filter_arrow_up.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_recommend.png b/app/src/main/res/drawable-xxxhdpi/ic_recommend.png
new file mode 100755
index 0000000000..9c81073cd4
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_recommend.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/search_history_delete.png b/app/src/main/res/drawable-xxxhdpi/search_history_delete.png
new file mode 100755
index 0000000000..313a4ee350
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/search_history_delete.png differ
diff --git a/app/src/main/res/drawable/actionbar_search_bg.xml b/app/src/main/res/drawable/actionbar_search_bg.xml
index 22f407e085..737aab1104 100644
--- a/app/src/main/res/drawable/actionbar_search_bg.xml
+++ b/app/src/main/res/drawable/actionbar_search_bg.xml
@@ -1,9 +1,9 @@
-
+
-
+
-
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_sub_catalog_item.xml b/app/src/main/res/drawable/bg_sub_catalog_item.xml
new file mode 100644
index 0000000000..6710f5e133
--- /dev/null
+++ b/app/src/main/res/drawable/bg_sub_catalog_item.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_tag_text.xml b/app/src/main/res/drawable/bg_tag_text.xml
new file mode 100644
index 0000000000..078c47dd4e
--- /dev/null
+++ b/app/src/main/res/drawable/bg_tag_text.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_header_item.xml b/app/src/main/res/layout/catalog_header_item.xml
new file mode 100644
index 0000000000..6859798ffc
--- /dev/null
+++ b/app/src/main/res/layout/catalog_header_item.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_image_item.xml b/app/src/main/res/layout/catalog_image_item.xml
new file mode 100644
index 0000000000..5312f8daa0
--- /dev/null
+++ b/app/src/main/res/layout/catalog_image_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_item.xml b/app/src/main/res/layout/catalog_item.xml
new file mode 100644
index 0000000000..54f3309eb9
--- /dev/null
+++ b/app/src/main/res/layout/catalog_item.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_subject_collection_item.xml b/app/src/main/res/layout/catalog_subject_collection_item.xml
new file mode 100644
index 0000000000..2cfeff5c6e
--- /dev/null
+++ b/app/src/main/res/layout/catalog_subject_collection_item.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/catalog_subject_collection_list_item.xml b/app/src/main/res/layout/catalog_subject_collection_list_item.xml
new file mode 100644
index 0000000000..5d1e42dee8
--- /dev/null
+++ b/app/src/main/res/layout/catalog_subject_collection_list_item.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_subject_game_item.xml b/app/src/main/res/layout/catalog_subject_game_item.xml
new file mode 100644
index 0000000000..33153bc6f3
--- /dev/null
+++ b/app/src/main/res/layout/catalog_subject_game_item.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/catalog_subject_item.xml b/app/src/main/res/layout/catalog_subject_item.xml
new file mode 100644
index 0000000000..009bbac5a7
--- /dev/null
+++ b/app/src/main/res/layout/catalog_subject_item.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fm_search_history_item.xml b/app/src/main/res/layout/fm_search_history_item.xml
index 4fbbf05e86..4701e1c563 100644
--- a/app/src/main/res/layout/fm_search_history_item.xml
+++ b/app/src/main/res/layout/fm_search_history_item.xml
@@ -1,29 +1,27 @@
-
+
+ android:id="@+id/search_history_line"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:background="@color/text_F5F5F5" />
-
-
+ android:id="@+id/search_history_name"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:ellipsize="end"
+ android:gravity="center_vertical"
+ android:padding="16dp"
+ android:singleLine="true"
+ android:textColor="@color/bg_303030"
+ android:textSize="14sp" />
+
diff --git a/app/src/main/res/layout/fragment_catalog.xml b/app/src/main/res/layout/fragment_catalog.xml
new file mode 100644
index 0000000000..cfa38a7b4a
--- /dev/null
+++ b/app/src/main/res/layout/fragment_catalog.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_catalog_list.xml b/app/src/main/res/layout/fragment_catalog_list.xml
new file mode 100644
index 0000000000..3611e77cc9
--- /dev/null
+++ b/app/src/main/res/layout/fragment_catalog_list.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_search_default.xml b/app/src/main/res/layout/fragment_search_default.xml
index 5f97472ea5..f79380e696 100644
--- a/app/src/main/res/layout/fragment_search_default.xml
+++ b/app/src/main/res/layout/fragment_search_default.xml
@@ -25,16 +25,12 @@
visibleGone="@{isExistHistory}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:background="@android:color/white"
android:includeFontPadding="false"
- android:paddingLeft="20dp"
- android:paddingTop="16dp"
- android:paddingRight="20dp"
- android:paddingBottom="16dp"
+ android:padding="16dp"
android:text="@string/search_history"
- android:textColor="@color/black"
- android:textSize="15sp"
+ android:textColor="@color/text_0E0E0E"
+ android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -44,11 +40,12 @@
visibleGone="@{isExistHistory}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="20dp"
+ android:layout_marginRight="16dp"
android:drawableLeft="@drawable/search_history_delete"
- android:drawablePadding="8dp"
- android:text="@string/search_history_clean"
+ android:drawablePadding="4dp"
+ android:textColor="@color/text_999999"
android:textSize="12sp"
+ android:text="@string/search_history_clean"
app:layout_constraintBottom_toBottomOf="@id/history_title"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/history_title" />
@@ -65,8 +62,7 @@
visibleGone="@{isExistHistory}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="20dp"
- android:paddingBottom="5dp"
+ android:paddingLeft="16dp"
app:flexWrap="wrap" />
@@ -75,16 +71,12 @@
visibleGone="@{isExistHotTag}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:background="@android:color/white"
android:includeFontPadding="false"
- android:paddingLeft="20dp"
- android:paddingTop="16dp"
- android:paddingRight="20dp"
- android:paddingBottom="16dp"
+ android:padding="16dp"
android:text="@string/search_hot_tag"
- android:textColor="@color/black"
- android:textSize="15sp"
+ android:textColor="@color/text_0E0E0E"
+ android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/history_flex_container" />
@@ -101,8 +93,7 @@
visibleGone="@{isExistHotTag}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="20dp"
- android:paddingBottom="7dp"
+ android:paddingLeft="16dp"
app:flexWrap="wrap" />
@@ -111,16 +102,12 @@
visibleGone="@{isExistHotSearch}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:background="@android:color/white"
android:includeFontPadding="false"
- android:paddingLeft="20dp"
- android:paddingTop="16dp"
- android:paddingRight="20dp"
- android:paddingBottom="11dp"
+ android:padding="16dp"
android:text="@string/search_hot"
- android:textColor="@color/black"
- android:textSize="15sp"
+ android:textColor="@color/text_0E0E0E"
+ android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/hot_tag_flex_container" />
diff --git a/app/src/main/res/layout/fragment_sub_catalog.xml b/app/src/main/res/layout/fragment_sub_catalog.xml
new file mode 100644
index 0000000000..bd9d05eb74
--- /dev/null
+++ b/app/src/main/res/layout/fragment_sub_catalog.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_tags.xml b/app/src/main/res/layout/fragment_tags.xml
index fec4630e35..b518d6c427 100644
--- a/app/src/main/res/layout/fragment_tags.xml
+++ b/app/src/main/res/layout/fragment_tags.xml
@@ -8,11 +8,10 @@
android:id="@+id/tags_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:background="@color/all_white"
android:clipToPadding="false"
android:paddingLeft="20dp"
- android:paddingTop="16dp"
+ android:paddingTop="8dp"
android:paddingRight="12dp"
android:paddingBottom="8dp" />
@@ -32,11 +31,18 @@
android:layout_height="wrap_content"
android:visibility="gone" />
+
+
+ android:layout_below="@id/divider">
+
+
@@ -148,11 +150,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
- android:drawableLeft="@drawable/game_horizontal_rating"
+ android:drawableLeft="@{game.commentCount > 3?@drawable/game_horizontal_rating: null}"
android:drawablePadding="4dp"
android:includeFontPadding="false"
- android:paddingRight="8dp"
- android:text="@{game.commentCount > 3?game.star + ``: `评分过少`}"
+ android:paddingRight="@{game.commentCount > 3?DisplayUtils.dip2px(8F): 0}"
+ android:text="@{game.commentCount > 3?(game.star == 10.0? `10` : game.star + ``): ``}"
android:textColor="@{Color.parseColor(game.commentCount > 3?`#1383EB`:`#2496FF`)}"
android:textStyle="bold"
android:visibility="gone" />
diff --git a/app/src/main/res/layout/item_filter_size.xml b/app/src/main/res/layout/item_filter_size.xml
index a65ea1370e..27fbc54b6f 100644
--- a/app/src/main/res/layout/item_filter_size.xml
+++ b/app/src/main/res/layout/item_filter_size.xml
@@ -1,22 +1,34 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_catalog_filter.xml b/app/src/main/res/layout/layout_catalog_filter.xml
new file mode 100644
index 0000000000..ce480c9c02
--- /dev/null
+++ b/app/src/main/res/layout/layout_catalog_filter.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_config_filter.xml b/app/src/main/res/layout/layout_config_filter.xml
index ab6525f8e5..3bf1108a30 100644
--- a/app/src/main/res/layout/layout_config_filter.xml
+++ b/app/src/main/res/layout/layout_config_filter.xml
@@ -4,18 +4,17 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/config_controller"
android:layout_width="match_parent"
- android:layout_height="48dp"
+ android:layout_height="40dp"
android:background="@color/all_white"
android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingBottom="8dp">
+ android:paddingRight="16dp">
diff --git a/app/src/main/res/layout/search_default_hot_item.xml b/app/src/main/res/layout/search_default_hot_item.xml
index 87a4f7cc79..44db71c1ba 100644
--- a/app/src/main/res/layout/search_default_hot_item.xml
+++ b/app/src/main/res/layout/search_default_hot_item.xml
@@ -14,34 +14,36 @@
+ android:paddingLeft="16dp"
+ android:paddingBottom="16dp">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/sub_catalog_item.xml b/app/src/main/res/layout/sub_catalog_item.xml
new file mode 100644
index 0000000000..f353517857
--- /dev/null
+++ b/app/src/main/res/layout/sub_catalog_item.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar_search.xml b/app/src/main/res/layout/toolbar_search.xml
index 05a49a9d6d..e39d75e80d 100644
--- a/app/src/main/res/layout/toolbar_search.xml
+++ b/app/src/main/res/layout/toolbar_search.xml
@@ -2,14 +2,14 @@
+ android:layout_width="44dp"
+ android:layout_height="match_parent">
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index d097824ed9..c679433078 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -214,6 +214,8 @@
#f9f9f9
#FF4147
#a9a9a9
+ #757575
+ #0E0E0E
#99666666
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1d93b248eb..b58affb6fa 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -553,7 +553,7 @@
我的问答
我的草稿
我的积分
- 我的问答
+ 我的论坛
已关注
回答为什么折叠?
继续撰写