From 5bf0bb50420993faec3b229fc81430f44b44da5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Fri, 10 Feb 2023 09:54:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E[=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E6=B5=AE=E5=B1=82]=E5=8A=9F=E8=83=BD=E2=80=94=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=20https://jira.shanqu.cc/browse/GHZS-1100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 2 +- .../com/gh/common/history/HistoryDatabase.kt | 12 +- .../com/gh/common/history/HistoryHelper.kt | 2 + .../java/com/gh/common/util/GameUtils.java | 1 + .../java/com/gh/common/util/PackageUtils.java | 2 + .../java/com/gh/download/DownloadManager.java | 5 + .../adapter/LibaoDetailAdapter.java | 4 +- .../adapter/MessageDetailAdapter.java | 4 +- .../com/gh/gamecenter/amway/AmwayAdapter.kt | 2 +- .../download/GameDownloadFragmentAdapter.java | 8 +- .../NewInstalledGameFragmentAdapter.kt | 5 +- .../download/UpdatableGameAdapter.kt | 2 +- .../download/UpdatableGameViewModel.kt | 5 + .../gamecenter/entity/AmwayCommentEntity.kt | 4 + .../com/gh/gamecenter/entity/GameInstall.kt | 3 + .../gh/gamecenter/entity/GameUpdateEntity.kt | 4 + .../gh/gamecenter/entity/HistoryGameEntity.kt | 3 + .../entity/PersonalHistoryEntity.kt | 3 + .../forum/detail/ForumDetailFragment.kt | 4 +- .../home/ForumArticleAskItemViewHolder.kt | 6 +- .../forum/home/ForumRecordsAdapter.kt | 6 +- .../forum/home/HorizontalForumsAdapter.kt | 6 +- .../gamecenter/forum/list/ForumListAdapter.kt | 6 +- .../gamedetail/GameDetailFragment.kt | 8 +- .../gamedetail/myrating/MyRatingAdapter.kt | 6 +- .../gh/gamecenter/info/ConcernAdapter.java | 4 +- .../libao/Libao2FragmentAdapter.java | 2 +- .../libao/Libao3FragmentAdapter.java | 2 +- .../gamecenter/libao/LibaoHistoryAdapter.java | 2 +- .../gh/gamecenter/libao/LibaoNewAdapter.kt | 6 +- .../gh/gamecenter/libao/LibaoSearchAdapter.kt | 6 +- .../personalhome/InstalledGameAdapter.kt | 6 +- .../personalhome/PersonalItemViewHolder.kt | 6 +- .../home/game/UserCommentHistoryAdapter.kt | 6 +- .../BaseAnswerOrArticleItemViewHolder.kt | 6 +- .../detail/ArticleDetailContentViewHolder.kt | 2 +- .../qa/dialog/ChooseForumContainerAdapter.kt | 2 +- .../QuestionDetailContentViewHolder.kt | 2 +- .../room/converter/IconFloatConverter.kt | 18 +++ .../video/detail/DetailPlayerView.kt | 2 +- .../video/game/GameVideoActivity.kt | 2 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 9 +- app/src/main/java/com/gh/vspace/VHelper.kt | 14 ++ .../main/res/layout/catalog_subject_item.xml | 3 +- .../main/res/layout/dialog_installed_game.xml | 4 + app/src/main/res/layout/forum_record_item.xml | 17 ++- app/src/main/res/layout/fragment_forum.xml | 18 ++- app/src/main/res/layout/game_gallery_list.xml | 1 + .../res/layout/game_gallery_slide_item.xml | 5 + app/src/main/res/layout/home_amway_list.xml | 1 + .../res/layout/item_home_recent_vgame.xml | 4 +- .../res/layout/layout_float_load_complete.xml | 4 + .../gamecenter/common/constant/Constants.java | 4 + .../common/entity/CommunityEntity.kt | 4 +- .../gh/gamecenter/common/entity/IconFloat.kt | 15 +++ .../res/drawable-xxxhdpi/label_bottom.webp | Bin 0 -> 18894 bytes .../label_upperleft_blue.9.png | Bin 0 -> 17508 bytes .../label_upperleft_red.9.png | Bin 0 -> 14278 bytes .../gamecenter/feature/entity/GameEntity.kt | 8 ++ .../gh/gamecenter/feature/view/GameIconUi.kt | 37 +++++- .../gamecenter/feature/view/GameIconView.kt | 121 ++++++++++++++++-- 61 files changed, 383 insertions(+), 73 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/room/converter/IconFloatConverter.kt create mode 100644 module_common/src/main/java/com/gh/gamecenter/common/entity/IconFloat.kt create mode 100644 module_common/src/main/res/drawable-xxxhdpi/label_bottom.webp create mode 100644 module_common/src/main/res/drawable-xxxhdpi/label_upperleft_blue.9.png create mode 100644 module_common/src/main/res/drawable-xxxhdpi/label_upperleft_red.9.png diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 56c4f589e4..8308df2f79 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -262,7 +262,7 @@ public class BindingAdapters { public static void setGameIcon(View view, GameEntity gameEntity) { if (gameEntity != null && view instanceof GameIconView) { - ((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript()); + ((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript(), gameEntity.getIconFloat()); } } diff --git a/app/src/main/java/com/gh/common/history/HistoryDatabase.kt b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt index 291db67894..d446fff269 100644 --- a/app/src/main/java/com/gh/common/history/HistoryDatabase.kt +++ b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt @@ -19,7 +19,7 @@ import com.halo.assistant.HaloApp @Database( entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class], - version = 12, + version = 13, exportSchema = false ) @TypeConverters( @@ -40,7 +40,8 @@ import com.halo.assistant.HaloApp MeConverter::class, SimpleGameListConverter::class, TagInfoListConverter::class, - ActivityLabelListConverter::class + ActivityLabelListConverter::class, + IconFloatConverter::class ) abstract class HistoryDatabase : RoomDatabase() { @@ -136,6 +137,12 @@ abstract class HistoryDatabase : RoomDatabase() { } } + val MIGRATION_12_13: Migration = object : Migration(12, 13) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("Alter TABLE HistoryGameEntity add iconFloat TEXT") + } + } + val instance by lazy { Room.databaseBuilder( HaloApp.getInstance().application, @@ -152,6 +159,7 @@ abstract class HistoryDatabase : RoomDatabase() { .addMigrations(MIGRATION_9_10) .addMigrations(MIGRATION_10_11) .addMigrations(MIGRATION_11_12) + .addMigrations(MIGRATION_12_13) .build() } } diff --git a/app/src/main/java/com/gh/common/history/HistoryHelper.kt b/app/src/main/java/com/gh/common/history/HistoryHelper.kt index 03ffceb51d..68c40bd872 100644 --- a/app/src/main/java/com/gh/common/history/HistoryHelper.kt +++ b/app/src/main/java/com/gh/common/history/HistoryHelper.kt @@ -56,6 +56,7 @@ object HistoryHelper { historyGame.des = "" historyGame.icon = updateEntity.rawIcon ?: updateEntity.icon historyGame.iconSubscript = updateEntity.iconSubscript + historyGame.iconFloat = updateEntity.iconFloat historyGame.name = updateEntity.name historyGame.tagStyle = updateEntity.tagStyle return historyGame @@ -70,6 +71,7 @@ object HistoryHelper { historyGame.des = gameEntity.des historyGame.icon = gameEntity.rawIcon ?: gameEntity.icon historyGame.iconSubscript = gameEntity.iconSubscript + historyGame.iconFloat = gameEntity.iconFloat historyGame.name = gameEntity.name historyGame.tagStyle = gameEntity.tagStyle historyGame.tag = gameEntity.getTag() diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 3906766d87..c1aa81a51a 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -204,6 +204,7 @@ public class GameUtils { gameUpdateEntity.setIcon(gameEntity.getIcon()); gameUpdateEntity.setRawIcon(gameEntity.getRawIcon()); gameUpdateEntity.setIconSubscript(gameEntity.getIconSubscript()); + gameUpdateEntity.setIconFloat(gameEntity.getIconFloat()); gameUpdateEntity.setName(gameEntity.getName()); gameUpdateEntity.setPackageName(apkEntity.getPackageName()); gameUpdateEntity.setSize(apkEntity.getSize()); diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index ef114fc4cd..2a1b117e29 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -118,6 +118,7 @@ public class PackageUtils { updateEntity.setIcon(gameEntity.getIcon()); updateEntity.setRawIcon(gameEntity.getRawIcon()); updateEntity.setIconSubscript(gameEntity.getIconSubscript()); + updateEntity.setIconFloat(gameEntity.getIconFloat()); updateEntity.setPackageName(apkEntity.getPackageName()); updateEntity.setSize(apkEntity.getSize()); updateEntity.setVersion(apkEntity.getVersion()); @@ -185,6 +186,7 @@ public class PackageUtils { updateEntity.setIcon(gameEntity.getIcon()); updateEntity.setRawIcon(gameEntity.getRawIcon()); updateEntity.setIconSubscript(gameEntity.getIconSubscript()); + updateEntity.setIconFloat(gameEntity.getIconFloat()); updateEntity.setPackageName(apkEntity.getPackageName()); updateEntity.setSize(apkEntity.getSize()); updateEntity.setVersion(apkEntity.getVersion()); diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 8d992b4cc0..7ea0edb6a5 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -326,6 +326,11 @@ public class DownloadManager implements DownloadStatusListener { ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_PLATFORM_RECOMMEND, apkEntity.getRecommend() != null ? "true" : "false"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_NAME, gameEntity.getName()); + if (gameEntity.getIconFloat() != null) { + ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT, gameEntity.getIconFloat().getUpperLeftText()); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor()); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, gameEntity.getIconFloat().getBottomText()); + } if (SimulatorGameManager.isSimulatorGame(gameEntity)) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR_GAME, apkEntity.getFormat()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator())); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/LibaoDetailAdapter.java b/app/src/main/java/com/gh/gamecenter/adapter/LibaoDetailAdapter.java index 1ee0a83e06..68177c07bd 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/LibaoDetailAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/LibaoDetailAdapter.java @@ -200,11 +200,11 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter { ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white); if (mLibaoEntity.getGame() != null) { - holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getGame().getIcon(), mLibaoEntity.getGame().getIconSubscript()); + holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getGame().getIcon(), mLibaoEntity.getGame().getIconSubscript(), mLibaoEntity.getGame().getIconFloat()); GameEntity gameEntity = mLibaoEntity.getGame().toGameEntity(); GameItemViewHolder.initGameSubtitle(gameEntity, holder.binding.gameSubtitleTv, null, null, false, null); } else { - holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null); + holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null, mLibaoEntity.getGame().getIconFloat()); } holder.binding.libaodetailName.setText(mLibaoEntity.getName()); if (TextUtils.isEmpty(mLibaoEntity.getPlatform())) { diff --git a/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java b/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java index c613390101..78365bb06b 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java @@ -291,9 +291,9 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter { } if (mConcernEntity.getGame() != null) { - viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGame().getIcon(), mConcernEntity.getGame().getIconSubscript()); + viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGame().getIcon(), mConcernEntity.getGame().getIconSubscript(), mConcernEntity.getGame().getIconFloat()); } else { - viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null); + viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null, mConcernEntity.getGame().getIconFloat()); } viewHolder.binding.newsDigestTitle.setText(mConcernEntity.getGameName()); NewsUtils.setNewsPublishOn(viewHolder.binding.newsDigestTime, mConcernEntity.getTime()); diff --git a/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt b/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt index 55307e5a59..08f6954c3f 100644 --- a/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt @@ -255,7 +255,7 @@ class AmwayAdapter( binding.gameIconView.displayGameIcon( amway.game.rawIcon - ?: amway.game.icon, amway.game.iconSubscript + ?: amway.game.icon, amway.game.iconSubscript, amway.game.iconFloat ) amway.game.tag?.let { diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java index 4f21437232..1a3b5a4a8e 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder; import com.gh.common.util.DialogUtils; import com.gh.common.util.PackageInstaller; import com.gh.common.util.PackageUtils; +import com.gh.gamecenter.common.entity.IconFloat; import com.gh.gamecenter.feature.utils.PlatformUtils; import com.gh.gamecenter.feature.view.DownloadButton; import com.gh.common.xapk.XapkInstaller; @@ -125,7 +126,12 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { if (!TextUtils.isEmpty(rawIcon)) { icon = rawIcon; } - viewHolder.binding.dmItemIvIcon.displayGameIcon(icon, ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT)); + IconFloat iconFloat = new IconFloat( + ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT), + ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR), + ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_BOTTOM_TEXT) + ); + viewHolder.binding.dmItemIvIcon.displayGameIcon(icon, ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT), iconFloat); } else { ImageUtils.display(viewHolder.binding.dmItemIvIcon.getIconIv(), R.mipmap.logo); viewHolder.binding.dmItemIvIcon.getIconDecoratorIv().setVisibility(View.GONE); diff --git a/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragmentAdapter.kt index 1ccab6b4c5..b03493afb2 100644 --- a/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragmentAdapter.kt @@ -82,12 +82,13 @@ class NewInstalledGameFragmentAdapter(context: Context, private var mViewModel: name = gameEntity.name binding.gameIconView.displayGameIcon( gameEntity.getRawIconInAdvanced(), - gameEntity.iconSubscript + gameEntity.iconSubscript, + gameEntity.iconFloat ) binding.gameDes.text = gameEntity.brief } if (isSimulatorGame(gameEntity)) { - binding.gameIconView.displayGameIcon(gameEntity.icon, gameEntity.iconSubscript) + binding.gameIconView.displayGameIcon(gameEntity.icon, gameEntity.iconSubscript, gameEntity.iconFloat) } binding.gameName.text = name generateExposureEvent(gameEntity) diff --git a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt index 333e38b0d0..a660599b0d 100644 --- a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt @@ -168,7 +168,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) : container.setBackgroundColor(R.color.background_white.toColor(context)) } - iconIv.displayGameIcon(update.rawIcon ?: update.icon, update.iconSubscript) + iconIv.displayGameIcon(update.rawIcon ?: update.icon, update.iconSubscript, update.iconFloat) val nameText = if (!update.readablePlatform.isNullOrEmpty()) { update.name + " - " + update.readablePlatform } else { diff --git a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt index 818e341afd..e17936d0e7 100644 --- a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt @@ -586,6 +586,11 @@ class UpdatableGameViewModel( downloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript) downloadEntity.addMetaExtra(Constants.DOWNLOAD_ID, downloadId) downloadEntity.addMetaExtra(Constants.APK_MD5, update.md5) + if (update.iconFloat != null) { + downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT, update.iconFloat?.upperLeftText) + downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_COLOR, update.iconFloat?.upperLeftColor) + downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, update.iconFloat?.bottomText) + } val platform = PlatformUtils.getInstance(getApplication()).getPlatformName(update.platform) if ("官方版" != platform) { diff --git a/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt index ad5362e3ec..4a0cba2049 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.entity import android.os.Parcelable +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.entity.TagStyleEntity import com.google.gson.annotations.SerializedName @@ -37,6 +38,8 @@ data class AmwayCommentEntity( var subtitle: String? = "", @SerializedName("subtitle_style") var subtitleStyle: TagStyleEntity? = null, + @SerializedName("icon_float") + var iconFloat: IconFloat? = null, // 曝光用的位置 var sequence: Int = 0, @@ -54,6 +57,7 @@ data class AmwayCommentEntity( gameEntity.icon = icon gameEntity.rawIcon = rawIcon gameEntity.iconSubscript = iconSubscript + gameEntity.iconFloat = iconFloat gameEntity.platform = "" gameEntity.subtitle = subtitle ?: "" diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt index f8fd413c8c..1be15caaf9 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.entity import com.gh.common.util.PackageUtils +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.feature.entity.GameEntity import com.google.gson.annotations.SerializedName import com.halo.assistant.HaloApp @@ -12,6 +13,7 @@ data class GameInstall( var name: String? = "", var icon: String? = "", var iconSubScript: String? = "", + var iconFloat: IconFloat? = null, var isSignByGh: Boolean = false, var installTime: Long = 0, var version: String = "", @@ -29,6 +31,7 @@ data class GameInstall( gameInstall.name = game.name gameInstall.icon = game.rawIcon ?: game.icon gameInstall.iconSubScript = game.iconSubscript + gameInstall.iconFloat = game.iconFloat gameInstall.version = PackageUtils.getVersionNameByPackageName(installedPkgName) ?: "unknown" gameInstall.packageName = installedPkgName gameInstall.isSmoothGame = game.isVGame() diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt index 3e4dcf50f4..19e2f43c6d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt @@ -1,5 +1,6 @@ package com.gh.gamecenter.entity +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.entity.* import com.google.gson.annotations.SerializedName @@ -13,6 +14,8 @@ data class GameUpdateEntity( var rawIcon: String? = null, @SerializedName("icon_subscript") var iconSubscript: String? = "", + @SerializedName("icon_float") + var iconFloat: IconFloat? = null, @SerializedName("package") var packageName: String = "", var size: String? = null, @@ -60,6 +63,7 @@ data class GameUpdateEntity( gameEntity.icon = icon gameEntity.rawIcon = rawIcon gameEntity.iconSubscript = iconSubscript + gameEntity.iconFloat = iconFloat gameEntity.tagStyle = tagStyle gameEntity.brief = brief gameEntity.download = download diff --git a/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt index 0e29ce48bf..b192cc8f48 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt @@ -2,6 +2,7 @@ package com.gh.gamecenter.entity import androidx.room.Entity import androidx.room.PrimaryKey +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.entity.TagStyleEntity import com.google.gson.annotations.SerializedName @@ -12,6 +13,7 @@ data class HistoryGameEntity( var id: String = "", var icon: String? = null, var iconSubscript: String? = null, + var iconFloat: IconFloat? = null, var name: String? = null, var brief: String? = null, @@ -36,6 +38,7 @@ data class HistoryGameEntity( gameEntity.des = des gameEntity.rawIcon = icon gameEntity.iconSubscript = iconSubscript + gameEntity.iconFloat = iconFloat gameEntity.subtitle = subtitle gameEntity.subtitleStyle = subtitleStyle gameEntity.name = name diff --git a/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt index 6667e3595b..6ed1cdca44 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt @@ -5,6 +5,7 @@ import android.os.Parcelable import com.gh.gamecenter.common.annotation.SyncPage import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.entity.CommunityEntity +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.common.syncpage.SyncFieldConstants import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.TimeUtils @@ -133,6 +134,8 @@ data class PersonalHistoryEntity( var rawIcon: String? = null, @SerializedName("icon_subscript") var iconSubscript: String? = null, + @SerializedName("icon_float") + var iconFloat: IconFloat? = null, @SerializedName("played_time") val playedTime: Long = 0 diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt index 38ec0a4d19..5dfc3c7d8e 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt @@ -342,8 +342,8 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable { mBinding.forumThumbSmall.displayGameIcon(icon, null) mBinding.forumThumbBig.displayGameIcon(icon, null) } else { - mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript) - mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript) + mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat) + mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat) } mBinding.toolbar.setNavigationIcon(if (!mIsDarkModeOn) R.drawable.ic_bar_back else R.drawable.ic_bar_back_light) mBinding.searchIv.setImageDrawable( diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt index 22a92b3c45..59436cec93 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt @@ -326,7 +326,11 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : if (entity.bbs.type == "official_bbs") { forumIcon?.displayGameIcon(entity.bbs.icon, null) } else { - forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript) + forumIcon?.displayGameIcon( + entity.bbs.game?.getIcon(), + entity.bbs.game?.iconSubscript, + entity.bbs.game?.iconFloat + ) } forumNameTv.setOnClickListener { diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt index 663cc84d99..549f864ab8 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt @@ -48,7 +48,11 @@ class ForumRecordsAdapter( if (forumEntity.type == "official_bbs") { forumIv.displayGameIcon(forumEntity.icon, null) } else { - forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript) + forumIv.displayGameIcon( + forumEntity.game.getIcon(), + forumEntity.game.iconSubscript, + forumEntity.game.iconFloat + ) } root.setOnClickListener { diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt index c86a57e982..54a26b3008 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt @@ -55,7 +55,11 @@ class HorizontalForumsAdapter( if (forumEntity.type == "official_bbs") { forumIv.displayGameIcon(forumEntity.icon, null) } else { - forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript) + forumIv.displayGameIcon( + forumEntity.game.getIcon(), + forumEntity.game.iconSubscript, + forumEntity.game.iconFloat + ) } followTv.run { diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt index 4f430cac7b..547ded9a73 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt @@ -65,7 +65,11 @@ class ForumListAdapter( if (forumEntity?.type == "official_bbs") { forumIcon.displayGameIcon(forumEntity.icon, null) } else { - forumIcon.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript) + forumIcon.displayGameIcon( + forumEntity.game.getIcon(), + forumEntity.game.iconSubscript, + forumEntity.game.iconFloat + ) } topLine.visibility = if (position == 0) View.GONE else View.VISIBLE diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index c67177cd7d..e1460c75f7 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1119,7 +1119,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } mBodyBinding.gamedetailTvName.isSelected = true val ranking = mNewGameDetailEntity!!.ranking - if (ranking != null) { + val shouldShowRank = + (ranking != null && (mGameEntity?.iconFloat == null || mGameEntity?.iconFloat?.bottomText.isNullOrEmpty())) || (ranking != null && ranking.no.toInt() <= 10 && mGameEntity?.iconFloat != null && !mGameEntity?.iconFloat?.bottomText.isNullOrEmpty()) + if (ranking != null && shouldShowRank) { mBodyBinding.gameDetailRankLl.visibility = View.VISIBLE mBodyBinding.gameDetailRankTv.text = "${ranking.columnName}第${ranking.no}名" mBodyBinding.gameDetailRankTv.isSelected = true @@ -1134,7 +1136,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } - BindingAdapters.setGame(mBodyBinding.gamedetailIvThumb, mGameEntity) + BindingAdapters.setGame(mBodyBinding.gamedetailIvThumb, mGameEntity?.apply { + if (shouldShowRank && iconFloat != null) iconFloat!!.bottomText = "" + }) BindingAdapters.setGame(mBodyBinding.gamedetailThumbSmall, mGameEntity) mNewGameDetailEntity?.event?.let { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingAdapter.kt index 627a27605a..1a15c414a4 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingAdapter.kt @@ -62,7 +62,11 @@ class MyRatingAdapter( holder.binding.tvComment.setExpandMaxLines(maxDesLines) holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines) - holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript) + holder.binding.gameIcon.displayGameIcon( + rating.game.getRawIconIfExisted(), + rating.game.iconSubscript, + rating.game.iconFloat + ) val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content) if (m.find()) { diff --git a/app/src/main/java/com/gh/gamecenter/info/ConcernAdapter.java b/app/src/main/java/com/gh/gamecenter/info/ConcernAdapter.java index 7aa39d8774..5c158a7acf 100644 --- a/app/src/main/java/com/gh/gamecenter/info/ConcernAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/info/ConcernAdapter.java @@ -362,9 +362,9 @@ class ConcernAdapter extends BaseRecyclerAdapter { viewHolder.setClickData(concernEntity); if (concernEntity.getGame() != null) { - viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGame().getIcon(), concernEntity.getGame().getIconSubscript()); + viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGame().getIcon(), concernEntity.getGame().getIconSubscript(), concernEntity.getGame().getIconFloat()); } else { - viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGameIcon(), null); + viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGameIcon(), null, concernEntity.getGame().getIconFloat()); } viewHolder.binding.newsDigestTitle.setText(concernEntity.getGameName()); diff --git a/app/src/main/java/com/gh/gamecenter/libao/Libao2FragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/libao/Libao2FragmentAdapter.java index 8afae28d62..ad88ded1fe 100644 --- a/app/src/main/java/com/gh/gamecenter/libao/Libao2FragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/libao/Libao2FragmentAdapter.java @@ -207,7 +207,7 @@ class Libao2FragmentAdapter extends BaseRecyclerAdapter { holder.setClickData(libaoEntity); ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white); holder.binding.libaoName.setText(libaoEntity.getName()); - holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript()); + holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat()); if (TextUtils.isEmpty(libaoEntity.getPlatform())) { holder.binding.libaoGameName.setText(libaoEntity.getGame().getName()); } else { diff --git a/app/src/main/java/com/gh/gamecenter/libao/Libao3FragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/libao/Libao3FragmentAdapter.java index a708118eb0..b0404c345d 100644 --- a/app/src/main/java/com/gh/gamecenter/libao/Libao3FragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/libao/Libao3FragmentAdapter.java @@ -205,7 +205,7 @@ class Libao3FragmentAdapter extends BaseRecyclerAdapter final LibaoEntity libaoEntity = mLibaoList.get(position); ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white); holder.binding.libaoName.setText(libaoEntity.getName()); - holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript()); + holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat()); if (mFilter.equals("expires:false") && libaoEntity.getExpires() > 0) { holder.binding.expiresTime.setVisibility(View.VISIBLE); holder.binding.expiresTime.setText(String.format(Locale.CHINA, "%s过期", TimeUtils.getFormatTime(libaoEntity.getExpires(), "MM.dd"))); diff --git a/app/src/main/java/com/gh/gamecenter/libao/LibaoHistoryAdapter.java b/app/src/main/java/com/gh/gamecenter/libao/LibaoHistoryAdapter.java index 32a9ec002b..c5a5c7c65e 100644 --- a/app/src/main/java/com/gh/gamecenter/libao/LibaoHistoryAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/libao/LibaoHistoryAdapter.java @@ -161,7 +161,7 @@ public class LibaoHistoryAdapter extends BaseRecyclerAdapter { viewHolder.binding.libaoName.setText(libaoEntity.getName()); viewHolder.binding.libaoDes.setText(libaoEntity.getContent()); viewHolder.binding.libaoGameName.setText(libaoEntity.getGame().getName()); - viewHolder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript()); + viewHolder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat()); //领取状态 if (TextUtils.isEmpty(libaoEntity.getStatus())) { diff --git a/app/src/main/java/com/gh/gamecenter/libao/LibaoNewAdapter.kt b/app/src/main/java/com/gh/gamecenter/libao/LibaoNewAdapter.kt index 426e808326..05102f5f23 100644 --- a/app/src/main/java/com/gh/gamecenter/libao/LibaoNewAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/libao/LibaoNewAdapter.kt @@ -201,7 +201,11 @@ class LibaoNewAdapter( .getPlatformName(libaoEntity.platform) ) } - holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript()) + holder.binding.libaoGameIcon.displayGameIcon( + libaoEntity.getIcon(), + libaoEntity.getIconSubscript(), + libaoEntity.game?.iconFloat + ) val content: String if (libaoEntity.content!!.contains("
")) { diff --git a/app/src/main/java/com/gh/gamecenter/libao/LibaoSearchAdapter.kt b/app/src/main/java/com/gh/gamecenter/libao/LibaoSearchAdapter.kt index 56c1f04a77..c40a9b438d 100644 --- a/app/src/main/java/com/gh/gamecenter/libao/LibaoSearchAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/libao/LibaoSearchAdapter.kt @@ -222,7 +222,11 @@ class LibaoSearchAdapter( .getPlatformName(libaoEntity.platform) ) } - holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript()) + holder.binding.libaoGameIcon.displayGameIcon( + libaoEntity.getIcon(), + libaoEntity.getIconSubscript(), + libaoEntity.game?.iconFloat + ) val content: String if (libaoEntity.content!!.contains("
")) { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/InstalledGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/InstalledGameAdapter.kt index 3fdb06d208..63b8623d77 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/InstalledGameAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/InstalledGameAdapter.kt @@ -23,7 +23,11 @@ class InstalledGameAdapter(mContext: Context, val games: ArrayList) override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val gameInstall = games[position] holder.itemView.apply { - findViewById(R.id.game_icon).displayGameIcon(gameInstall.icon, gameInstall.iconSubScript) + findViewById(R.id.game_icon).displayGameIcon( + gameInstall.icon, + gameInstall.iconSubScript, + gameInstall.iconFloat + ) findViewById(R.id.game_name).text = gameInstall.name } } diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt index 03bed12d67..89518888bb 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt @@ -16,7 +16,11 @@ class PersonalItemViewHolder(val binding: CommunityAnswerItemBinding) : if (entity.community.type == "official_bbs") { forumIcon?.displayGameIcon(entity.community.icon, null) } else { - forumIcon?.displayGameIcon(entity.community.game?.getIcon(), entity.community.game?.iconSubscript) + forumIcon?.displayGameIcon( + entity.community.game?.getIcon(), + entity.community.game?.iconSubscript, + entity.community.game?.iconFloat + ) } forumNameContainer?.setOnClickListener { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt index a4be8052c3..253a1a6474 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt @@ -80,7 +80,11 @@ class UserCommentHistoryAdapter( holder.binding.tvComment.setExpandMaxLines(maxDesLines) holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines) - holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript) + holder.binding.gameIcon.displayGameIcon( + rating.game.getRawIconIfExisted(), + rating.game.iconSubscript, + rating.game.iconFloat + ) val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content) if (m.find()) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt index c89092c14f..ba1f9d3f56 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt @@ -136,7 +136,11 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH if (entity.bbs.type == "official_bbs") { forumIcon?.displayGameIcon(entity.bbs.icon, null) } else { - forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript) + forumIcon?.displayGameIcon( + entity.bbs.game?.getIcon(), + entity.bbs.game?.iconSubscript, + entity.bbs.game?.iconFloat + ) } val contentType = when (entity.type) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailContentViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailContentViewHolder.kt index b91cff18cd..6347656215 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailContentViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailContentViewHolder.kt @@ -183,7 +183,7 @@ class ArticleDetailContentViewHolder( val icon = if (!entity.icon.isNullOrEmpty()) entity.icon else entity.game?.getIcon() val iconSubscript = if (!entity.iconSubscript.isNullOrEmpty()) entity.iconSubscript else entity.game?.iconSubscript - forumIconView.displayGameIcon(icon, iconSubscript) + forumIconView.displayGameIcon(icon, iconSubscript, entity.game?.iconFloat) forumContainer.setOnClickListener { DirectUtils.directForumDetail(forumContainer.context, entity.id, "帖子详情") LogUtils.uploadAccessToBbs(entity.id, "文章内所属论坛") diff --git a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt index dbb94e3b46..8c5094ed7a 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt @@ -72,7 +72,7 @@ class ChooseForumContainerAdapter( ) val icon = forumEntity.icon.ifEmpty { forumEntity.game.getIcon() } - holder.binding.forumIcon.displayGameIcon(icon, forumEntity.game.iconSubscript) + holder.binding.forumIcon.displayGameIcon(icon, forumEntity.game.iconSubscript, forumEntity.game.iconFloat) holder.binding.followTv.visibility = View.GONE holder.itemView.setOnClickListener { val tabType = if (type == ChooseForumContainerFragment.ChooseForumType.SEARCH.value) "论坛tab" else "" diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/QuestionDetailContentViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/QuestionDetailContentViewHolder.kt index 40f0b92bbe..e2ad6ab5c2 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/QuestionDetailContentViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/QuestionDetailContentViewHolder.kt @@ -160,7 +160,7 @@ class QuestionDetailContentViewHolder( val icon = if (!entity.icon.isNullOrEmpty()) entity.icon else entity.game?.getIcon() val iconSubscript = if (!entity.iconSubscript.isNullOrEmpty()) entity.iconSubscript else entity.game?.iconSubscript - forumIconView.displayGameIcon(icon, iconSubscript) + forumIconView.displayGameIcon(icon, iconSubscript, entity.game?.iconFloat) forumContainer.setOnClickListener { DirectUtils.directForumDetail(forumContainer.context, entity.id, "问题详情") LogUtils.uploadAccessToBbs(entity.id, "文章内所属论坛") diff --git a/app/src/main/java/com/gh/gamecenter/room/converter/IconFloatConverter.kt b/app/src/main/java/com/gh/gamecenter/room/converter/IconFloatConverter.kt new file mode 100644 index 0000000000..72f318240b --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/room/converter/IconFloatConverter.kt @@ -0,0 +1,18 @@ +package com.gh.gamecenter.room.converter + +import androidx.room.TypeConverter +import com.gh.gamecenter.common.entity.IconFloat +import com.gh.gamecenter.common.utils.toJson +import com.gh.gamecenter.common.utils.toObject + +class IconFloatConverter { + @TypeConverter + fun toIconFloatString(data: IconFloat?): String { + return data?.toJson() ?: "" + } + + @TypeConverter + fun toIconFloat(token: String?): IconFloat { + return token?.toObject() ?: IconFloat() + } +} diff --git a/app/src/main/java/com/gh/gamecenter/video/detail/DetailPlayerView.kt b/app/src/main/java/com/gh/gamecenter/video/detail/DetailPlayerView.kt index 6f150c0a1e..7627f69404 100644 --- a/app/src/main/java/com/gh/gamecenter/video/detail/DetailPlayerView.kt +++ b/app/src/main/java/com/gh/gamecenter/video/detail/DetailPlayerView.kt @@ -214,7 +214,7 @@ class DetailPlayerView @JvmOverloads constructor(context: Context, attrs: Attrib mBinding.gameIconView.displayGameIcon( videoEntity.game?.rawIcon - ?: videoEntity.gameIcon, videoEntity.game?.iconSubscript + ?: videoEntity.gameIcon, videoEntity.game?.iconSubscript, videoEntity.game?.iconFloat ) ImageUtils.display(mBinding.userIconIv, videoEntity.user.icon) if (videoEntity.user.border.isNotEmpty()) { diff --git a/app/src/main/java/com/gh/gamecenter/video/game/GameVideoActivity.kt b/app/src/main/java/com/gh/gamecenter/video/game/GameVideoActivity.kt index 5f58f8dd7c..8dbf886768 100644 --- a/app/src/main/java/com/gh/gamecenter/video/game/GameVideoActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/video/game/GameVideoActivity.kt @@ -74,7 +74,7 @@ class GameVideoActivity : ToolBarActivity() { if (it.status == Status.SUCCESS) { mBinding.gameIcon.displayGameIcon( it.data?.game?.getIcon() - ?: it.data?.gameIcon, it.data?.game?.iconSubscript + ?: it.data?.gameIcon, it.data?.game?.iconSubscript, it.data?.game?.iconFloat ) mBinding.gameName.text = it.data?.game?.name mBinding.likeCount.text = NumberUtils.transSimpleCount(it.data?.likeCount ?: 0) diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index bc1ff99f6c..ce112c3b92 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -10,6 +10,7 @@ import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.common.baselist.DiffUtilAdapter import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration import com.gh.gamecenter.core.utils.ToastUtils @@ -115,9 +116,15 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( fun bindView(entity: VGameItemData) { if (mBinding.gameIconIv.getTag(R.string.app_name) != entity.downloadEntity.packageName) { + val iconFloat = IconFloat( + entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT), + entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_TOP_COLOR), + entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_BOTTOM_TEXT) + ) mBinding.gameIconIv.displayGameIcon( entity.downloadEntity.getMetaExtra(Constants.RAW_GAME_ICON), - entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT) + entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT), + iconFloat ) mBinding.gameIconIv.setTag(R.string.app_name, entity.downloadEntity.packageName) } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 5769fbbda5..bb4c40dc5c 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -774,6 +774,20 @@ object VHelper { updateEntity.iconSubscript ) originDownloadEntity.addMetaExtra(Constants.APK_MD5, updateEntity.md5) + if (updateEntity.iconFloat != null) { + originDownloadEntity.addMetaExtra( + Constants.GAME_ICON_FLOAT_TOP_TEXT, + updateEntity.iconFloat?.upperLeftText + ) + originDownloadEntity.addMetaExtra( + Constants.GAME_ICON_FLOAT_TOP_COLOR, + updateEntity.iconFloat?.upperLeftColor + ) + originDownloadEntity.addMetaExtra( + Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, + updateEntity.iconFloat?.bottomText + ) + } PackageRepository.removeUpdate(updateEntity.id, true) } diff --git a/app/src/main/res/layout/catalog_subject_item.xml b/app/src/main/res/layout/catalog_subject_item.xml index 29c4d9af46..9511f2b432 100644 --- a/app/src/main/res/layout/catalog_subject_item.xml +++ b/app/src/main/res/layout/catalog_subject_item.xml @@ -2,4 +2,5 @@ + android:layout_height="wrap_content" + android:clipChildren="false" /> diff --git a/app/src/main/res/layout/dialog_installed_game.xml b/app/src/main/res/layout/dialog_installed_game.xml index 7e49ef1364..c985ffd7c8 100644 --- a/app/src/main/res/layout/dialog_installed_game.xml +++ b/app/src/main/res/layout/dialog_installed_game.xml @@ -22,7 +22,11 @@ android:id="@+id/dialog_installed_game_rv" android:layout_width="match_parent" android:layout_height="200dp" + android:layout_marginTop="-2dp" + android:clipChildren="false" + android:clipToPadding="false" android:paddingLeft="24dp" + android:paddingTop="2dp" android:paddingRight="24dp" /> diff --git a/app/src/main/res/layout/forum_record_item.xml b/app/src/main/res/layout/forum_record_item.xml index 9db72c1dc6..a9c6a16f27 100644 --- a/app/src/main/res/layout/forum_record_item.xml +++ b/app/src/main/res/layout/forum_record_item.xml @@ -8,15 +8,6 @@ android:gravity="center_horizontal" android:orientation="vertical"> - - + + android:overScrollMode="never" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toBottomOf="@+id/followTitle" /> + android:layout_height="wrap_content" + android:clipChildren="false"> + android:overScrollMode="never" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toBottomOf="@+id/hotTitle" /> diff --git a/app/src/main/res/layout/game_gallery_slide_item.xml b/app/src/main/res/layout/game_gallery_slide_item.xml index 77c9910cc5..fbf61d06f4 100644 --- a/app/src/main/res/layout/game_gallery_slide_item.xml +++ b/app/src/main/res/layout/game_gallery_slide_item.xml @@ -20,6 +20,8 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" android:descendantFocusability="blocksDescendants" android:orientation="vertical" android:paddingTop="12dp" @@ -29,6 +31,7 @@ android:id="@+id/firstRecyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" + android:clipChildren="false" android:clipToPadding="false" android:paddingLeft="12dp" /> @@ -37,6 +40,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="12dp" + android:clipChildren="false" android:clipToPadding="false" android:paddingLeft="26dp" /> @@ -45,6 +49,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="12dp" + android:clipChildren="false" android:clipToPadding="false" android:paddingLeft="8dp" /> diff --git a/app/src/main/res/layout/home_amway_list.xml b/app/src/main/res/layout/home_amway_list.xml index ab0fc8fda1..908a60295c 100644 --- a/app/src/main/res/layout/home_amway_list.xml +++ b/app/src/main/res/layout/home_amway_list.xml @@ -4,6 +4,7 @@ android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" + android:clipChildren="false" android:clipToPadding="false" android:descendantFocusability="blocksDescendants" android:paddingTop="12dp" diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index a3168f740b..1384abbaa6 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -64,9 +64,11 @@ diff --git a/app/src/main/res/layout/layout_float_load_complete.xml b/app/src/main/res/layout/layout_float_load_complete.xml index a492126422..907fa48891 100644 --- a/app/src/main/res/layout/layout_float_load_complete.xml +++ b/app/src/main/res/layout/layout_float_load_complete.xml @@ -21,7 +21,11 @@ android:id="@+id/viewPager" android:layout_width="0dp" android:layout_height="0dp" + android:layout_marginStart="-1dp" android:layout_marginEnd="12dp" + android:clipChildren="false" + android:clipToPadding="false" + android:paddingStart="1dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/launchTv" app:layout_constraintStart_toEndOf="@+id/closeIv" diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index 6bf962bc64..933b11316a 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -57,6 +57,10 @@ public class Constants { public static final String RAW_GAME_ICON = "raw_game_icon"; public static final String GAME_ICON_SUBSCRIPT = "game_icon_subscript"; + public static final String GAME_ICON_FLOAT_TOP_TEXT = "game_icon_float_top"; + public static final String GAME_ICON_FLOAT_TOP_COLOR = "game_icon_float_top_color"; + public static final String GAME_ICON_FLOAT_BOTTOM_TEXT = "game_icon_float_bottom"; + public static final String IS_PLATFORM_RECOMMEND = "isPlatformRecommend"; public static final String APK_MD5 = "apk_md5"; diff --git a/module_common/src/main/java/com/gh/gamecenter/common/entity/CommunityEntity.kt b/module_common/src/main/java/com/gh/gamecenter/common/entity/CommunityEntity.kt index 0065b5e199..d53806baef 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/entity/CommunityEntity.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/entity/CommunityEntity.kt @@ -33,7 +33,9 @@ data class CommunityEntity( @SerializedName("ori_icon") var mRawIcon: String? = null, @SerializedName("icon_subscript") - var iconSubscript: String? = null + var iconSubscript: String? = null, + @SerializedName("icon_float") + var iconFloat: IconFloat? = null ) : Parcelable { @IgnoredOnParcel diff --git a/module_common/src/main/java/com/gh/gamecenter/common/entity/IconFloat.kt b/module_common/src/main/java/com/gh/gamecenter/common/entity/IconFloat.kt new file mode 100644 index 0000000000..9f7c29fd5c --- /dev/null +++ b/module_common/src/main/java/com/gh/gamecenter/common/entity/IconFloat.kt @@ -0,0 +1,15 @@ +package com.gh.gamecenter.common.entity + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import kotlinx.parcelize.Parcelize + +@Parcelize +data class IconFloat( + @SerializedName("upper_left_text") + var upperLeftText: String = "", + @SerializedName("upper_left_color") + var upperLeftColor: String = "", + @SerializedName("bottom_text") + var bottomText: String = "" +) : Parcelable \ No newline at end of file diff --git a/module_common/src/main/res/drawable-xxxhdpi/label_bottom.webp b/module_common/src/main/res/drawable-xxxhdpi/label_bottom.webp new file mode 100644 index 0000000000000000000000000000000000000000..8178e526f5b95da0e0c71df2c1dbf7894c7f38ea GIT binary patch literal 18894 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 KoPMWg1pol~m~?>v literal 0 HcmV?d00001 diff --git a/module_common/src/main/res/drawable-xxxhdpi/label_upperleft_blue.9.png b/module_common/src/main/res/drawable-xxxhdpi/label_upperleft_blue.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd0bc524da8260b87b587a9bf52f7b87dffe498 GIT binary patch literal 17508 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 W$%82<>0|o<00005G!n=DZD2NDi6E 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 literal 0 HcmV?d00001 diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt index 3a6cfed4a1..e8530523e1 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt @@ -7,6 +7,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.common.entity.CommunityEntity import com.gh.gamecenter.common.entity.Display +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.common.entity.LinkEntity import com.gh.gamecenter.core.provider.* import com.gh.gamecenter.feature.HaloApp @@ -296,6 +297,9 @@ data class GameEntity( @SerializedName("recommend_tag") var recommendTag: String = "", + @SerializedName("icon_float") + var iconFloat: IconFloat? = null,//图标浮层 + // 专题id,用于曝光使用 var subjectId: String? = null, // 专题名字,用于曝光使用 @@ -930,6 +934,8 @@ class SimpleGame( var subtitleStyle: TagStyleEntity? = null, @SerializedName("advance_download") var advanceDownload: Boolean = false, + @SerializedName("icon_float") + var iconFloat: IconFloat? = null ) : Parcelable { @IgnoredOnParcel @@ -958,6 +964,7 @@ class SimpleGame( gameEntity.subtitle = subtitle ?: "" gameEntity.subtitleStyle = subtitleStyle gameEntity.advanceDownload = advanceDownload + gameEntity.iconFloat = iconFloat return gameEntity } @@ -967,6 +974,7 @@ class SimpleGame( gameEntity.mIcon = mIcon gameEntity.mRawIcon = mRawIcon gameEntity.iconSubscript = iconSubscript + gameEntity.iconFloat = iconFloat return gameEntity } } diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconUi.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconUi.kt index bf5b14c483..904d7ef8a2 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconUi.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconUi.kt @@ -1,27 +1,37 @@ package com.gh.gamecenter.feature.view import android.content.Context +import android.graphics.Color +import android.graphics.Typeface import android.util.AttributeSet +import android.view.Gravity import android.view.View +import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.core.content.ContextCompat import com.facebook.drawee.drawable.ScalingUtils import com.facebook.drawee.view.SimpleDraweeView import com.gh.gamecenter.common.R +import splitties.views.assignAndGetGeneratedId import splitties.views.dsl.constraintlayout.* -import splitties.views.dsl.core.Ui -import splitties.views.dsl.core.add +import splitties.views.dsl.core.* import splitties.views.dsl.idepreview.UiPreView +import splitties.views.existingOrNewId class GameIconUi(override val ctx: Context) : Ui { val gameIconIv: SimpleDraweeView val gameIconDecorationIv: SimpleDraweeView val borderView: View + val bottomLabelTv: TextView override val root: ConstraintLayout = constraintLayout { gameIconIv = getIv(ctx) gameIconDecorationIv = getIv(ctx) - borderView = View(ctx) + borderView = View(ctx).apply { + assignAndGetGeneratedId() + } + bottomLabelTv = initBottomLabelTv() add(gameIconIv, lParams(0, 0) { startOfParent() topOfParent() @@ -40,10 +50,31 @@ class GameIconUi(override val ctx: Context) : Ui { endToEndOf(gameIconIv) bottomToBottomOf(gameIconIv) }) + add(bottomLabelTv, lParams(0, 0) { + startOfParent() + endOfParent() + bottomOfParent() + }) + ConstraintSet().also { + it.clone(this) + it.setDimensionRatio(bottomLabelTv.existingOrNewId, "h,1000:275") + }.applyTo(this) + } + + private fun initBottomLabelTv() = textView { + assignAndGetGeneratedId() + setBackgroundResource(R.drawable.label_bottom) + setTextColor(Color.WHITE) + isSingleLine = true + typeface = Typeface.DEFAULT_BOLD + textSize = 10F + gravity = Gravity.BOTTOM.xor(Gravity.CENTER_HORIZONTAL) + visibility = View.GONE } private fun getIv(context: Context): SimpleDraweeView { return SimpleDraweeView(context).apply { + assignAndGetGeneratedId() hierarchy.setPlaceholderImage( ContextCompat.getDrawable(context, R.drawable.occupy), ScalingUtils.ScaleType.FIT_XY diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconView.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconView.kt index b9cbace81e..45ce6d83f3 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconView.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/view/GameIconView.kt @@ -2,23 +2,31 @@ package com.gh.gamecenter.feature.view import android.content.Context import android.graphics.Color +import android.graphics.Typeface import android.graphics.drawable.GradientDrawable import android.text.TextUtils import android.util.AttributeSet import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.TextView import androidx.annotation.ColorRes +import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.widget.ViewPager2 import com.facebook.drawee.generic.RoundingParams import com.facebook.drawee.view.SimpleDraweeView +import com.gh.gamecenter.common.entity.IconFloat import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.RadiusCardView import com.gh.gamecenter.core.utils.DisplayUtils import com.gh.gamecenter.feature.R import com.gh.gamecenter.feature.entity.GameEntity -import splitties.views.dsl.core.add -import splitties.views.dsl.core.lParams -import splitties.views.dsl.core.matchParent +import splitties.dimensions.dip +import splitties.views.dsl.core.* +import kotlin.math.abs -class GameIconView : RadiusCardView { +class GameIconView : FrameLayout { private var mCornerRadius = 0 private var mBorderColor = 0 @@ -26,9 +34,13 @@ class GameIconView : RadiusCardView { private var mBorderWidth = 1 private var mFadeDuration = -1 + private var mGameIconCv: RadiusCardView? = null private var mGameIconIv: SimpleDraweeView? = null private var mGameIconDecorationIv: SimpleDraweeView? = null private var mBorderView: View? = null + private var mTopLabelContainer: FrameLayout? = null + private var mTopLabelTv: TextView? = null + private var mBottomLabelTv: TextView? = null private var mIsRemoveCrevice = false constructor(context: Context) : super(context, null) { @@ -49,6 +61,7 @@ class GameIconView : RadiusCardView { fun initView(attrs: AttributeSet?) { val gameIconUi = GameIconUi(context) + mGameIconCv = RadiusCardView(context) if (attrs != null && !isInEditMode) { val ta = context.obtainStyledAttributes(attrs, R.styleable.GameIconView) @@ -64,15 +77,32 @@ class GameIconView : RadiusCardView { ta.recycle() } - add(gameIconUi.root, lParams(matchParent, matchParent) { }) + mGameIconCv?.add(gameIconUi.root, lParams(matchParent, matchParent) { }) + add(mGameIconCv!!, lParams(matchParent, matchParent) { }) mGameIconIv = gameIconUi.gameIconIv mGameIconDecorationIv = gameIconUi.gameIconDecorationIv mBorderView = gameIconUi.borderView + mBottomLabelTv = gameIconUi.bottomLabelTv mGameIconIv?.dimOnDarkMode() mGameIconDecorationIv?.dimOnDarkMode() + mTopLabelTv = textView { + setBackgroundResource(R.drawable.label_upperleft_blue) + setPadding(dip(6), dip(2), dip(6), 0) + setTextColor(Color.WHITE) + isSingleLine = true + typeface = Typeface.DEFAULT_BOLD + textSize = 10F + } + mTopLabelContainer = FrameLayout(context).apply { + visibility = View.GONE + add(mTopLabelTv!!, lParams(wrapContent, dip(24)) { }) + } + + add(mTopLabelContainer!!, lParams(DisplayUtils.getScreenWidth(), wrapContent) { }) + if (mFadeDuration != -1) { mGameIconIv?.hierarchy?.fadeDuration = mFadeDuration } @@ -81,23 +111,45 @@ class GameIconView : RadiusCardView { fun displayGameIcon(game: GameEntity) { if (!TextUtils.isEmpty(game.rawIcon)) { - displayGameIcon(game.rawIcon ?: "", game.iconSubscript) + displayGameIcon(game.rawIcon ?: "", game.iconSubscript, game.iconFloat) } else { - displayGameIcon(game.icon ?: "", null) + displayGameIcon(game.icon ?: "", null, game.iconFloat) } } - fun displayGameIcon(icon: String?, iconSubscript: String?) { - displayGameIcon(icon, iconSubscript, false) + fun displayGameIcon(icon: String?, iconSubscript: String?, iconFloat: IconFloat? = null) { + displayGameIcon(icon, iconSubscript, false, iconFloat) } - fun displayGameIcon(icon: String?, iconSubscript: String?, goneIfEmpty: Boolean = false) { + fun displayGameIcon( + icon: String?, + iconSubscript: String?, + goneIfEmpty: Boolean = false, + iconFloat: IconFloat? = null + ) { if (getTag(ImageUtils.TAG_TARGET_WIDTH) == null) { setTag(ImageUtils.TAG_TARGET_WIDTH, layoutParams.width) } mGameIconIv?.display(icon) - mGameIconDecorationIv?.display(iconSubscript, true) + if (iconFloat == null || (iconFloat.upperLeftText.isEmpty() && iconFloat.bottomText.isEmpty())) { + mGameIconDecorationIv?.visibility = View.VISIBLE + mTopLabelContainer?.visibility = View.GONE + mBottomLabelTv?.visibility = View.GONE + mGameIconDecorationIv?.display(iconSubscript, true) + } else { + mGameIconDecorationIv?.visibility = View.GONE + if (iconFloat.upperLeftText.isNotEmpty() && iconFloat.upperLeftColor.isNotEmpty()) { + mTopLabelContainer?.visibility = View.VISIBLE + mTopLabelTv?.text = iconFloat.upperLeftText + mTopLabelTv?.setBackgroundResource(if (iconFloat.upperLeftColor == "blue") R.drawable.label_upperleft_blue else R.drawable.label_upperleft_red) + mTopLabelTv?.setPadding(dip(6), dip(2), dip(6), 0) + } + if (iconFloat.bottomText.isNotEmpty()) { + mBottomLabelTv?.visibility = View.VISIBLE + mBottomLabelTv?.text = iconFloat.bottomText + } + } if (goneIfEmpty) { visibility = if (TextUtils.isEmpty(icon)) View.GONE else View.VISIBLE } @@ -116,6 +168,49 @@ class GameIconView : RadiusCardView { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) setBorder(w) + setIconFloat(w) + } + + private fun setIconFloat(width: Int) { + val ratio = width / SIZE_80.toFloat() + val topLabelMarginLeft = dip(-2) * ratio + val topLabelMarginTop = dip(-2) * ratio + val bottomLabelPaddingBottom = (dip(4) * ratio).toInt() + val offsetX = abs(topLabelMarginLeft) + val offsetY = abs(topLabelMarginTop) + + mTopLabelTv?.run { + pivotX = 0F + pivotY = 0F + scaleX = ratio + scaleY = ratio + } + mTopLabelContainer?.run { + layoutParams = (layoutParams as MarginLayoutParams).apply { + setMargins(topLabelMarginLeft.toInt(), topLabelMarginTop.toInt(), 0, 0) + } + } + mBottomLabelTv?.run { + textSize = ratio * 10F + setPadding(0, 0, 0, bottomLabelPaddingBottom) + } + setParentClip(this, offsetX, offsetY) + } + + private fun setParentClip(view: View, offsetX: Float, offsetY: Float) { + val viewParent = view.parent + if (viewParent != null && viewParent is ViewGroup) { + viewParent.clipChildren = false + if (viewParent.paddingLeft != 0 || viewParent.paddingTop != 0) { + viewParent.clipToPadding = false + } + if (view.x < offsetX || view.y < offsetY) { + val parentOffsetX = if (view.x < offsetX) offsetX - view.x else 0F + val parentOffsetY = if (view.y < offsetY) offsetY - view.y else 0F + if (viewParent.parent is RecyclerView || viewParent.parent is ViewPager || viewParent.parent is ViewPager2) return + setParentClip(viewParent, parentOffsetX, parentOffsetY) + } + } } private fun setBorder(width: Int) { @@ -125,8 +220,8 @@ class GameIconView : RadiusCardView { 0F } - setRadiusPx(cornerRadius, cornerRadius, cornerRadius, cornerRadius) - cardElevation = 0F + mGameIconCv?.setRadiusPx(cornerRadius, cornerRadius, cornerRadius, cornerRadius) + mGameIconCv?.cardElevation = 0F // 一些设备(没错,又是 vivo),代码设置 CardView 的 radius 无效(xml 设置有效) // 被迫再设置一次 SimpleDraweeView 的 radius :(