feat: 【光环助手V5.15.0】新增 猜你喜欢-发现页(完成UI、接口对接) https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/2065
@ -739,6 +739,10 @@
|
||||
android:name=".BbsCertificationActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".discovery.DiscoveryActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
|
||||
@ -6,13 +6,11 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.CountDownTimer;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
@ -1325,6 +1323,7 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showGameH5DownloadDialog(Context context, GameEntity gameEntity, RegionSetting.GameH5Download gameH5Download) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
@ -1906,13 +1905,21 @@ public class DialogUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
public static void showReportReasonDialog(Context context, ArrayList<String> items, ReportReasonCallBack callBack) {
|
||||
showReportReasonDialog(context, items, "", callBack);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
public static void showReportReasonDialog(Context context, ArrayList<String> items, String title, ReportReasonCallBack callBack) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
DialogReportReasonBinding binding = DialogReportReasonBinding.inflate(LayoutInflater.from(context));
|
||||
|
||||
if (!title.isEmpty()) {
|
||||
binding.reasonTitle.setText(title);
|
||||
}
|
||||
|
||||
ReportReasonAdapter reportReasonAdapter = new ReportReasonAdapter(context, items, reason -> {
|
||||
if (reason.equals("其他原因")) {
|
||||
binding.reasonTitle.setText(R.string.report_reason_other_title);
|
||||
|
||||
@ -35,6 +35,7 @@ import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.discovery.DiscoveryActivity
|
||||
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
@ -95,7 +96,14 @@ object DirectUtils {
|
||||
* 跳转到特定页面,根据 [type] 决定跳转页面,[path] 为跳转前的页面名称
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToSpecificPage(context: Context, type: String, link: String, text: String? = "", entrance: String? = null, path: String? = null) {
|
||||
fun directToSpecificPage(
|
||||
context: Context,
|
||||
type: String,
|
||||
link: String,
|
||||
text: String? = "",
|
||||
entrance: String? = null,
|
||||
path: String? = null
|
||||
) {
|
||||
when (type) {
|
||||
HOST_ARTICLE -> directToArticle(context, id = link, entrance = entrance)
|
||||
|
||||
@ -111,9 +119,19 @@ object DirectUtils {
|
||||
|
||||
HOST_WEB -> directToWebView(context, url = link, entrance = entrance)
|
||||
|
||||
HOST_DOWNLOAD -> directToDownloadManagerAndStartDownload(context, gameId = link, packageName = text, entrance = entrance)
|
||||
HOST_DOWNLOAD -> directToDownloadManagerAndStartDownload(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_UPDATE -> directToDownloadManagerAndStartUpdate(context, gameId = link, packageName = text, entrance = entrance)
|
||||
HOST_UPDATE -> directToDownloadManagerAndStartUpdate(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_LIBAO -> directToGiftDetail(context, giftId = link, entrance = entrance)
|
||||
|
||||
@ -126,7 +144,13 @@ object DirectUtils {
|
||||
directToLinkPage(context, linkEntity, entrance, path, null)
|
||||
}
|
||||
|
||||
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String, exposureEvent: ExposureEvent? = null) {
|
||||
fun directToLinkPage(
|
||||
context: Context,
|
||||
linkEntity: LinkEntity,
|
||||
entrance: String,
|
||||
path: String,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
directToLinkPage(context, linkEntity, entrance, path, exposureEvent, null)
|
||||
}
|
||||
|
||||
@ -209,9 +233,21 @@ object DirectUtils {
|
||||
directToCommunity(context, CommunityEntity(linkEntity.link!!, linkEntity.text!!))
|
||||
}
|
||||
|
||||
"community_article", "社区文章" -> directToCommunityArticle(context, linkEntity.community!!, linkEntity.link!!, entrance, path)
|
||||
"community_article", "社区文章" -> directToCommunityArticle(
|
||||
context,
|
||||
linkEntity.community!!,
|
||||
linkEntity.link!!,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
|
||||
"community_column", "社区专题" -> directToCommunityColumn(context, linkEntity.community, linkEntity.link!!, entrance, path)
|
||||
"community_column", "社区专题" -> directToCommunityColumn(
|
||||
context,
|
||||
linkEntity.community,
|
||||
linkEntity.link!!,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
|
||||
"community_special_column" -> directAskColumnDetail(
|
||||
context, linkEntity.link
|
||||
@ -223,7 +259,11 @@ object DirectUtils {
|
||||
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
|
||||
directDouyin(context, "1402577827140941")
|
||||
}
|
||||
else -> directToWebView(context, url = linkEntity.link!!, entrance = BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
else -> directToWebView(
|
||||
context,
|
||||
url = linkEntity.link!!,
|
||||
entrance = BaseActivity.mergeEntranceAndPath(entrance, path)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +273,16 @@ object DirectUtils {
|
||||
|
||||
"qqqun", "QQ群" -> directToQqGroup(context, linkEntity.link!!)
|
||||
|
||||
"tag" -> context.startActivity(TagsActivity.getIntent(context, linkEntity.text!!, linkEntity.title, entrance, path, exposureEvent?.source))
|
||||
"tag" -> context.startActivity(
|
||||
TagsActivity.getIntent(
|
||||
context,
|
||||
linkEntity.text!!,
|
||||
linkEntity.title,
|
||||
entrance,
|
||||
path,
|
||||
exposureEvent?.source
|
||||
)
|
||||
)
|
||||
|
||||
"all_community_article" -> directSimpleArticleList(
|
||||
context, linkEntity.link
|
||||
@ -244,7 +293,14 @@ object DirectUtils {
|
||||
|
||||
"catalog" -> directCatalog(context, linkEntity.link!!, linkEntity.text!!, entrance, path)
|
||||
|
||||
"category_v2" -> directCategoryV2(context, linkEntity.link!!, linkEntity.text!!, entrance, path, exposureEvent)
|
||||
"category_v2" -> directCategoryV2(
|
||||
context,
|
||||
linkEntity.link!!,
|
||||
linkEntity.text!!,
|
||||
entrance,
|
||||
path,
|
||||
exposureEvent
|
||||
)
|
||||
|
||||
"block", "版块" -> {
|
||||
if (linkEntity.link.isNullOrEmpty()) return
|
||||
@ -365,7 +421,13 @@ object DirectUtils {
|
||||
|
||||
"halo_tab" -> directToPersonalTab(context)
|
||||
|
||||
"common_collection" -> directToCommonCollectionDetail(context, linkEntity.link ?: "", linkEntity.blockId, linkEntity.blockName, entrance)
|
||||
"common_collection" -> directToCommonCollectionDetail(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
linkEntity.blockId,
|
||||
linkEntity.blockName,
|
||||
entrance
|
||||
)
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
@ -373,6 +435,8 @@ object DirectUtils {
|
||||
|
||||
"game_list_detail" -> directToGameCollectionDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
"explore_column" -> context.startActivity(DiscoveryActivity.getIntent(context, entrance))
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -416,7 +480,13 @@ object DirectUtils {
|
||||
* 跳转至专题合集
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String, columnName: String = "") {
|
||||
fun directToColumnCollection(
|
||||
context: Context,
|
||||
id: String,
|
||||
position: Int = -1,
|
||||
entrance: String,
|
||||
columnName: String = ""
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, ColumnCollectionDetailActivity::class.java.name)
|
||||
@ -594,7 +664,12 @@ object DirectUtils {
|
||||
* 跳转到游戏评分详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameRatingDetail(context: Context, gameId: String? = "", commentId: String? = "", entrance: String? = null) {
|
||||
fun directToGameRatingDetail(
|
||||
context: Context,
|
||||
gameId: String? = "",
|
||||
commentId: String? = "",
|
||||
entrance: String? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_GAMEID, gameId)
|
||||
@ -618,7 +693,12 @@ object DirectUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToGameDetail(context: Context, id: String, defaultTab: Int = GameDetailFragment.INDEX_DESC, entrance: String? = null) {
|
||||
fun directToGameDetail(
|
||||
context: Context,
|
||||
id: String,
|
||||
defaultTab: Int = GameDetailFragment.INDEX_DESC,
|
||||
entrance: String? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
@ -634,14 +714,23 @@ object DirectUtils {
|
||||
|
||||
// 专栏
|
||||
@JvmStatic
|
||||
fun directToSubject(context: Context, id: String, subjectName: String? = "", entrance: String? = null, exposureEvent: ExposureEvent? = null) {
|
||||
fun directToSubject(
|
||||
context: Context,
|
||||
id: String,
|
||||
subjectName: String? = "",
|
||||
entrance: String? = null,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
|
||||
bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData)
|
||||
if (exposureEvent != null) bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
|
||||
if (exposureEvent != null) bundle.putParcelableArrayList(
|
||||
KEY_EXPOSURE_SOURCE_LIST,
|
||||
ArrayList(exposureEvent.source)
|
||||
)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -693,7 +782,12 @@ object DirectUtils {
|
||||
* 跳转到下载管理器并开始下载 [gameId] 和 [packageName] 用于唯一确定一个下载文件
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToDownloadManagerAndStartDownload(context: Context, gameId: String? = "", packageName: String? = "", entrance: String? = null) {
|
||||
fun directToDownloadManagerAndStartDownload(
|
||||
context: Context,
|
||||
gameId: String? = "",
|
||||
packageName: String? = "",
|
||||
entrance: String? = null
|
||||
) {
|
||||
DownloadHelper.createABrandNewDownloadTaskQuietly(gameId, packageName) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
@ -706,7 +800,12 @@ object DirectUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToDownloadManagerAndStartUpdate(context: Context, gameId: String? = "", packageName: String? = "", entrance: String? = null) {
|
||||
fun directToDownloadManagerAndStartUpdate(
|
||||
context: Context,
|
||||
gameId: String? = "",
|
||||
packageName: String? = "",
|
||||
entrance: String? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, DownloadManagerActivity.TAG)
|
||||
@ -892,7 +991,13 @@ object DirectUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToCommunityArticle(context: Context, articleId: String?, communityId: String?, entrance: String?, path: String?) {
|
||||
fun directToCommunityArticle(
|
||||
context: Context,
|
||||
articleId: String?,
|
||||
communityId: String?,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
@ -903,7 +1008,13 @@ object DirectUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToCommunityArticle(context: Context, community: CommunityEntity?, articleId: String?, entrance: String?, path: String?) {
|
||||
fun directToCommunityArticle(
|
||||
context: Context,
|
||||
community: CommunityEntity?,
|
||||
articleId: String?,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
if (articleId.isNullOrEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
@ -918,7 +1029,13 @@ object DirectUtils {
|
||||
* 跳转到社区专题
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToCommunityColumn(context: Context, community: CommunityEntity?, subjectId: String, entrance: String?, path: String?) {
|
||||
fun directToCommunityColumn(
|
||||
context: Context,
|
||||
community: CommunityEntity?,
|
||||
subjectId: String,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
if (subjectId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_PATH, path)
|
||||
@ -1008,7 +1125,12 @@ object DirectUtils {
|
||||
* @param fixedTopAmwayCommentId 需要置顶的安利Id
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToAmway(context: Context, fixedTopAmwayCommentId: String? = null, entrance: String? = null, path: String? = "") {
|
||||
fun directToAmway(
|
||||
context: Context,
|
||||
fixedTopAmwayCommentId: String? = null,
|
||||
entrance: String? = null,
|
||||
path: String? = ""
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, AmwayActivity::class.java.name)
|
||||
@ -1149,7 +1271,13 @@ object DirectUtils {
|
||||
* 跳转分类
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directCategoryDirectory(context: Context, categoryId: String, categoryTitle: String, entrance: String? = null, path: String? = "") {
|
||||
fun directCategoryDirectory(
|
||||
context: Context,
|
||||
categoryId: String,
|
||||
categoryTitle: String,
|
||||
entrance: String? = null,
|
||||
path: String? = ""
|
||||
) {
|
||||
if (categoryId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, CategoryDirectoryActivity::class.java.name)
|
||||
@ -1198,7 +1326,10 @@ object DirectUtils {
|
||||
bundle.putString(KEY_CATEGORY_ID, categoryId)
|
||||
bundle.putString(KEY_CATEGORY_TITLE, categoryTitle)
|
||||
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
if (exposureEvent != null) bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
|
||||
if (exposureEvent != null) bundle.putParcelableArrayList(
|
||||
KEY_EXPOSURE_SOURCE_LIST,
|
||||
ArrayList(exposureEvent.source)
|
||||
)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1206,7 +1337,13 @@ object DirectUtils {
|
||||
* 跳转到问题标签详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directAskColumnLabelDetail(context: Context, tag: String, community: CommunityEntity, entrance: String? = null, path: String? = "") {
|
||||
fun directAskColumnLabelDetail(
|
||||
context: Context,
|
||||
tag: String,
|
||||
community: CommunityEntity,
|
||||
entrance: String? = null,
|
||||
path: String? = ""
|
||||
) {
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString(KEY_TO, AskColumnDetailActivity::class.java.name)
|
||||
// bundle.putString(KEY_ASK_TAG, tag)
|
||||
@ -1220,7 +1357,13 @@ object DirectUtils {
|
||||
* 跳转到专栏详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directAskColumnDetail(context: Context, columnId: String, community: CommunityEntity, entrance: String? = null, path: String? = "") {
|
||||
fun directAskColumnDetail(
|
||||
context: Context,
|
||||
columnId: String,
|
||||
community: CommunityEntity,
|
||||
entrance: String? = null,
|
||||
path: String? = ""
|
||||
) {
|
||||
// if (columnId.isEmpty()) return
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString(KEY_TO, AskColumnDetailActivity::class.java.name)
|
||||
@ -1430,7 +1573,13 @@ object DirectUtils {
|
||||
Constants.COMMODITY_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&shopid=%s×tamp=%d", url, commodityId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
url = String.format(
|
||||
Locale.CHINA,
|
||||
"%s&shopid=%s×tamp=%d",
|
||||
url,
|
||||
commodityId,
|
||||
(Date().time / 1000 / 1000.toFloat()).roundToInt()
|
||||
)
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
@ -1450,7 +1599,13 @@ object DirectUtils {
|
||||
Constants.ENERGY_RECORD_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&position=%s×tamp=%d", url, position, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
url = String.format(
|
||||
Locale.CHINA,
|
||||
"%s&position=%s×tamp=%d",
|
||||
url,
|
||||
position,
|
||||
(Date().time / 1000 / 1000.toFloat()).roundToInt()
|
||||
)
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
@ -1478,7 +1633,13 @@ object DirectUtils {
|
||||
Constants.ORDER_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&order_id=%s×tamp=%d", url, orderId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
url = String.format(
|
||||
Locale.CHINA,
|
||||
"%s&order_id=%s×tamp=%d",
|
||||
url,
|
||||
orderId,
|
||||
(Date().time / 1000 / 1000.toFloat()).roundToInt()
|
||||
)
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package com.gh.gamecenter.discovery
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
|
||||
/**
|
||||
* 猜你喜欢-发现页
|
||||
*/
|
||||
class DiscoveryActivity : ToolBarActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
updateStatusBarColor(R.color.background_white, R.color.background_white)
|
||||
setNavigationTitle("发现")
|
||||
}
|
||||
|
||||
override fun isAutoResetViewBackgroundEnabled(): Boolean = true
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
updateStatusBarColor(R.color.background_white, R.color.background_white)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, entrance: String): Intent {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
return getTargetIntent(context, DiscoveryActivity::class.java, DiscoveryFragment::class.java, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,262 @@
|
||||
package com.gh.gamecenter.discovery
|
||||
|
||||
import android.content.Context
|
||||
import android.util.SparseArray
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.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.DialogUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.baselist.ListAdapter
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.ItemViewType
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.ifLogin
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.viewholder.FooterViewHolder
|
||||
import com.gh.gamecenter.core.utils.StringUtils
|
||||
import com.gh.gamecenter.databinding.ItemRecommendInterestBinding
|
||||
import com.gh.gamecenter.databinding.ItemRecommendInterestFooterBinding
|
||||
import com.gh.gamecenter.databinding.ItemRecommendInterestImageBinding
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.game.GameItemViewHolder
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class DiscoveryAdapter(
|
||||
context: Context,
|
||||
val mViewModel: DiscoveryViewModel,
|
||||
val entrance: String
|
||||
) : ListAdapter<DiscoveryItemData>(context), IExposable {
|
||||
|
||||
private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
when (position) {
|
||||
itemCount - 2 -> {
|
||||
return ITEM_DIRECT_GAME_BLOCK
|
||||
}
|
||||
itemCount - 1 -> {
|
||||
return ItemViewType.ITEM_FOOTER
|
||||
}
|
||||
else -> {
|
||||
val itemData = mEntityList[position]
|
||||
return when {
|
||||
itemData.interestCardLabels != null -> {
|
||||
ITEM_RECOMMEND_INTEREST
|
||||
}
|
||||
itemData.interestImageCardLabel != null -> {
|
||||
ITEM_RECOMMEND_INTEREST_IMAGE
|
||||
}
|
||||
else -> {
|
||||
ItemViewType.GAME_NORMAL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(oldItem: DiscoveryItemData?, newItem: DiscoveryItemData?): Boolean {
|
||||
return oldItem?.gameEntity?.id == newItem?.gameEntity?.id
|
||||
|| oldItem?.interestCardLabels?.firstOrNull()?.id == newItem?.interestCardLabels?.firstOrNull()?.id
|
||||
|| oldItem?.interestImageCardLabel?.id == newItem?.interestImageCardLabel?.id
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return when (viewType) {
|
||||
ItemViewType.GAME_NORMAL -> {
|
||||
GameItemViewHolder(parent.toBinding())
|
||||
}
|
||||
ItemViewType.ITEM_FOOTER -> {
|
||||
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
|
||||
}
|
||||
ITEM_DIRECT_GAME_BLOCK -> {
|
||||
DirectGameBlockViewHolder(parent.toBinding())
|
||||
}
|
||||
ITEM_RECOMMEND_INTEREST -> {
|
||||
RecommendInterestViewHolder(parent.toBinding())
|
||||
}
|
||||
ITEM_RECOMMEND_INTEREST_IMAGE -> {
|
||||
RecommendInterestImageViewHolder(parent.toBinding())
|
||||
}
|
||||
else -> {
|
||||
throw NullPointerException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is GameItemViewHolder -> {
|
||||
val itemData = mEntityList[position]
|
||||
val gameEntity = itemData.gameEntity!!
|
||||
holder.bindGameItem(gameEntity)
|
||||
|
||||
val exposureSources = ArrayList<ExposureSource>()
|
||||
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
|
||||
mExposureEventSparseArray.put(position, event)
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
GameDetailActivity.startGameDetailActivity(
|
||||
mContext,
|
||||
gameEntity,
|
||||
StringUtils.buildString("(${entrance}", "-列表[", (position).toString(), "])"),
|
||||
traceEvent = event
|
||||
)
|
||||
}
|
||||
holder.itemView.setOnLongClickListener {
|
||||
discoveryFeedback(position, gameEntity)
|
||||
true
|
||||
}
|
||||
DownloadItemUtils.setOnClickListener(
|
||||
mContext,
|
||||
holder.binding.downloadBtn,
|
||||
gameEntity,
|
||||
position,
|
||||
this,
|
||||
StringUtils.buildString("(${entrance}", "-列表[", (position).toString(), "])"),
|
||||
StringUtils.buildString(entrance, ":", gameEntity.name),
|
||||
event
|
||||
)
|
||||
|
||||
DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true)
|
||||
holder.itemView.setPadding(16f.dip2px(), 8f.dip2px(), 16f.dip2px(), 8f.dip2px())
|
||||
}
|
||||
is RecommendInterestViewHolder -> {
|
||||
val labels = mEntityList[position].interestCardLabels ?: return
|
||||
holder.binding.labelTv1.goneIf(labels.size < 1) {
|
||||
holder.binding.labelTv1.text = labels[0].title
|
||||
holder.binding.labelTv1.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(holder.binding.root.context, labels[0], entrance, "")
|
||||
}
|
||||
}
|
||||
holder.binding.labelTv2.goneIf(labels.size < 2) {
|
||||
holder.binding.labelTv2.text = labels[1].title
|
||||
holder.binding.labelTv2.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(holder.binding.root.context, labels[1], entrance, "")
|
||||
}
|
||||
}
|
||||
holder.binding.labelTv3.goneIf(labels.size < 3) {
|
||||
holder.binding.labelTv3.text = labels[2].title
|
||||
holder.binding.labelTv3.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(holder.binding.root.context, labels[2], entrance, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
is RecommendInterestImageViewHolder -> {
|
||||
val label = mEntityList[position].interestImageCardLabel ?: return
|
||||
holder.binding.root.setOnClickListener {
|
||||
DirectUtils.directToLinkPage(holder.binding.root.context, label, entrance, "")
|
||||
}
|
||||
}
|
||||
is DirectGameBlockViewHolder -> {
|
||||
holder.binding.root.setOnClickListener {
|
||||
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_GAME))
|
||||
}
|
||||
}
|
||||
|
||||
is FooterViewHolder -> {
|
||||
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 2
|
||||
}
|
||||
|
||||
private fun discoveryFeedback(position: Int, gameEntity: GameEntity) {
|
||||
mContext.ifLogin(entrance) {
|
||||
DialogUtils.showReportReasonDialog(
|
||||
mContext,
|
||||
Constants.FEEDBACK_REASON_LIST.toList() as ArrayList<String>,
|
||||
"不喜欢的原因"
|
||||
) { reason, desc ->
|
||||
mViewModel.discoveryFeedback(gameEntity.id, reason, gameEntity.type ?: "") {
|
||||
mEntityList.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyItemByDownload(download: DownloadEntity) {
|
||||
val positionAndPackageMap = mViewModel.positionAndPackageMap
|
||||
for (key in positionAndPackageMap.keys) {
|
||||
if (key.contains(download.packageName)) {
|
||||
val position = positionAndPackageMap[key]
|
||||
if (position != null && mEntityList != null && position < mEntityList.size) {
|
||||
mEntityList[position].gameEntity?.let {
|
||||
it.getEntryMap()[download.platform] = download
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
|
||||
val positionAndPackageMap = mViewModel.positionAndPackageMap
|
||||
for (key in positionAndPackageMap.keys) {
|
||||
if (key.contains(status.packageName)) {
|
||||
val position = positionAndPackageMap[key]
|
||||
if (position != null && mEntityList != null && position < mEntityList.size) {
|
||||
mEntityList[position].gameEntity?.let {
|
||||
it.getEntryMap().remove(status.platform)
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clearPositionAndPackageMap() {
|
||||
mViewModel.positionAndPackageMap.clear()
|
||||
}
|
||||
|
||||
override fun getEventByPosition(pos: Int): ExposureEvent? {
|
||||
return mExposureEventSparseArray.get(pos)
|
||||
}
|
||||
|
||||
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
class RecommendInterestViewHolder(val binding: ItemRecommendInterestBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
}
|
||||
|
||||
class RecommendInterestImageViewHolder(val binding: ItemRecommendInterestImageBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
}
|
||||
|
||||
class DirectGameBlockViewHolder(val binding: ItemRecommendInterestFooterBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITEM_RECOMMEND_INTEREST = 200
|
||||
const val ITEM_RECOMMEND_INTEREST_IMAGE = 201
|
||||
const val ITEM_DIRECT_GAME_BLOCK = 202
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
package com.gh.gamecenter.discovery
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.ethanhua.skeleton.Skeleton
|
||||
import com.gh.common.util.DialogUtils
|
||||
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.common.baselist.LazyListFragment
|
||||
import com.gh.gamecenter.common.baselist.ListAdapter
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.getBitmapFromView
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.databinding.LayoutDiscoveryGuideBinding
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class DiscoveryFragment : LazyListFragment<DiscoveryItemData, DiscoveryViewModel>() {
|
||||
|
||||
private var mAdapter: DiscoveryAdapter? = null
|
||||
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
mAdapter?.notifyItemByDownload(downloadEntity)
|
||||
if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
|
||||
showUnzipFailureDialog(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDataInit(downloadEntity: DownloadEntity) {
|
||||
mAdapter?.notifyItemByDownload(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initRealView() {
|
||||
super.initRealView()
|
||||
mSkeletonScreen = Skeleton.bind(mSkeletonScreenView)
|
||||
.shimmer(true)
|
||||
.angle(Constants.SHIMMER_ANGLE)
|
||||
.color(R.color.skeleton_shimmer_color)
|
||||
.duration(Constants.SHIMMER_DURATION)
|
||||
.maskWidth(Constants.MASK_WIDTH)
|
||||
.gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
|
||||
.apply {
|
||||
load(R.layout.fragment_discovery_skeleton)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
|
||||
override fun provideListAdapter(): ListAdapter<*> {
|
||||
return mAdapter ?: DiscoveryAdapter(requireContext(), mListViewModel,"发现页").also { mAdapter = it }
|
||||
}
|
||||
|
||||
override fun onFragmentResume() {
|
||||
super.onFragmentResume()
|
||||
DownloadManager.getInstance().addObserver(dataWatcher)
|
||||
}
|
||||
|
||||
override fun onFragmentPause() {
|
||||
super.onFragmentPause()
|
||||
DownloadManager.getInstance().removeObserver(dataWatcher)
|
||||
}
|
||||
|
||||
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
|
||||
|
||||
private fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
|
||||
val data = mListViewModel.positionAndPackageMap
|
||||
for (gameAndPosition in data) {
|
||||
if (gameAndPosition.key.contains(downloadEntity.packageName)) {
|
||||
val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
|
||||
if (targetView != null) {
|
||||
DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChanged(ts: MutableList<DiscoveryItemData>?) {
|
||||
super.onChanged(ts)
|
||||
val isFirstGuide = SPUtils.getBoolean(Constants.SP_DISCOVERY_GUIDE, true)
|
||||
if (!isFirstGuide) return
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
showGuideView()
|
||||
SPUtils.setBoolean(Constants.SP_DISCOVERY_GUIDE, false)
|
||||
}, 800)
|
||||
}
|
||||
|
||||
private fun showGuideView() {
|
||||
if (!isSupportVisible) return
|
||||
val firstView = mListRv.layoutManager?.findViewByPosition(0)
|
||||
if (firstView != null && requireActivity() is AppCompatActivity) {
|
||||
val location = IntArray(2)
|
||||
firstView.getLocationInWindow(location)
|
||||
val decorView = requireActivity().window.decorView as? FrameLayout
|
||||
val guideViewBinding =
|
||||
LayoutDiscoveryGuideBinding.inflate(LayoutInflater.from(requireContext()), decorView, true)
|
||||
val originalBackground = firstView.background
|
||||
firstView.setBackgroundColor(
|
||||
if (mIsDarkModeOn) R.color.black.toColor(requireContext()) else R.color.white.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
guideViewBinding.guideImageContainer.setCardBackgroundColor(
|
||||
if (mIsDarkModeOn) R.color.black.toColor(requireContext()) else R.color.white.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
val snapshotBitmap = firstView.getBitmapFromView(
|
||||
firstView.width - 16f.dip2px(),
|
||||
firstView.height,
|
||||
-8f.dip2px().toFloat(),
|
||||
0f
|
||||
)
|
||||
firstView.background = originalBackground
|
||||
guideViewBinding.guideImage.setImageBitmap(snapshotBitmap)
|
||||
(guideViewBinding.guideImageContainer.layoutParams as RelativeLayout.LayoutParams).run {
|
||||
topMargin = location[1]
|
||||
guideViewBinding.guideImageContainer.layoutParams = this
|
||||
}
|
||||
guideViewBinding.root.setOnClickListener {
|
||||
decorView?.removeView(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAutomaticLoad(): Boolean = false
|
||||
|
||||
// 下载被删除事件
|
||||
@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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.gh.gamecenter.discovery
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
|
||||
@Keep
|
||||
data class DiscoveryItemData(
|
||||
val gameEntity: GameEntity? = null,
|
||||
val interestCardLabels: ArrayList<DiscoveryGameCardLabel>? = null,
|
||||
val interestImageCardLabel: DiscoveryGameCardLabel? = null
|
||||
)
|
||||
@ -0,0 +1,159 @@
|
||||
package com.gh.gamecenter.discovery
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.common.baselist.ListViewModel
|
||||
import com.gh.gamecenter.common.baselist.LoadStatus
|
||||
import com.gh.gamecenter.common.baselist.LoadType
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.EnvHelper
|
||||
import com.gh.gamecenter.common.utils.observableToMain
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.utils.toRequestBody
|
||||
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.TagEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.Observable
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class DiscoveryViewModel(application: Application) : ListViewModel<GameEntity, DiscoveryItemData>(application) {
|
||||
|
||||
val positionAndPackageMap = HashMap<String, Int>()
|
||||
private val mApi = RetrofitManager.getInstance().api
|
||||
private var mGameTags: ArrayList<LinkEntity>? = null
|
||||
private var mDiscoveryGameCardLabels: ArrayList<DiscoveryGameCardLabel>? = null
|
||||
private var mDiscoveryGameCardLabelMap: LinkedHashMap<String, ArrayList<DiscoveryGameCardLabel>> = linkedMapOf()
|
||||
|
||||
init {
|
||||
getCardLabels()
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) {
|
||||
val itemDataList = arrayListOf<DiscoveryItemData>()
|
||||
it.forEachIndexed { index, gameEntity ->
|
||||
itemDataList.add(DiscoveryItemData(gameEntity))
|
||||
addGamePositionAndPackage(index, gameEntity)
|
||||
//第6、12、18、24个游戏后面固定插入兴趣推荐卡片
|
||||
when (index) {
|
||||
5 -> {
|
||||
itemDataList.add(DiscoveryItemData(interestCardLabels = mDiscoveryGameCardLabelMap["卡片一"]))
|
||||
}
|
||||
11 -> {
|
||||
itemDataList.add(
|
||||
DiscoveryItemData(
|
||||
interestImageCardLabel = mDiscoveryGameCardLabelMap["卡片二"]?.get(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
17 -> {
|
||||
itemDataList.add(DiscoveryItemData(interestCardLabels = mDiscoveryGameCardLabelMap["卡片三"]))
|
||||
}
|
||||
23 -> {
|
||||
itemDataList.add(DiscoveryItemData(interestCardLabels = mDiscoveryGameCardLabelMap["卡片四"]))
|
||||
}
|
||||
else -> {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
mResultLiveData.postValue(itemDataList)
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<MutableList<GameEntity>>? {
|
||||
return mApi.getDiscoveryGames(page).map {
|
||||
if (page == 1) {
|
||||
mGameTags = it.gameTags
|
||||
groupingDiscoveryLabel()
|
||||
}
|
||||
it.games
|
||||
}
|
||||
}
|
||||
|
||||
//按照card字段分组
|
||||
private fun groupingDiscoveryLabel() {
|
||||
mDiscoveryGameCardLabelMap.clear()
|
||||
var tagIndex = 0
|
||||
mDiscoveryGameCardLabels?.forEach {
|
||||
if (mDiscoveryGameCardLabelMap.contains(it.card)) {
|
||||
mDiscoveryGameCardLabelMap[it.card]?.add(it)
|
||||
} else {
|
||||
mDiscoveryGameCardLabelMap[it.card] = arrayListOf(it)
|
||||
}
|
||||
}
|
||||
//如果it.link为空需要在mGameTags中依次获取
|
||||
mDiscoveryGameCardLabelMap.keys.forEach {
|
||||
val labels = mDiscoveryGameCardLabelMap[it]
|
||||
labels?.forEach { label ->
|
||||
if (!mGameTags.isNullOrEmpty() && mGameTags!!.size > tagIndex && label.link.isNullOrEmpty()) {
|
||||
val gameTag = mGameTags!![tagIndex]
|
||||
label.link = gameTag.link
|
||||
label.type = gameTag.type
|
||||
label.text = gameTag.linkText
|
||||
label.title = gameTag.linkText
|
||||
tagIndex++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCardLabels() {
|
||||
mApi.cardLabels
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<ArrayList<DiscoveryGameCardLabel>>() {
|
||||
override fun onResponse(response: ArrayList<DiscoveryGameCardLabel>?) {
|
||||
super.onResponse(response)
|
||||
mDiscoveryGameCardLabels = response
|
||||
initLoadParams()
|
||||
loadData()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
super.onFailure(e)
|
||||
mLoadStatusLiveData.value = LoadStatus.INIT_FAILED
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun discoveryFeedback(gameId: String, reason: String, type: String, callback: () -> Unit) {
|
||||
val paramsMap = mapOf(
|
||||
"reason" to reason,
|
||||
"type" to type
|
||||
)
|
||||
mApi.discorveryFeedback(gameId, paramsMap.toRequestBody())
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun addGamePositionAndPackage(position: Int, game: GameEntity) {
|
||||
var packages = ""
|
||||
for (apkEntity in game.getApk()) {
|
||||
packages += apkEntity.packageName
|
||||
}
|
||||
positionAndPackageMap[packages + (position)] = position
|
||||
game.gameLocation = GameEntity.GameLocation.INDEX
|
||||
game.setEntryMap(DownloadManager.getInstance().getEntryMap(game.name))
|
||||
}
|
||||
|
||||
override fun load(loadType: LoadType?) {
|
||||
if (loadType == LoadType.REFRESH) {
|
||||
getCardLabels()
|
||||
} else {
|
||||
super.load(loadType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class DiscoveryGameCardEntity(
|
||||
val more: Int,
|
||||
@SerializedName("game_tags")
|
||||
val gameTags: ArrayList<LinkEntity> = arrayListOf(),
|
||||
@SerializedName("data")
|
||||
val games: ArrayList<GameEntity> = arrayListOf()
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class DiscoveryGameCardLabel(
|
||||
@SerializedName("_id")
|
||||
val id: String = "",
|
||||
val card: String = "",
|
||||
val order: Int = 0,
|
||||
) : LinkEntity()
|
||||
@ -291,6 +291,9 @@ data class GameEntity(
|
||||
var welcomeDialogId: String? = null,
|
||||
var welcomeDialogTitle: String? = null,
|
||||
|
||||
@SerializedName("column_rank")
|
||||
var columnRank: ColumnRank? = null,//榜单详情
|
||||
|
||||
// 专题id,用于曝光使用
|
||||
var subjectId: String? = null,
|
||||
// 专题名字,用于曝光使用
|
||||
@ -836,6 +839,12 @@ data class GameEntity(
|
||||
var url: String = ""
|
||||
) : Parcelable
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class ColumnRank(
|
||||
val name: String = "",
|
||||
val position: Int = 0
|
||||
) : Parcelable
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
|
||||
@ -25,6 +25,7 @@ import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.FragmentMainHomeWrapperBinding
|
||||
import com.gh.gamecenter.databinding.TabItemMainBinding
|
||||
import com.gh.gamecenter.discovery.DiscoveryFragment
|
||||
import com.gh.gamecenter.entity.SubjectData
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.game.GameFragment
|
||||
@ -207,7 +208,10 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
|
||||
if (isContentStyleChanged) {
|
||||
updateIndicatorDrawable()
|
||||
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDisplayingLightContent && !mIsDarkModeOn)
|
||||
DisplayUtils.setLightStatusBar(
|
||||
requireActivity(),
|
||||
!mIsDisplayingLightContent && !mIsDarkModeOn
|
||||
)
|
||||
}
|
||||
|
||||
mTabTitleList[position].run {
|
||||
@ -277,10 +281,12 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
tab.customView = tabViewBinding.root
|
||||
tab.view.setPadding(0, 0, 0, 0)
|
||||
if (i == 0) {
|
||||
tab.view.layoutParams = (tab.view.layoutParams as LinearLayout.LayoutParams).apply { setMargins(10F.dip2px(), 0, 0, 0) }
|
||||
tab.view.layoutParams =
|
||||
(tab.view.layoutParams as LinearLayout.LayoutParams).apply { setMargins(10F.dip2px(), 0, 0, 0) }
|
||||
}
|
||||
if (i == mBinding?.tabLayout?.tabCount!! - 1) {
|
||||
tab.view.layoutParams = (tab.view.layoutParams as LinearLayout.LayoutParams).apply { setMargins(0, 0, 10F.dip2px(), 0) }
|
||||
tab.view.layoutParams =
|
||||
(tab.view.layoutParams as LinearLayout.LayoutParams).apply { setMargins(0, 0, 10F.dip2px(), 0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -307,7 +313,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
|
||||
currentTab?.offsetRatio = offset / totalHeight.toFloat()
|
||||
if ((currentTab?.isTopViewShow == true && offset >= totalHeight)
|
||||
|| currentTab?.isSlideEmpty == true) {
|
||||
|| currentTab?.isSlideEmpty == true
|
||||
) {
|
||||
currentTab.isTopViewShow = false
|
||||
currentTab.primaryColor = backgroundWhiteColor
|
||||
currentTab.useLightStyle = false
|
||||
@ -374,7 +381,11 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
currentTab.currentSelectColor = color
|
||||
if (currentTab.isTopViewShow) {
|
||||
val colorInBetween =
|
||||
ColorUtils.blendARGB(color, R.color.background_white.toColor(requireContext()), currentTab.offsetRatio)
|
||||
ColorUtils.blendARGB(
|
||||
color,
|
||||
R.color.background_white.toColor(requireContext()),
|
||||
currentTab.offsetRatio
|
||||
)
|
||||
currentTab.primaryColor = colorInBetween
|
||||
updateAppBarStyle(colorInBetween, colorInBetween != R.color.background_white.toColor(requireContext()))
|
||||
}
|
||||
@ -476,6 +487,9 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
putString(EntranceConsts.KEY_COLLECTION_ID, tab.link)
|
||||
putString(EntranceConsts.KEY_COLUMNNAME, tab.text)
|
||||
})
|
||||
"explore_column" -> DiscoveryFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页")
|
||||
})
|
||||
"bbs" -> Fragment()
|
||||
else -> Fragment()
|
||||
}
|
||||
|
||||
@ -2987,4 +2987,22 @@ public interface ApiService {
|
||||
*/
|
||||
@POST("mobile_auth/{user_id}:unbind")
|
||||
Single<ResponseBody> unBindPhone();
|
||||
|
||||
/**
|
||||
* 获取发现页游戏列表
|
||||
*/
|
||||
@GET("home/explore/games")
|
||||
Observable<DiscoveryGameCardEntity> getDiscoveryGames(@Query("page") int page);
|
||||
|
||||
/**
|
||||
* 获取发现页卡片列表
|
||||
*/
|
||||
@GET("home/explore/cards")
|
||||
Observable<ArrayList<DiscoveryGameCardLabel>> getCardLabels();
|
||||
|
||||
/**
|
||||
* 反馈游戏
|
||||
*/
|
||||
@POST("home/explore/games/{game_id}/feedback")
|
||||
Single<ResponseBody> discorveryFeedback(@Path("game_id") String gameId, @Body RequestBody body);
|
||||
}
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 32 KiB |
BIN
app/src/main/res/drawable-night-xxxhdpi/ic_discovery_guide.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
app/src/main/res/drawable-night-xxxhdpi/ic_interest_arrow.png
Normal file
|
After Width: | Height: | Size: 307 B |
BIN
app/src/main/res/drawable-xxxhdpi/bg_recommend_interest.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 33 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_discovery_guide.webp
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_interest.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_interest_arrow.png
Normal file
|
After Width: | Height: | Size: 331 B |
8
app/src/main/res/drawable/bg_shape_white_radius_4.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
<solid android:color="@color/background_white" />
|
||||
|
||||
</shape>
|
||||
32
app/src/main/res/layout/fragment_discovery_skeleton.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_height="88dp"
|
||||
android:background="@drawable/bg_skeleton_radius_8">
|
||||
<View
|
||||
android:layout_width="112dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_margin="12dp"
|
||||
android:background="@drawable/bg_skeleton_child_radius_4" />
|
||||
</RelativeLayout>
|
||||
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
<include layout="@layout/item_skeleton_discovery_list" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
100
app/src/main/res/layout/item_recommend_interest.xml
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_white">
|
||||
|
||||
<View
|
||||
android:id="@+id/backgroundView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="88dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="@drawable/bg_shape_space_radius_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/interestTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:drawableLeft="@drawable/ic_interest"
|
||||
android:drawablePadding="4dp"
|
||||
android:includeFontPadding="false"
|
||||
android:text="猜你感兴趣的内容"
|
||||
android:textColor="@color/text_title"
|
||||
android:textSize="@dimen/secondary_size"
|
||||
app:layout_constraintStart_toStartOf="@+id/backgroundView"
|
||||
app:layout_constraintTop_toTopOf="@+id/backgroundView" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3"
|
||||
app:layout_constraintEnd_toEndOf="@+id/backgroundView"
|
||||
app:layout_constraintStart_toStartOf="@+id/backgroundView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/interestTv">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/labelTv1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_shape_white_radius_4"
|
||||
android:drawableRight="@drawable/ic_interest_arrow"
|
||||
android:drawablePadding="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:text="解谜"
|
||||
android:textColor="@color/text_subtitle"
|
||||
android:textSize="@dimen/secondary_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/labelTv2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_shape_white_radius_4"
|
||||
android:drawableRight="@drawable/ic_interest_arrow"
|
||||
android:drawablePadding="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:text="角色扮演"
|
||||
android:textColor="@color/text_subtitle"
|
||||
android:textSize="@dimen/secondary_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/labelTv3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_shape_white_radius_4"
|
||||
android:drawableRight="@drawable/ic_interest_arrow"
|
||||
android:drawablePadding="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:text="Steam移植"
|
||||
android:textColor="@color/text_subtitle"
|
||||
android:textSize="@dimen/secondary_size" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
19
app/src/main/res/layout/item_recommend_interest_footer.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_white"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:src="@drawable/bg_recommend_interest_footer"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="w,328:56"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
19
app/src/main/res/layout/item_recommend_interest_image.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_white"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:src="@drawable/bg_recommend_interest"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="w,328:80"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
45
app/src/main/res/layout/item_skeleton_discovery_list.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<View
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:background="@drawable/bg_skeleton_radius_14" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="16dp"
|
||||
android:background="@drawable/bg_skeleton_radius_4" />
|
||||
<View
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/bg_skeleton_radius_4" />
|
||||
<View
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/bg_skeleton_radius_4" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@drawable/bg_skeleton_radius_4" />
|
||||
</LinearLayout>
|
||||
34
app/src/main/res/layout/layout_discovery_guide.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_alpha_40"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/guideImageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/guideImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/guideImageContainer"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginRight="24dp"
|
||||
android:src="@drawable/ic_discovery_guide" />
|
||||
</RelativeLayout>
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.common.baselist;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewStub;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -55,6 +56,8 @@ public abstract class LazyListFragment<T, VM extends BaseListViewModel /* 该泛
|
||||
|
||||
@Nullable
|
||||
protected SkeletonScreen mSkeletonScreen;
|
||||
@Nullable
|
||||
protected FrameLayout mSkeletonScreenView;
|
||||
|
||||
private int[] lastPositions;
|
||||
private int lastVisibleItemPosition;
|
||||
@ -145,6 +148,7 @@ public abstract class LazyListFragment<T, VM extends BaseListViewModel /* 该泛
|
||||
mReuseNoConn = mCachedView.findViewById(R.id.reuse_no_connection);
|
||||
mReuseNoData = mCachedView.findViewById(R.id.reuse_none_data);
|
||||
mDataExceptionView = mCachedView.findViewById(R.id.reuse_data_exception);
|
||||
mSkeletonScreenView = mCachedView.findViewById(R.id.skeleton);
|
||||
|
||||
if (mListRefresh != null) {
|
||||
mListRefresh.setColorSchemeResources(R.color.theme);
|
||||
|
||||
@ -412,6 +412,7 @@ public class Constants {
|
||||
public static final int PACKAGES_CD = 60 * 1000;
|
||||
|
||||
public static final String[] REPORT_LIST = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其他原因"};
|
||||
public static final String[] FEEDBACK_REASON_LIST = new String[]{"重复推荐", "不感兴趣", "游戏太旧", "已经玩过了", "游戏质量差", "与推荐描述不符"};
|
||||
|
||||
public static final String ENTRANCE_UNKNOWN = "(unknown)";
|
||||
|
||||
@ -442,6 +443,8 @@ public class Constants {
|
||||
public static final String SP_FOLLOW_SYSTEM_DARK_MODE_ENABLED = "follow_system_dark_mode_enabled";
|
||||
|
||||
public static final String SP_TEST_FLAVOR_CHANNEL = "sp_test_flavor_channel";
|
||||
//发现页引导
|
||||
public static final String SP_DISCOVERY_GUIDE = "sp_discovery_guide";
|
||||
|
||||
// 登入标识
|
||||
public static final String LOGIN_TAG = "login_tag";
|
||||
|
||||
@ -1210,6 +1210,14 @@ fun View.getBitmapFromView(): Bitmap? {
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun View.getBitmapFromView(width: Int, height: Int, offsetX: Float, offsetY: Float): Bitmap? {
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.translate(offsetX, offsetY)
|
||||
this.draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun View.setRootBackgroundColor(@ColorRes res: Int) {
|
||||
if (this.id == View.NO_ID) {
|
||||
this.id = R.id.root_container
|
||||
|
||||
@ -4,6 +4,11 @@
|
||||
android:layout_height = "match_parent"
|
||||
android:background="@color/background">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/skeleton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id = "@+id/list_refresh"
|
||||
android:layout_width = "match_parent"
|
||||
|
||||