kvs = new ArrayList<>(Arrays.asList(arrayKv));
+ if (customPageTrackData != null) {
+ kvs.addAll(Arrays.asList(customPageTrackData.toKV()));
+ }
+
+ SensorsBridge.trackEventWithExposureSource("DownloadProcessBegin",
+ downloadExposureEvent.getSource(), kvs.toArray(new String[0])
);
//TODO remove
@@ -463,6 +489,7 @@ public class DownloadManager implements DownloadStatusListener {
SentryHelper.INSTANCE.onEvent("CLEAR_DELETED_TASK_ERROR", "exception_digest", e.getLocalizedMessage());
}
}
+
/**
* 添加一个下载任务
*
diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt
index acbe1a0d25..2b8f896bcc 100644
--- a/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt
+++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt
@@ -6,13 +6,13 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
-import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.callback.OnViewClickListener
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.lightgame.adapter.BaseRecyclerAdapter
class DownloadDialogAdapter(
diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt
index 77209b1cd5..60844b373e 100644
--- a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt
+++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt
@@ -7,7 +7,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.Config
-import com.gh.common.dialog.CertificationDialog
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.common.dialog.PackageCheckDialogFragment
import com.gh.common.util.*
@@ -343,33 +342,28 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
context as AppCompatActivity,
gameEntity
) {
- CertificationDialog.showCertificationDialog(
+ DialogUtils.checkDownload(
context,
- gameEntity
- ) {
- DialogUtils.checkDownload(
+ apkEntity.size,
+ gameEntity.id,
+ gameEntity.name,
+ gameEntity.categoryChinese
+ ) { isSubscribe ->
+ DownloadManager.createDownload(
context,
- apkEntity.size,
- gameEntity.id,
- gameEntity.name,
- gameEntity.categoryChinese
- ) { isSubscribe ->
- DownloadManager.createDownload(
- context,
- apkEntity,
- gameEntity,
- false,
- false,
- entrance,
- location,
- isSubscribe, traceEvent
- )
+ apkEntity,
+ gameEntity,
+ false,
+ false,
+ entrance,
+ location,
+ isSubscribe, traceEvent
+ )
- DeviceRemindDialog.showDeviceRemindDialog(
- context,
- gameEntity
- )
- }
+ DeviceRemindDialog.showDeviceRemindDialog(
+ context,
+ gameEntity
+ )
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java
index e0ad46b0b1..a54115e212 100644
--- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java
@@ -70,7 +70,7 @@ public class DownloadManagerActivity extends ToolBarActivity {
@Override
public boolean onMenuItemClick(MenuItem item) {
NewFlatLogUtils.logHaloFunManageShow("下载管理");
- DirectUtils.directToVGameDownload(this, false);
+ DirectUtils.directToVGameDownload(this, "下载管理", false);
return true;
}
diff --git a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt
index 3c2926e9b5..38c828fb3e 100644
--- a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt
@@ -8,11 +8,13 @@ import android.view.View
import com.gh.base.DownloadToolbarActivity
import com.gh.common.exposure.ExposureManager.log
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
+import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.toArrayList
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.GamePlatform
+import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
@@ -170,7 +172,12 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
@JvmStatic
- fun startGameDetailActivity(context: Context, gameId: String, entrance: String?, traceEvent: ExposureEvent?) {
+ fun startGameDetailActivity(
+ context: Context,
+ gameId: String,
+ entrance: String?,
+ traceEvent: ExposureEvent?
+ ) {
startGameDetailActivity(context, gameId, entrance, -1, traceEvent = traceEvent)
}
@@ -226,7 +233,8 @@ class GameDetailActivity : DownloadToolbarActivity() {
platformName: String? = null,
packageName: String? = null,
platforms: List? = null,
- traceEvent: ExposureEvent? = null
+ traceEvent: ExposureEvent? = null,
+ customPageTrackData: CustomPageTrackData? = null
) {
val bundle = Bundle()
@@ -280,6 +288,13 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
bundle.putString(EntranceConsts.KEY_GAMEID, gameId)
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
+ bundle.putParcelable(EntranceConsts.KEY_CUSTOM_PAGE_TRACK_DATA, customPageTrackData)
+ bundle.putString(EntranceConsts.KEY_LAST_PAGE_ID, GlobalActivityManager.getLastPageEntity().pageId)
+ bundle.putString(EntranceConsts.KEY_LAST_PAGE_NAME, GlobalActivityManager.getLastPageEntity().pageName)
+ bundle.putString(
+ EntranceConsts.KEY_LAST_PAGE_BUSINESS_ID,
+ GlobalActivityManager.getLastPageEntity().pageBusinessId
+ )
context.startActivity(
getTargetIntent(
context,
diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java
index 02b31a20af..32d4418e36 100644
--- a/app/src/main/java/com/gh/gamecenter/MainActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java
@@ -17,7 +17,6 @@ import static com.gh.gamecenter.common.utils.ExtensionsKt.observableToMain;
import static com.gh.gamecenter.login.utils.LoginHelper.WEIBO_SCOPE;
import android.annotation.SuppressLint;
-import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -48,6 +47,7 @@ import com.gh.common.constant.Config;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.history.HistoryDatabase;
import com.gh.common.history.HistoryHelper;
+import com.gh.common.prioritychain.GlobalPriorityChainHelper;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.AdHelper;
@@ -56,7 +56,6 @@ import com.gh.common.util.DataUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ErrorHelper;
-import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.PackageInstaller;
@@ -92,11 +91,9 @@ import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.StartupAdEntity;
-import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.utils.PlatformUtils;
-import com.gh.gamecenter.fragment.MainWrapperFragment;
-import com.gh.gamecenter.fragment.MainWrapperViewModel;
+import com.gh.gamecenter.home.custom.model.CustomPageShareRepository;
import com.gh.gamecenter.home.skip.PackageSkipActivity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
@@ -105,6 +102,9 @@ import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.room.AppDatabase;
import com.gh.gamecenter.room.dao.SimulatorGameDao;
+import com.gh.gamecenter.wrapper.MainWrapperFragment;
+import com.gh.gamecenter.wrapper.MainWrapperRepository;
+import com.gh.gamecenter.wrapper.MainWrapperViewModel;
import com.gh.vspace.VHelper;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.gson.JsonSyntaxException;
@@ -113,13 +113,11 @@ import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
-import com.lightgame.utils.AppManager;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.openapi.IWBAPI;
import com.sina.weibo.sdk.openapi.WBAPIFactory;
-import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
@@ -133,14 +131,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
-import kotlin.jvm.functions.Function1;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
@@ -148,9 +143,6 @@ import tv.danmaku.ijk.media.exo2.ExoSourceManager;
public class MainActivity extends BaseActivity {
- public static final String EB_SKIP_MAIN = "MainActivity";
- public static final String SWITCH_TO_COMMUNITY = "switch_to_community";
- public static final String SWITCH_TO_VIDEO = "switch_to_video";
public static final String SHOW_AD = "show_ad";
public static final int COUNTDOWN_AD = 100;
public static final int COUNTDOWN_MAX_COUNT = 3;
@@ -229,7 +221,7 @@ public class MainActivity extends BaseActivity {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手发生了闪退,建议安装到最新版本修复异常"
, "马上反馈", "马上安装修复",
() -> {
- DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "crash", true, "desc", null);
+ DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "", "crash", true, "desc", null);
return null;
},
() -> {
@@ -263,10 +255,6 @@ public class MainActivity extends BaseActivity {
ReservationRepository.refreshReservations();
- if (getIntent().getBooleanExtra(SWITCH_TO_VIDEO, false)) {
- handler.postDelayed(() -> mMainWrapperFragment.setCurrentItem(2), 800);
- }
-
// 跳转至其它页面
if (getIntent() != null
&& getIntent().getExtras() != null
@@ -300,7 +288,6 @@ public class MainActivity extends BaseActivity {
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
- HomePluggableHelper.activationFilterData();
// 启动app删除视频缓存文件
try {
@@ -414,15 +401,12 @@ public class MainActivity extends BaseActivity {
}
@Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
- int currentPageIndex = savedInstanceState.getInt(CURRENT_PAGE, -1);
- if (currentPageIndex >= 0) {
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, currentPageIndex));
- if (currentPageIndex == MainWrapperFragment.INDEX_VIDEO) {
- DisplayUtils.setLightStatusBar(this, false);
- }
+ int bottomTabPosition = savedInstanceState.getInt(CURRENT_PAGE, -1);
+ if (bottomTabPosition != -1) {
+ MainWrapperRepository.Companion.getInstance().sendSelectTabEvent(bottomTabPosition, -1);
}
}
}
@@ -453,6 +437,7 @@ public class MainActivity extends BaseActivity {
protected void onDestroy() {
super.onDestroy();
+ CustomPageShareRepository.Companion.getInstance().onClear();
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
handler.removeCallbacksAndMessages(null);
@@ -595,10 +580,12 @@ public class MainActivity extends BaseActivity {
ExtensionsKt.removeFromParent(startSdkAdIcpContainer, true);
}
- // 通知优先级高的弹窗可以显示了
- AppExecutor.getUiExecutor().execute(() -> {
- mMainWrapperFragment.showDialog();
- });
+ onSplashHidden();
+ }
+
+ private void onSplashHidden() {
+ // 通知全局弹窗可以进行显示
+ AppExecutor.getUiExecutor().execute(GlobalPriorityChainHelper.INSTANCE::start);
}
/**
@@ -747,8 +734,8 @@ public class MainActivity extends BaseActivity {
}
Utils.log(bundle);
- if (bundle.getInt(EntranceConsts.KEY_POSITION) != -1) {
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, bundle.getInt(EntranceConsts.KEY_POSITION)));
+ if (!TextUtils.isEmpty(bundle.getString(EntranceConsts.KEY_TYPE, ""))) {
+ MainWrapperRepository.Companion.getInstance().sendSelectTabEvent(bundle.getString(EntranceConsts.KEY_TYPE));
}
}
}, 500);
@@ -788,8 +775,6 @@ public class MainActivity extends BaseActivity {
} else {
toast("抱歉,暂未找到相关内容");
}
- LogUtils.uploadPackageSkip("external_jump", "进入游戏库", "", "");
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_GAME));
return true;
}
return false;
@@ -884,9 +869,8 @@ public class MainActivity extends BaseActivity {
protected void onSaveInstanceState(@NotNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
- outState.putInt(CURRENT_PAGE, mMainWrapperFragment.getCurrentItem());
if (mMainWrapperFragment != null) {
- outState.putInt(BaseFragment_ViewPager.ARGS_INDEX, mMainWrapperFragment.getCurrentItem());
+ outState.putInt(CURRENT_PAGE, mMainWrapperFragment.getCurrentItem());
}
}
@@ -914,10 +898,6 @@ public class MainActivity extends BaseActivity {
&& getIntent().getBooleanExtra(EntranceConsts.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
}
-
- if (getIntent().getBooleanExtra(SWITCH_TO_VIDEO, false)) {
- mMainWrapperFragment.setCurrentItem(2);
- }
}
// 连接上网络事件
@@ -948,25 +928,6 @@ public class MainActivity extends BaseActivity {
return "游戏首页";
}
- public static void skipToMainActivity(Context context, int position) {
- Activity activity = AppManager.getInstance().findActivity(MainActivity.class);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
- && activity != null && !activity.isDestroyed()) {
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, position));
- } else {
- Timer timer = new Timer();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, position));
- }
- }, 300);
- }
-
- Intent intent = MainActivity.getMainIntent(context);
- context.startActivity(intent);
- }
-
//需要提前初始化微博sdk,否则第一次分享或授权登录会失败
private void initWBSDK() {
IWBAPI mWBAPI = WBAPIFactory.createWBAPI(this);
diff --git a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
index 9761905478..9a43b48cd1 100644
--- a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt
@@ -116,10 +116,23 @@ open class SearchActivity : BaseActivity() {
}
protected open fun trackSearchPageShow(){
+ val bottomTab = intent.getStringExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME) ?: ""
+ val multiTabId = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_ID) ?: ""
+ val multiTabName = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_NAME) ?: ""
+ val customPageId = intent.getStringExtra(EntranceConsts.KEY_CUSTOM_PAGE_ID) ?: ""
+ val customPageName = intent.getStringExtra(EntranceConsts.KEY_CUSTOM_PAGE_NAME) ?: ""
+ val searchBoxPattern = intent.getStringExtra(EntranceConsts.KEY_SEARCH_BOX_PATTERN) ?: ""
+
SensorsBridge.trackSearchPageShow(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
- intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
+ intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: "",
+ bottomTab,
+ multiTabId,
+ multiTabName,
+ customPageId,
+ customPageName,
+ searchBoxPattern
)
}
@@ -362,12 +375,33 @@ open class SearchActivity : BaseActivity() {
hint: String,
entrance: String,
sourceEntrance: String
+ ): Intent = getIntent(context, searchImmediately, hint, entrance, sourceEntrance, "", "", "", "", "", "")
+
+ @JvmStatic
+ fun getIntent(
+ context: Context,
+ searchImmediately: Boolean,
+ hint: String,
+ entrance: String,
+ sourceEntrance: String,
+ bottomTab: String = "",
+ multiTabId: String = "",
+ multiTabName: String = "",
+ customPageId: String = "",
+ customPageName: String = "",
+ searchBoxPattern: String = ""
): Intent {
val intent = Intent(context, SearchActivity::class.java)
intent.putExtra(KEY_SEARCH_IMMEDIATELY, searchImmediately)
intent.putExtra(EntranceConsts.KEY_HINT, hint)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
intent.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
+ intent.putExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME, bottomTab)
+ intent.putExtra(EntranceConsts.KEY_MULTI_TAB_NAV_ID, multiTabId)
+ intent.putExtra(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, multiTabName)
+ intent.putExtra(EntranceConsts.KEY_CUSTOM_PAGE_ID, customPageId)
+ intent.putExtra(EntranceConsts.KEY_CUSTOM_PAGE_NAME, customPageName)
+ intent.putExtra(EntranceConsts.KEY_SEARCH_BOX_PATTERN, searchBoxPattern)
return intent
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/SkipActivity.java b/app/src/main/java/com/gh/gamecenter/SkipActivity.java
index e0b473257b..cc6e98b66f 100644
--- a/app/src/main/java/com/gh/gamecenter/SkipActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/SkipActivity.java
@@ -68,7 +68,6 @@ import com.gh.gamecenter.video.videomanager.VideoManagerActivity;
import com.gh.vspace.shortcut.OnCreateShortcutResult;
import com.gh.vspace.shortcut.ShortcutManager;
import com.gh.vspace.shortcut.ShortcutPermissionTipsDialog;
-import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
import com.muugi.shortcut.core.Executor;
@@ -145,7 +144,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToArticle(this, path, ENTRANCE_BROWSER);
break;
case HOST_GAME:
- DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
+ DirectUtils.directToGameDetail(this, path, "", ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
break;
case HOST_COLUMN:
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER, null, false);
@@ -171,17 +170,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), ENTRANCE_BROWSER);
break;
case HOST_COMMUNITY:
- // 把切换放到 MainActivity 处理
- if (HaloApp.getInstance().isRunningForeground) {
- intent = new Intent(this, MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(MainActivity.SWITCH_TO_COMMUNITY, true);
- } else {
- bundle = new Bundle();
- bundle.putBoolean(MainActivity.SWITCH_TO_COMMUNITY, true);
- intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
- }
- startActivity(intent);
+ DirectUtils.directToHomeCommunityTab(this);
break;
// 社区文章格式一
case "community.article":
@@ -254,17 +243,7 @@ public class SkipActivity extends BaseActivity {
TextUtils.isEmpty(sectionName) ? "" : sectionName, false, "");
break;
case HOST_VIDEO_STREAMING_HOME:
- // 把切换放到 MainActivity 处理
- if (HaloApp.getInstance().isRunningForeground) {
- intent = new Intent(this, MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true);
- } else {
- bundle = new Bundle();
- bundle.putBoolean(MainActivity.SWITCH_TO_VIDEO, true);
- intent = SplashScreenActivity.getSplashScreenIntent(this, bundle);
- }
- startActivity(intent);
+ DirectUtils.directToHomeVideoTab(this);
break;
case HOST_VIDEO_STREAMING_DESC:
DirectUtils.directToGameDetailVideoStreaming(this, path, ENTRANCE_BROWSER);
@@ -324,7 +303,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directCategoryDirectory(this, path, title, ENTRANCE_BROWSER, "浏览器");
break;
case HOST_COLUMN_COLLECTION:
- DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "", "", "", null);
+ DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "", "", "", "", null,false);
break;
case EntranceConsts.HOST_BLOCK:
name = uri.getQueryParameter("name");
@@ -397,8 +376,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToGameRatingDetail(this, uri.getQueryParameter(EntranceConsts.KEY_GAME_ID), uri.getQueryParameter(EntranceConsts.KEY_COMMENT_ID), ENTRANCE_BROWSER);
break;
case EntranceConsts.HOST_FORUM:
- position = uri.getQueryParameter("position");
- DirectUtils.directToForum(this, TextUtils.isEmpty(position) ? 0 : Integer.parseInt(position));
+ DirectUtils.directToHomeCommunityTab(this);
break;
case EntranceConsts.HOST_HELP_AND_FEEDBACK:
if ("vgame".equals(suggestionType)) {
@@ -419,7 +397,8 @@ public class SkipActivity extends BaseActivity {
JSONObject extJsonObject = new JSONObject(extJson);
String qqGameId = extJsonObject.optString("aid");
DirectUtils.directToQGameById(this, qqGameId);
- } catch (JSONException ignored) {}
+ } catch (JSONException ignored) {
+ }
break;
default:
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt
index 011a4bad7b..934f67c888 100644
--- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt
@@ -11,6 +11,9 @@ import android.preference.PreferenceManager
import android.view.KeyEvent
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
+import androidx.core.text.bold
+import androidx.core.text.buildSpannedString
+import androidx.core.text.color
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
@@ -78,25 +81,37 @@ class SplashScreenActivity : BaseActivity() {
if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
showPrivacyDialog()
} else {
+ val spanBuilder = buildSpannedString {
+ append("这个弹窗只会在右上角有环境标签的测试包出现" +
+ "\n进入应用以后还可以到关于我们页面长按应用图标重新选择")
+ bold {
+ color(R.color.text_theme.toColor(this@SplashScreenActivity)) {
+ append("\n点击这里进行预设置渠道")
+ }
+ }
+ }
+
// Test dex2oat
executeDex2OatInAdvance()
DialogHelper.showDialog(
- this,
- "选择接口环境",
- "这个弹窗只会在右上角有环境标签的测试包出现\n进入应用以后还可以到关于我们页面长按应用图标重新选择",
- "正式环境",
- "测试环境",
- {
+ context = this,
+ title ="选择环境",
+ content = spanBuilder,
+ confirmText = "正式环境",
+ cancelText = "测试环境",
+ confirmClickCallback = {
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, false)
showPrivacyDialog()
},
- {
+ cancelClickCallback = {
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, true)
showPrivacyDialog()
},
- false,
- "",
- ""
+ uiModificationCallback = {
+ it.contentTv.setOnClickListener {
+ EnvHelper.showChangeChannelDialog(this@SplashScreenActivity)
+ }
+ }
)
}
} else {
@@ -262,7 +277,6 @@ class SplashScreenActivity : BaseActivity() {
runOnIoThread {
mViewModel?.deviceDialogSetting()
mViewModel?.filterDetailTags()
- mViewModel?.authDialog()
mViewModel?.postMark(mIsNewForThisVersion)
mViewModel?.regulationTestStatus()
checkAndPostUsageStats()
diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenViewModel.kt b/app/src/main/java/com/gh/gamecenter/SplashScreenViewModel.kt
index 051157ee0e..9c0fb63e8d 100644
--- a/app/src/main/java/com/gh/gamecenter/SplashScreenViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/SplashScreenViewModel.kt
@@ -13,7 +13,6 @@ import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
-import com.gh.gamecenter.feature.entity.AuthDialogEntity
import com.gh.gamecenter.entity.DeviceDialogEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
@@ -77,18 +76,6 @@ class SplashScreenViewModel(application: Application) : AndroidViewModel(applica
})
}
- /**
- * 获取游戏实名认证弹窗
- */
- fun authDialog() {
- mApi.authDialog()
- .subscribe(object : Response?>() {
- override fun onResponse(response: List?) {
- super.onResponse(response)
- SPUtils.setString(Constants.SP_AUTH_DIALOG, GsonUtils.toJson(response))
- }
- })
- }
/**
* 判断新老用户
diff --git a/app/src/main/java/com/gh/gamecenter/ToolBoxActivity.java b/app/src/main/java/com/gh/gamecenter/ToolBoxActivity.java
deleted file mode 100644
index 97ed2b33ff..0000000000
--- a/app/src/main/java/com/gh/gamecenter/ToolBoxActivity.java
+++ /dev/null
@@ -1,283 +0,0 @@
-//package com.gh.gamecenter;
-//
-//import android.content.Context;
-//import android.content.Intent;
-//import android.os.Bundle;
-//import android.text.TextUtils;
-//import android.view.View;
-//import android.view.inputmethod.EditorInfo;
-//import android.widget.EditText;
-//import android.widget.LinearLayout;
-//import android.widget.TextView;
-//
-//import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
-//import com.gh.gamecenter.common.base.activity.ToolBarActivity;
-//import com.gh.common.util.EntranceUtils;
-//import com.gh.gamecenter.core.utils.MtaHelper;
-//import com.gh.gamecenter.common.utils.TextHelper;
-//import com.gh.gamecenter.core.utils.UrlFilterUtils;
-//import com.gh.gamecenter.common.view.VerticalItemDecoration;
-//import com.gh.gamecenter.adapter.ToolBoxRvAdapter;
-//import com.gh.gamecenter.common.entity.ToolBoxEntity;
-//import com.gh.gamecenter.retrofit.Response;
-//import com.gh.gamecenter.retrofit.RetrofitManager;
-//import com.gh.gamecenter.common.entity.SuggestType;
-//import com.google.android.material.appbar.AppBarLayout;
-//import com.lightgame.utils.Util_System_Keyboard;
-//import com.lightgame.utils.Utils;
-//
-//import java.util.List;
-//
-//import androidx.annotation.NonNull;
-//import androidx.annotation.Nullable;
-//import androidx.recyclerview.widget.LinearLayoutManager;
-//import androidx.recyclerview.widget.RecyclerView;
-//import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-//import butterknife.BindView;
-//import butterknife.OnClick;
-//import io.reactivex.android.schedulers.AndroidSchedulers;
-//import io.reactivex.schedulers.Schedulers;
-//
-///**
-// * Created by khy on 24/05/17.
-// */
-//
-//public class ToolBoxActivity extends ToolBarActivity implements SwipeRefreshLayout.OnRefreshListener, OnRequestCallBackListener {
-//
-// @BindView(R.id.et_search)
-// public EditText searchEt;
-// @BindView(R.id.tv_search)
-// public TextView searchTv;
-// @BindView(R.id.tv_back)
-// public View backTv;
-// @BindView(R.id.toolbox_appbar)
-// AppBarLayout mAppBar;
-// @BindView(R.id.toolbox_rv)
-// RecyclerView mToolboxRv;
-// @BindView(R.id.reuse_none_data)
-// LinearLayout mNoneData;
-// @BindView(R.id.reuse_tv_none_data)
-// TextView mNoneDataTv;
-// @BindView(R.id.reuse_no_connection)
-// LinearLayout mNoConnection;
-// @BindView(R.id.toolbox_refresh)
-// SwipeRefreshLayout mRefresh;
-// @BindView(R.id.reuse_ll_loading)
-// View mLoading;
-//
-// private LinearLayoutManager mLayoutManager;
-// private ToolBoxRvAdapter mRvAdapter;
-// private ToolBoxRvAdapter mNormalRvAdapter;
-//
-// private boolean mIsSearch; // 记录页面状态 搜索页面/普通页面
-// private String mSearchKey; // 记录搜索关键字
-//
-// Runnable runnable = () -> changeAdapter(true);
-//
-// @NonNull
-// public static Intent getIntent(Context context, String entrance) {
-// Intent intent = new Intent(context, ToolBoxActivity.class);
-// intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance);
-// return intent;
-// }
-//
-// @Override
-// protected int getLayoutId() {
-// return R.layout.activity_toolbox;
-// }
-//
-// @Override
-// protected void onCreate(Bundle savedInstanceState) {
-// super.onCreate(savedInstanceState);
-// setNavigationTitle("光环工具箱");
-//
-// mRefresh.setColorSchemeResources(R.color.theme);
-// mRefresh.setOnRefreshListener(this);
-//
-// // 跳转到工具箱 https://gitlab.ghzs.com/pm/halo-app-issues/issues/636
-// String gameId = getIntent().getStringExtra(EntranceUtils.KEY_GAMEID);
-// String targetUrl = getIntent().getStringExtra(EntranceUtils.KEY_URL);
-// if (!TextUtils.isEmpty(targetUrl) && !TextUtils.isEmpty(gameId)) {
-// findGameAndOpenItsToolboxWebview(gameId, targetUrl);
-// }
-//
-// mLayoutManager = new LinearLayoutManager(this);
-// mToolboxRv.setLayoutManager(mLayoutManager);
-// mRvAdapter = new ToolBoxRvAdapter(this, this, mIsSearch, mSearchKey);
-// mToolboxRv.addItemDecoration(new VerticalItemDecoration(this, 8, false));
-// mToolboxRv.setAdapter(mRvAdapter);
-//
-// mNormalRvAdapter = mRvAdapter;
-//
-// mToolboxRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
-// @Override
-// public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
-// super.onScrollStateChanged(recyclerView, newState);
-// if (newState == RecyclerView.SCROLL_STATE_IDLE && mLayoutManager.findLastVisibleItemPosition() + 1 == mRvAdapter
-// .getItemCount()) {
-// if (!mRvAdapter.isOver() && !mRvAdapter.isLoading() && !mRvAdapter.isNetworkError()) {
-// mRvAdapter.loadData();
-// }
-// }
-// }
-// });
-//
-// mAppBar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
-// if (verticalOffset == 0) {
-// mRefresh.setEnabled(true);
-// } else {
-// mRefresh.setEnabled(false);
-// }
-// int totalScrollRange = appBarLayout.getTotalScrollRange();
-// if (totalScrollRange == -verticalOffset) {
-// Util_System_Keyboard.hideSoftKeyboard(this);
-// }
-// });
-//
-// initSearch();
-// }
-//
-// private void findGameAndOpenItsToolboxWebview(String gameId, String url) {
-// RetrofitManager.getInstance()
-// .getApi()
-// .getGameToolBoxData(1, UrlFilterUtils.getFilterQuery("game_id", gameId))
-// .subscribeOn(Schedulers.io())
-// .observeOn(AndroidSchedulers.mainThread())
-// .subscribe(new Response>() {
-// @Override
-// public void onResponse(@Nullable List response) {
-// if (response == null) return;
-//
-// for (ToolBoxEntity toolbox : response) {
-// if (url.equals(toolbox.getUrl())) {
-// Intent intent = WebActivity.getWebByCollectionTools(ToolBoxActivity.this, toolbox, false);
-// startActivity(intent);
-// }
-// }
-// }
-// });
-// }
-//
-// private void initSearch() {
-// backTv.setOnClickListener(v -> search(false, ""));
-//
-// TextHelper.limitTheLengthOfEditText(searchEt, 20, () -> {
-// Utils.toast(this, "最多输入20字");
-// });
-//
-// searchTv.setOnClickListener(v -> {
-// MtaHelper.onEvent("我的光环_新", "工具箱", "点击搜索");
-// if (TextUtils.isEmpty(searchEt.getText().toString())) {
-// Utils.toast(this, R.string.search_hint);
-// return;
-// }
-// Util_System_Keyboard.hideSoftKeyboard(this,searchEt);
-// search(true, searchEt.getText().toString());
-// });
-//
-// searchEt.setOnFocusChangeListener((v, hasFocus) -> {
-// if (!hasFocus) {
-// Util_System_Keyboard.hideSoftKeyboard(this, searchEt);
-// }
-// });
-//
-// searchEt.setOnEditorActionListener((v, actionId, event) -> {
-// if (actionId == EditorInfo.IME_ACTION_SEARCH) {
-// searchTv.performClick();
-// }
-// return false;
-// });
-// }
-//
-//
-// @OnClick({R.id.reuse_no_connection, R.id.reuse_none_data})
-// public void onClick(View view) {
-// if (view.getId() == R.id.reuse_no_connection) {
-// mLoading.setVisibility(View.VISIBLE);
-// mNoConnection.setVisibility(View.GONE);
-// mLoading.postDelayed(runnable, 1000);
-// } else if (view.getId() == R.id.reuse_none_data) {
-// if (mIsSearch) {
-// // TODO反馈
-// MtaHelper.onEvent("我的光环_新", "工具箱", "点击反馈");
-// SuggestionActivity.startSuggestionActivity(this, SuggestType.functionSuggest, null, null);
-// }
-// }
-// }
-//
-// @Override
-// public void loadDone() {
-// mRefresh.setRefreshing(false);
-// mNoneData.setVisibility(View.GONE);
-// mNoConnection.setVisibility(View.GONE);
-// mLoading.setVisibility(View.GONE);
-// }
-//
-// @Override
-// public void loadDone(Object obj) {
-//
-// }
-//
-// @Override
-// public void loadEmpty() {
-// mRefresh.setRefreshing(false);
-// mNoneData.setVisibility(View.VISIBLE);
-// mNoConnection.setVisibility(View.GONE);
-// mLoading.setVisibility(View.GONE);
-// if (mIsSearch) {
-// mNoneDataTv.setText("未找到结果,点我反馈");
-// } else {
-// mNoneDataTv.setText(getResources().getString(R.string.game_empty));
-// }
-// }
-//
-// @Override
-// public void loadError() {
-// mRefresh.setRefreshing(false);
-// mNoneData.setVisibility(View.GONE);
-// mNoConnection.setVisibility(View.VISIBLE);
-// mLoading.setVisibility(View.GONE);
-// }
-//
-// @Override
-// public void onRefresh() {
-// mRefresh.postDelayed(runnable, 1000);
-// }
-//
-// public void search(boolean isSearch, String searchKey) {
-// if (mNoneData.getVisibility() == View.VISIBLE) {
-// mNoneData.setVisibility(View.GONE);
-// }
-// if (isSearch) {
-// mLoading.setVisibility(View.VISIBLE);
-// }
-// mIsSearch = isSearch;
-// mSearchKey = searchKey;
-// changeAdapter(false);
-// }
-//
-// private void changeAdapter(boolean isRefresh) {
-// if (mIsSearch) {
-// mRvAdapter = new ToolBoxRvAdapter(this, this, mIsSearch, mSearchKey);
-// } else {
-// if (mNormalRvAdapter != null && !isRefresh) {
-// mRvAdapter = mNormalRvAdapter;
-// } else {
-// mRvAdapter = new ToolBoxRvAdapter(this, this, mIsSearch, null);
-// mNormalRvAdapter = mRvAdapter;
-// }
-// }
-// mToolboxRv.setAdapter(mRvAdapter);
-//
-// if (mSearchKey != null) {
-// searchEt.setText(mSearchKey);
-// searchEt.setSelection(searchEt.getText().length());
-// }
-//
-// if (mIsSearch) {
-// backTv.setVisibility(View.VISIBLE);
-// } else {
-// backTv.setVisibility(View.GONE);
-// }
-// }
-//}
diff --git a/app/src/main/java/com/gh/gamecenter/adapter/GameNewsAdapter.java b/app/src/main/java/com/gh/gamecenter/adapter/GameNewsAdapter.java
index 13077a281f..82983259cd 100644
--- a/app/src/main/java/com/gh/gamecenter/adapter/GameNewsAdapter.java
+++ b/app/src/main/java/com/gh/gamecenter/adapter/GameNewsAdapter.java
@@ -12,25 +12,24 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import com.gh.common.constant.Config;
import com.gh.common.util.DataCollectionUtils;
-import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.common.util.NewsUtils;
-import com.gh.gamecenter.core.utils.StringUtils;
-import com.gh.gamecenter.common.utils.TextHelper;
-import com.gh.gamecenter.core.utils.UrlFilterUtils;
-import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.NewsSearchActivity;
import com.gh.gamecenter.R;
-import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.adapter.viewholder.GameNewsSearchViewHolder;
import com.gh.gamecenter.adapter.viewholder.GameNewsTypeListViewHolder;
import com.gh.gamecenter.adapter.viewholder.NewsTextViewHolder;
+import com.gh.gamecenter.common.retrofit.Response;
+import com.gh.gamecenter.common.utils.TextHelper;
+import com.gh.gamecenter.common.viewholder.FooterViewHolder;
+import com.gh.gamecenter.core.utils.DisplayUtils;
+import com.gh.gamecenter.core.utils.StringUtils;
+import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.databinding.GameNewsSearchItemBinding;
import com.gh.gamecenter.databinding.GameNewsTypeItemBinding;
import com.gh.gamecenter.databinding.NewsTextItemBinding;
import com.gh.gamecenter.feature.entity.NewsEntity;
-import com.gh.gamecenter.common.retrofit.Response;
+import com.gh.gamecenter.newsdetail.NewsDetailActivity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
@@ -110,7 +109,6 @@ public class GameNewsAdapter extends BaseRecyclerAdapter {
@Override
public List apply(List list) {
// 去除重复数据
- Config.filterPluginArticle(list);
return NewsUtils.removeDuplicateData(mNewsList, list);
}
})
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 9d13c8f3de..b2ee32acc2 100644
--- a/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java
+++ b/app/src/main/java/com/gh/gamecenter/adapter/MessageDetailAdapter.java
@@ -18,35 +18,35 @@ import com.gh.common.util.ConcernContentUtils;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DirectUtils;
-import com.gh.gamecenter.common.utils.ExtensionsKt;
-import com.gh.gamecenter.core.utils.DisplayUtils;
-import com.gh.gamecenter.common.constant.EntranceConsts;
-import com.gh.gamecenter.common.utils.ImageUtils;
-import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.common.util.NewsUtils;
-import com.gh.gamecenter.core.utils.NumberUtils;
-import com.gh.gamecenter.core.utils.StringUtils;
-import com.gh.gamecenter.common.utils.TextHelper;
-import com.gh.gamecenter.common.utils.TimestampUtils;
-import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.ShareCardActivity;
import com.gh.gamecenter.ShareCardPicActivity;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.adapter.viewholder.CommentHeadViewHolder;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
+import com.gh.gamecenter.common.constant.EntranceConsts;
+import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
+import com.gh.gamecenter.common.retrofit.OkHttpCache;
+import com.gh.gamecenter.common.retrofit.Response;
+import com.gh.gamecenter.common.utils.ExtensionsKt;
+import com.gh.gamecenter.common.utils.ImageUtils;
+import com.gh.gamecenter.common.utils.TextHelper;
+import com.gh.gamecenter.common.utils.TimestampUtils;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
-import com.gh.gamecenter.feature.databinding.NewsDigestItemBinding;
-import com.gh.gamecenter.feature.viewholder.NewsDigestViewHolder;
+import com.gh.gamecenter.core.utils.DisplayUtils;
+import com.gh.gamecenter.core.utils.MtaHelper;
+import com.gh.gamecenter.core.utils.NumberUtils;
+import com.gh.gamecenter.core.utils.StringUtils;
import com.gh.gamecenter.databinding.CommentHeadItemBinding;
+import com.gh.gamecenter.feature.databinding.NewsDigestItemBinding;
import com.gh.gamecenter.feature.entity.ArticleCommentParent;
import com.gh.gamecenter.feature.entity.CommentEntity;
import com.gh.gamecenter.feature.entity.ConcernEntity;
import com.gh.gamecenter.feature.eventbus.EBDeleteComment;
+import com.gh.gamecenter.feature.viewholder.NewsDigestViewHolder;
import com.gh.gamecenter.manager.VisitManager;
-import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
-import com.gh.gamecenter.common.retrofit.OkHttpCache;
-import com.gh.gamecenter.common.retrofit.Response;
+import com.gh.gamecenter.newsdetail.NewsDetailActivity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.kt b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.kt
index c01d91ccdb..ec8bdd7ba4 100644
--- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.kt
@@ -57,7 +57,7 @@ class DetailViewHolder(
val gameEntity: GameEntity,
val isNewsDetail: Boolean, // 新闻详情不显示下载的游戏名, 只显示下载状态
entrance: String?,
- name: String,
+ name: String?,
title: String?,
val traceEvent: ExposureEvent?,
val isSupportDualButton: Boolean = false // 是否支持双下载按钮,不支持的时候跟普通列表意义选用优先级高的那个来显示
@@ -104,7 +104,7 @@ class DetailViewHolder(
val localDownloadListener = OnDetailDownloadClickListener(
mViewHolder = this,
mEntrance = entrance,
- mName = name,
+ mName = name ?: "",
mTitle = title ?: "",
mAsVGame = false,
mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
@@ -114,7 +114,7 @@ class DetailViewHolder(
val vGameDownloadListener = OnDetailDownloadClickListener(
mViewHolder = this,
mEntrance = entrance,
- mName = name,
+ mName = name ?: "",
mTitle = title ?: "",
mAsVGame = true,
mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
@@ -615,7 +615,6 @@ class DetailViewHolder(
builder.addHandler(BrowserInstallHandler())
builder.addHandler(PackageCheckHandler())
builder.addHandler(DownloadDialogHelperHandler())
- builder.addHandler(CertificationHandler())
builder.addHandler(VersionNumberHandler())
builder.addHandler(LandPageAddressHandler())
builder.addHandler(OverseaDownloadHandler())
@@ -624,7 +623,6 @@ class DetailViewHolder(
download(asVGame, isSubscribe as Boolean)
}
} else {
- builder.addHandler(CertificationHandler())
builder.addHandler(VersionNumberHandler())
builder.setProcessEndCallback { _: Boolean?, _: Any? ->
DownloadDialog.showDownloadDialog(
diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt
index 1db46a235c..294909c3c7 100644
--- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt
@@ -19,4 +19,7 @@ class CommonCollectionDetailTwoItemViewHolder(val binding: CommonCollectionDetai
BaseRecyclerViewHolder(binding.root)
class CommonCollectionImageTextItemViewHolder(val binding: CommonCollectionImageTextItemBinding) :
+ BaseRecyclerViewHolder(binding.root)
+
+class CommonCollectionDetailTwoItemHorizontalViewHolder(val binding: CommonCollectionDetailTwoItemHorizontalCustomBinding) :
BaseRecyclerViewHolder(binding.root)
\ No newline at end of file
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 a2b7fd88c7..3e860dd334 100644
--- a/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/amway/AmwayAdapter.kt
@@ -272,12 +272,6 @@ class AmwayAdapter(
}
binding.commentContainer.setOnClickListener {
- val exposureSource = if (useAlternativeLayout) {
- arrayListOf(ExposureSource("新首页"), ExposureSource("安利墙"))
- } else {
- arrayListOf(ExposureSource("安利墙"))
- }.toJson()
-
val intent = RatingReplyActivity.getIntent(
context = context,
gameId = amway.game.id,
@@ -285,7 +279,7 @@ class AmwayAdapter(
comment = amway.comment,
commentId = amway.comment.id,
showKeyboardIfReplyListIsEmpty = false,
- exposureSource = exposureSource,
+ exposureSource = basicExposureSource.toJson(),
entrance = viewModel.entrance ?: "",
path = EntranceConsts.ENTRANCE_AMWAY
)
diff --git a/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt b/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt
index 6a391b3be1..aca54d13c7 100644
--- a/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt
@@ -4,13 +4,14 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
-import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.ExposureListener
+import com.gh.common.iinterface.ISearchToolbarTab
import com.gh.common.util.DialogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.xapk.XapkInstaller
@@ -35,7 +36,6 @@ import com.gh.gamecenter.databinding.FragmentAmwayBinding
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
-import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
@@ -54,9 +54,9 @@ class AmwayFragment : LazyListFragment() {
private var mAdapter: AmwayAdapter? = null
- private var mIsFromMainWrapper = false
private var mUseAlternativeLayout = false
private var mIsCollapsed = false
+ private var mTabIndex = -1
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
@@ -73,9 +73,9 @@ class AmwayFragment : LazyListFragment() {
}
override fun onCreate(savedInstanceState: Bundle?) {
- mUseAlternativeLayout = arguments?.getBoolean(EntranceConsts.KEY_IS_HOME, false) ?: false
- mIsFromMainWrapper = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, false) ?: false
+ mTabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
super.onCreate(savedInstanceState)
+ mUseAlternativeLayout = mIsFromTabWrapper
}
override fun getStubLayoutId() = R.layout.fragment_stub
@@ -142,8 +142,8 @@ class AmwayFragment : LazyListFragment() {
override fun provideListAdapter(): ListAdapter<*> {
if (mAdapter == null) {
val basicExposureSource = arrayListOf().apply {
- arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE)?.let {
- add(it)
+ arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)?.let {
+ addAll(it)
}
add(ExposureSource("安利墙", ""))
}
@@ -156,24 +156,28 @@ class AmwayFragment : LazyListFragment() {
override fun isAutomaticLoad() = false
private fun initDefaultLayout() {
+ val statusBarHeight = DisplayUtils.getStatusBarHeight(context?.resources)
mDefaultBinding?.run {
nightMaskView.goneIf(!mIsDarkModeOn)
// toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
// [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
- (toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin = insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
+ (toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
+ }
+ if (mIsFromMainWrapper) {
+ (toolbar.layoutParams as MarginLayoutParams).topMargin = statusBarHeight
}
- val collapsingTrigger = 66F.dip2px() + DisplayUtils.getStatusBarHeight(context?.resources)
+ val collapsingTrigger = 66F.dip2px() + statusBarHeight
toolbar.setNavigationOnClickListener { requireActivity().finish() }
collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
collapsingToolbar.scrimShownAction = {
mIsCollapsed = it
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && it)
+ updateStatusBar()
if (it) {
titleTv.alpha = 1F
titleTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_black))
@@ -181,7 +185,7 @@ class AmwayFragment : LazyListFragment() {
titleTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
}
- if (mIsFromMainWrapper) {
+ if (mIsFromMainWrapper || mIsFromTabWrapper) {
toolbar.navigationIcon = null
} else {
toolbar.setNavigationIcon(if (it) R.drawable.ic_bar_back else R.drawable.ic_toolbar_back_white)
@@ -207,11 +211,6 @@ class AmwayFragment : LazyListFragment() {
mListRefresh?.isEnabled = absOffset <= 2
}
- if (mIsFromMainWrapper) {
- fab.layoutParams = (fab.layoutParams as MarginLayoutParams).apply {
- setMargins(0, 0, 14F.dip2px(), 72F.dip2px())
- }
- }
fab.setOnClickListener {
MtaHelper.onEvent("发表评论", "进入", "上墙")
ifLogin("安利墙") {
@@ -224,7 +223,7 @@ class AmwayFragment : LazyListFragment() {
mListRefresh?.setProgressViewOffset(
false,
0,
- 118F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)
+ 118F.dip2px() + statusBarHeight
)
mSkeletonScreen =
Skeleton.bind(mDefaultBinding?.skeletonPlaceholder).shimmer(false).load(R.layout.fragment_amway_skeleton)
@@ -244,14 +243,7 @@ class AmwayFragment : LazyListFragment() {
mAlternativeBinding?.listRv?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
- val scrollY = recyclerView.computeVerticalScrollOffset()
- mAlternativeBinding?.headerContainer?.translationY = -scrollY.toFloat()
- if (parentFragment is HomeSearchToolWrapperFragment && isSupportVisible) {
- (parentFragment as HomeSearchToolWrapperFragment).onScrollChanged(
- mAlternativeBinding?.headerContainer?.measuredHeight ?: 0,
- scrollY
- )
- }
+ onScrollChanged()
}
})
@@ -274,7 +266,12 @@ class AmwayFragment : LazyListFragment() {
mElapsedHelper.resetCounting()
mElapsedHelper.resumeCounting()
- if (mIsFromMainWrapper) {
+ updateStatusBar()
+ }
+
+ private fun updateStatusBar() {
+ if (!mIsFromTabWrapper && isSupportVisible) {
+ DisplayUtils.transparentStatusBar(requireActivity())
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
}
}
@@ -330,17 +327,16 @@ class AmwayFragment : LazyListFragment() {
}
}
- fun onScrollChanged() {
- if (parentFragment is HomeSearchToolWrapperFragment) {
- val scrollY = mAlternativeBinding?.listRv?.computeVerticalScrollOffset()
- if (scrollY != null) {
- mAlternativeBinding?.headerContainer?.translationY = -scrollY.toFloat()
- if (parentFragment is HomeSearchToolWrapperFragment && isSupportVisible) {
- (parentFragment as HomeSearchToolWrapperFragment).onScrollChanged(
- mAlternativeBinding?.headerContainer?.measuredHeight ?: 0,
- scrollY
- )
- }
+ fun onScrollChanged(isDarkModeChanged: Boolean = false) {
+ val scrollY = mAlternativeBinding?.listRv?.computeVerticalScrollOffset()
+ if (scrollY != null) {
+ mAlternativeBinding?.headerContainer?.translationY = -scrollY.toFloat()
+ if (mTabIndex == (parentFragment as? ISearchToolbarTab)?.getCurrentTabIndex()) {
+ (parentFragment as ISearchToolbarTab).onScrollChanged(
+ mAlternativeBinding?.headerContainer?.measuredHeight ?: 0,
+ scrollY,
+ isDarkModeChanged
+ )
}
}
}
@@ -355,15 +351,13 @@ class AmwayFragment : LazyListFragment() {
mAlternativeBinding?.secondBackground?.goneIf(mIsDarkModeOn)
mAlternativeBinding?.topBackgroundView?.goneIf(mIsDarkModeOn)
mAlternativeBinding?.listRefresh?.setBackgroundColor(R.color.ui_background.toColor(requireContext()))
- onScrollChanged()
+ onScrollChanged(true)
} else {
mDefaultBinding?.nightMaskView?.goneIf(!mIsDarkModeOn)
mDefaultBinding?.appbar?.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
mDefaultBinding?.collapsingToolbar?.setContentScrimColor(R.color.ui_surface.toColor(requireContext()))
mDefaultBinding?.listRefresh?.setBackgroundColor(R.color.ui_background.toColor(requireContext()))
}
- if (mIsFromMainWrapper) {
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
- }
+ updateStatusBar()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt
index 4c4079e867..12a21b0f36 100644
--- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt
+++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt
@@ -12,7 +12,6 @@ class CategoryV2Activity : DownloadToolbarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setToolbarMenu(R.menu.menu_search)
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
}
diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt
index 3874614a3f..3a3f658e53 100644
--- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt
@@ -24,13 +24,13 @@ import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.FragmentCategoryBinding
import com.gh.gamecenter.entity.CategoryEntity
import com.gh.gamecenter.entity.SidebarsEntity
-import com.gh.gamecenter.fragment.HomeSearchToolWrapperViewModel
+import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
class CategoryV2Fragment : LazyFragment() {
private var mBinding: FragmentCategoryBinding? = null
private var mViewModel: CategoryV2ViewModel? = null
- private var mHomeViewModel: HomeSearchToolWrapperViewModel? = null
+ private var mHomeViewModel: SearchToolbarTabWrapperViewModel? = null
private var mEntity: SidebarsEntity? = null
private var mSpecialCatalogFragment: SpecialCatalogFragment? = null
private var mCategoryV2ListFragment: CategoryV2ListFragment? = null
@@ -68,8 +68,10 @@ class CategoryV2Fragment : LazyFragment() {
// 除了这里以外,下面还有一个判断是否为首页 tab 栏的赋值
mViewModel?.entrance = if (mEntrance.contains("首页")) "首页" else "板块"
- if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true) {
- mHomeViewModel = viewModelProviderFromParent()
+
+ val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
+ if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true && multiTabNavId.isNotEmpty()) {
+ mHomeViewModel = viewModelProviderFromParent(SearchToolbarTabWrapperViewModel.Factory(multiTabNavId, ""), multiTabNavId)
mViewModel?.entrance = "首页Tab栏"
}
mViewModel?.logAppearance()
@@ -79,7 +81,7 @@ class CategoryV2Fragment : LazyFragment() {
override fun initRealView() {
super.initRealView()
-
+ initMenu(R.menu.menu_search)
setNavigationTitle(mCategoryTitle)
mBinding?.run {
@@ -491,6 +493,7 @@ class CategoryV2Fragment : LazyFragment() {
override fun onDarkModeChanged() {
super.onDarkModeChanged()
+ getItemMenu(R.id.menu_search)?.setIcon(R.drawable.ic_column_search)
mBinding?.categoryRv?.adapter?.run {
mBinding?.categoryRv?.recycledViewPool?.clear()
notifyItemRangeChanged(0, itemCount)
diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt
index 5def4b0595..e1474d6a46 100644
--- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt
@@ -242,7 +242,7 @@ class CategoryV2ListAdapter(
binding.run {
gameIconView.displayGameIcon(gameEntity)
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
- BindingAdapters.setGameName(gameName, gameEntity, false, null)
+ BindingAdapters.setGameName(gameName, gameEntity, false)
BindingAdapters.setGameTags(labelList, gameEntity)
gameRating.setDrawableStart(if (gameEntity.commentCount > 3) R.drawable.game_horizontal_rating.toDrawable() else null)
gameRating.text = if (gameEntity.commentCount > 3) {
diff --git a/app/src/main/java/com/gh/gamecenter/collection/ArticleFragment.java b/app/src/main/java/com/gh/gamecenter/collection/ArticleFragment.java
index e2cce7726b..162db65d26 100644
--- a/app/src/main/java/com/gh/gamecenter/collection/ArticleFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/collection/ArticleFragment.java
@@ -10,18 +10,18 @@ import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DataCollectionUtils;
-import com.gh.gamecenter.common.utils.DialogHelper;
-import com.gh.gamecenter.common.constant.EntranceConsts;
-import com.gh.gamecenter.common.view.CustomDividerItemDecoration;
-import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.common.baselist.ListAdapter;
import com.gh.gamecenter.common.baselist.ListFragment;
import com.gh.gamecenter.common.baselist.LoadType;
-import com.gh.gamecenter.feature.entity.NewsEntity;
+import com.gh.gamecenter.common.constant.EntranceConsts;
+import com.gh.gamecenter.common.utils.DialogHelper;
+import com.gh.gamecenter.common.view.CustomDividerItemDecoration;
import com.gh.gamecenter.eventbus.EBCollectionChanged;
+import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.history.IBatchDelete;
import com.gh.gamecenter.history.ManageOption;
+import com.gh.gamecenter.newsdetail.NewsDetailActivity;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
diff --git a/app/src/main/java/com/gh/gamecenter/collection/ToolsFragment.java b/app/src/main/java/com/gh/gamecenter/collection/ToolsFragment.java
index ffc24f91f5..6f8383e4fe 100644
--- a/app/src/main/java/com/gh/gamecenter/collection/ToolsFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/collection/ToolsFragment.java
@@ -11,8 +11,6 @@ import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.util.CollectionUtils;
-import com.gh.gamecenter.common.view.CustomDividerItemDecoration;
-import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.baselist.ListAdapter;
@@ -20,8 +18,10 @@ import com.gh.gamecenter.common.baselist.ListFragment;
import com.gh.gamecenter.common.baselist.LoadType;
import com.gh.gamecenter.common.baselist.NormalListViewModel;
import com.gh.gamecenter.common.entity.ToolBoxEntity;
+import com.gh.gamecenter.common.view.CustomDividerItemDecoration;
import com.gh.gamecenter.eventbus.EBCollectionChanged;
import com.gh.gamecenter.login.user.UserManager;
+import com.gh.gamecenter.newsdetail.NewsDetailActivity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.greenrobot.eventbus.Subscribe;
diff --git a/app/src/main/java/com/gh/gamecenter/discovery/DiscoveryAdapter.kt b/app/src/main/java/com/gh/gamecenter/discovery/DiscoveryAdapter.kt
index 6ae91ff9ee..e9b73530d5 100644
--- a/app/src/main/java/com/gh/gamecenter/discovery/DiscoveryAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/discovery/DiscoveryAdapter.kt
@@ -14,7 +14,6 @@ import com.gh.common.util.HomeBottomBarHelper
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.BlockActivity
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
@@ -33,15 +32,11 @@ import com.gh.gamecenter.discovery.DiscoveryFragment.Companion.INTERESTED_GAME_R
import com.gh.gamecenter.discovery.interestedgame.InterestedGameActivity
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
import com.gh.gamecenter.eventbus.EBDownloadStatus
-import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
-import com.gh.gamecenter.fragment.MainWrapperFragment
-import com.gh.gamecenter.fragment.MainWrapperRepository
import com.lightgame.download.DownloadEntity
-import org.greenrobot.eventbus.EventBus
class DiscoveryAdapter(
context: Context,
@@ -220,14 +215,8 @@ class DiscoveryAdapter(
}
}
recommendIv.setOnClickListener {
- val navBar = MainWrapperRepository.getInstance().getGameNavBarLiveData().value
- if (navBar == null || mContext is DiscoveryActivity) {
- val blockData = HomeBottomBarHelper.getDefaultGameBarData()
- mContext.startActivity(BlockActivity.getIntent(mContext, blockData, mBaseExposureSource, mEntrance))
- } else {
- EventBus.getDefault()
- .post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_GAME))
- }
+ val blockData = HomeBottomBarHelper.getDefaultGameBarData()
+ mContext.startActivity(BlockActivity.getIntent(mContext, blockData, mBaseExposureSource, mEntrance))
NewFlatLogUtils.logDiscoverPageJumpGamesLibraries()
}
}
@@ -319,7 +308,7 @@ class DiscoveryAdapter(
gameIconView.displayGameIcon(gameEntity)
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
- BindingAdapters.setGameName(gameName, gameEntity, false, null)
+ BindingAdapters.setGameName(gameName, gameEntity, false)
gameRating.setDrawableStart(if (gameEntity.commentCount > 3) R.drawable.game_horizontal_rating.toDrawable() else null)
gameRating.text = if (gameEntity.commentCount > 3) {
if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
diff --git a/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt b/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt
index c84698befc..0b052fc8ba 100644
--- a/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt
@@ -27,6 +27,7 @@ import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
import com.gh.gamecenter.common.constant.Constants
+import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBMiPush
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.DisplayUtils
@@ -87,7 +88,16 @@ class DownloadFragment : BaseFragment_TabLayout() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- SensorsBridge.trackDownloadManagerEnter()
+ SensorsBridge.trackDownloadManagerEnter(
+ mEntrance,
+ arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_GAME_COLUMN_ID, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_GAME_COLUMN_NAME, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_ID, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: "",
+ arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
+ )
mPermanentInactivePluggableApkList = HomePluggableHelper.getPermanentInactivePluggablePackage()
}
diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java
index b0a88bacf7..ec62756029 100644
--- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java
@@ -14,25 +14,26 @@ import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import com.gh.common.util.DirectUtils;
import com.gh.common.xapk.XapkDialogHelper;
-import com.gh.gamecenter.common.base.fragment.BaseFragment;
-import com.gh.gamecenter.common.utils.DialogHelper;
-import com.gh.gamecenter.common.constant.EntranceConsts;
-import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.common.xapk.XapkInstaller;
import com.gh.common.xapk.XapkUnzipStatus;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.R;
+import com.gh.gamecenter.common.base.fragment.BaseFragment;
+import com.gh.gamecenter.common.constant.EntranceConsts;
+import com.gh.gamecenter.common.eventbus.EBMiPush;
+import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
+import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.databinding.DownloadmanagerBinding;
import com.gh.gamecenter.eventbus.EBDownloadChanged;
-import com.gh.gamecenter.common.eventbus.EBMiPush;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.eventbus.EBUISwitch;
-import com.gh.gamecenter.fragment.MainWrapperFragment;
+import com.gh.gamecenter.wrapper.MainWrapperFragment;
import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadConfig;
import com.lightgame.download.DownloadEntity;
@@ -238,7 +239,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
mBinding.reuseNoneData.reuseNoneDataDescTv.setText(getString(R.string.game_no_data_desc));
mBinding.reuseNoneData.reuseResetLoadTv.setText("去首页看看");
mBinding.reuseNoneData.reuseResetLoadTv.setVisibility(View.VISIBLE);
- mBinding.reuseNoneData.reuseResetLoadTv.setOnClickListener(v -> MainActivity.skipToMainActivity(getActivity(), MainWrapperFragment.INDEX_HOME));
+ mBinding.reuseNoneData.reuseResetLoadTv.setOnClickListener(v -> DirectUtils.directToHomeDefaultTab(getActivity()));
mBinding.downloadingHintContainer.setOnClickListener(v -> mBinding.downloadmanagerRvShow.scrollToPosition(adapter.getItemCount() - 1));
mBinding.downloadmanagerRvShow.setHasFixedSize(true);
diff --git a/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt
index 76070878c6..117efebb89 100644
--- a/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt
@@ -120,7 +120,6 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
for (entity in gameList) {
if (entity.id == id) {
val newEntity = entity.copy()
- newEntity.isLibaoExists = entity.isLibaoExists
// 下载管理不显示镜像游戏,不然会有奇怪的问题
if (entity.shouldUseMirrorInfo()) {
diff --git a/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragment.kt b/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragment.kt
index d0bf80da9b..fffd2b2b84 100644
--- a/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/download/NewInstalledGameFragment.kt
@@ -8,6 +8,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
+import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
@@ -20,16 +21,15 @@ import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.core.utils.DisplayUtils
-import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentMyGameBinding
-import com.gh.gamecenter.feature.entity.GameEntity
-import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
-import com.gh.gamecenter.fragment.MainWrapperFragment
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.entity.GameInstall
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
+import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
@@ -143,7 +143,7 @@ class NewInstalledGameFragment : ToolbarFragment() {
mBinding.reuseNoneData.reuseNoneDataDescTv.text = getString(R.string.game_no_data_desc)
mBinding.reuseNoneData.reuseResetLoadTv.text = "去首页看看"
mBinding.reuseNoneData.reuseResetLoadTv.setOnClickListener {
- MainActivity.skipToMainActivity(requireContext(), MainWrapperFragment.INDEX_HOME)
+ DirectUtils.directToHomeDefaultTab(requireContext())
}
mBinding.run {
@@ -163,7 +163,7 @@ class NewInstalledGameFragment : ToolbarFragment() {
reuseNoneData.reuseNoneDataTv.text = getString(R.string.game_no_data)
reuseNoneData.reuseNoneDataDescTv.text = getString(R.string.game_no_data_desc)
reuseNoneData.reuseResetLoadTv.setOnClickListener {
- MainActivity.skipToMainActivity(activity, MainWrapperFragment.INDEX_HOME)
+ DirectUtils.directToHomeDefaultTab(requireContext())
}
}
}
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 66e86698eb..fb39ecc2cd 100644
--- a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameAdapter.kt
@@ -10,18 +10,23 @@ import androidx.core.view.setPadding
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.IExposable
-import com.gh.common.util.*
+import com.gh.common.util.DialogUtils
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.PackageInstaller
+import com.gh.common.util.PackageLauncher
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
-import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
+import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
-import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.CurrentActivityHolder
-import com.gh.gamecenter.databinding.*
+import com.gh.gamecenter.databinding.ItemUpdatableGameBinding
+import com.gh.gamecenter.databinding.ItemUpdatableGameHeaderBinding
+import com.gh.gamecenter.databinding.ItemUpdatableOtherGameHintBinding
+import com.gh.gamecenter.databinding.LayoutPopupOptionItemBinding
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.exposure.ExposureEvent
@@ -188,6 +193,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
DirectUtils.directToGameDetail(
context = context,
id = update.id,
+ name = update.name ?: "",
entrance = mViewModel.entrance,
traceEvent = update.exposureEvent
)
diff --git a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameFragment.kt b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameFragment.kt
index e76230f4d9..325122bd3c 100644
--- a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameFragment.kt
@@ -2,6 +2,7 @@ package com.gh.gamecenter.download
import android.view.View
import com.gh.common.exposure.ExposureListener
+import com.gh.common.util.DirectUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
@@ -14,9 +15,9 @@ import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentGameUpdatableBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
-import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
+import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
@@ -119,7 +120,7 @@ class UpdatableGameFragment : LazyFragment() {
noDataContainer.reuseNoneDataDescTv.text = getString(R.string.game_no_data_desc)
noDataContainer.reuseResetLoadTv.text = "去首页看看"
noDataContainer.reuseResetLoadTv.setOnClickListener {
- MainActivity.skipToMainActivity(activity, MainWrapperFragment.INDEX_HOME)
+ DirectUtils.directToHomeDefaultTab(requireContext())
}
}
}
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 4a0cba2049..74a3c8c517 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/AmwayCommentEntity.kt
@@ -28,8 +28,6 @@ data class AmwayCommentEntity(
var iconSubscript: String? = "",
@SerializedName("name")
private var mName: String,
- @SerializedName("name_suffix")
- var nameSuffix: String? = "",
@SerializedName(value = "new_tag_style")
var tag: List? = arrayListOf(),
@SerializedName("new_star")
@@ -48,7 +46,7 @@ data class AmwayCommentEntity(
@IgnoredOnParcel
val name: String?
- get() = mName.removeSuffix(".") + (nameSuffix ?: "")
+ get() = mName.removeSuffix(".")
fun toGameEntity(): GameEntity {
val gameEntity = GameEntity()
diff --git a/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt b/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt
new file mode 100644
index 0000000000..ed32f2f834
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt
@@ -0,0 +1,67 @@
+package com.gh.gamecenter.entity
+
+import android.os.Parcelable
+import androidx.annotation.DrawableRes
+import com.gh.common.util.ViewPagerFragmentHelper
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.google.gson.annotations.SerializedName
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class BottomTab(
+ @SerializedName("_id")
+ val id: String = "",
+ val name: String = "",
+ @SerializedName("icon_select")
+ val iconSelect: String = "", // 选中图片
+ @SerializedName("icon_unselect")
+ val iconUnselect: String = "", // 未选中图片
+ @DrawableRes
+ val iconSelector: Int = 0, // 本地字段
+ @SerializedName("js_code")
+ val jsCode: String = "", // js代码
+ val link: LinkEntity? = null, // 通用链接
+ @SerializedName("search_style")
+ val searchStyle: SearchStyle = SearchStyle(), // 搜索样式
+ @SerializedName("is_default_page")
+ var default: Boolean = false, // 是否为默认显示页
+ var isTransparentStyle: Boolean = false // 本地字段,透明底部Tab
+): Parcelable {
+ @Parcelize
+ data class SearchStyle(
+ @SerializedName("style_type")
+ var styleType: String = STYLE_TWO_LINES, // 样式类型(two_lines:搜索栏与顶部tab分为两行、apposition:搜索栏与顶部tab同一行)
+ @SerializedName("search_type")
+ var searchType: String = TYPE_HALO_GAME, // 搜索类型(halo_game:光环游戏、qq_mini_game:QQ小游戏、bbs:论坛)
+ ): Parcelable {
+ companion object {
+ const val STYLE_TWO_LINES = "two_lines"
+ const val STYLE_APPOSITION = "apposition"
+ const val TYPE_HALO_GAME = "halo_game"
+ const val TYPE_QQ_MINI_GAME = "qq_mini_game"
+ const val TYPE_BBS = "bbs"
+ }
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as BottomTab
+ // 只对比链接类型和id、搜索样式判断是否相同
+ if (link?.type != other.link?.type) return false
+ if (link?.link == other.link?.link) return false
+ return searchStyle == other.searchStyle
+ }
+
+ override fun hashCode(): Int {
+ var result = link?.type?.hashCode() ?: 0
+ result = 31 * result + (link?.link?.hashCode() ?: 0)
+ result = 31 * result + searchStyle.hashCode()
+ // 除我的光环页面外,增加计算底部tab id的HashCode
+ if (link?.type != ViewPagerFragmentHelper.TYPE_MY_HALO) {
+ result = 31 * result + id.hashCode()
+ }
+ return result
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/CommonCollectionEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/CommonCollectionEntity.kt
index 00091f28c1..4782fc953f 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/CommonCollectionEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/CommonCollectionEntity.kt
@@ -11,13 +11,28 @@ data class CommonCollectionEntity(
val type: String = "",
val style: String = "",
val more: Int = 0,
+ val layout: Int = -1, // 对应自定义页面的layout样式
@SerializedName("home_page_style")
val homePageStyle: String = "horizontal_sliding", //首页样式 (横排滑动:horizontal_sliding 竖排一行两个:1-2)
@SerializedName("vertical_line")
val verticalLine: String = "", // 竖排时才有数据,代表竖排行数控制
@SerializedName("common_collection_content")
val collectionList: MutableList = mutableListOf()
-)
+) {
+ val layoutChinese: String
+ get() = when (layout) {
+ 0 -> "轮播banner"
+ 1 -> "导航栏"
+ 2 -> "金刚区"
+ 3 -> "横向滑动banner"
+ 4 -> "双列banner"
+ 5 -> "横排竖式卡片"
+ 6 -> "双列竖式卡片"
+ 7 -> "竖式图文列表"
+ 8 -> "横排图文列表"
+ else -> ""
+ }
+}
@Parcelize
data class CommonCollectionContentEntity(
diff --git a/app/src/main/java/com/gh/gamecenter/entity/DataUnionEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/DataUnionEntity.kt
new file mode 100644
index 0000000000..b9ba84ddf9
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/DataUnionEntity.kt
@@ -0,0 +1,13 @@
+package com.gh.gamecenter.entity
+
+import com.gh.gamecenter.home.custom.model.CustomPageData
+import com.google.gson.annotations.SerializedName
+
+data class DataUnionEntity(
+ @SerializedName("bottom_tab")
+ val bottomTab: List = listOf(), // 底部tab
+ @SerializedName("multi_tab_nav")
+ val multiTabNav: MultiTabNav? = null, // 多tab导航页(当默认页为【多tab导航数据】时才有此字段数据)
+ @SerializedName("custom_page")
+ val customPage: CustomPageData? = null, // 自定义页面相关信息(当默认页为【自定义页面】时才有此字段数据】)
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameVideoInfo.kt b/app/src/main/java/com/gh/gamecenter/entity/GameVideoInfo.kt
index 3a6aba1521..69b1a35eb1 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/GameVideoInfo.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/GameVideoInfo.kt
@@ -9,8 +9,6 @@ class GameVideoInfo(
val gameName: String = "",
@SerializedName("game_icon")
val gameIcon: String = "",
- @SerializedName("name_suffix")
- var nameSuffix: String? = null,
@SerializedName("video_count")
val videoCount: Int = 0,
@SerializedName("vote_count")
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 b192cc8f48..f19bb9fdd1 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HistoryGameEntity.kt
@@ -43,8 +43,6 @@ data class HistoryGameEntity(
gameEntity.subtitleStyle = subtitleStyle
gameEntity.name = name
gameEntity.tagStyle = tagStyle
- gameEntity.isLibaoExists = isLibaoExist
- gameEntity.setTag(tag)
return gameEntity
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt
index c60d9a35e4..8edcd1ea59 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt
@@ -16,5 +16,5 @@ class HomeDataEntity(
@SerializedName("home_sub_slide")
val homeSubSlide: ArrayList = arrayListOf(),
@SerializedName("home_push")
- var homePush: HomePush? = null
+ var homePush: PullDownPush? = null
)
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeItemTestV2Entity.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeItemTestV2Entity.kt
index 685f420967..6cc75bba71 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomeItemTestV2Entity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomeItemTestV2Entity.kt
@@ -34,9 +34,9 @@ data class HomeItemTestV2Entity(
@SerializedName("start_id")
val startId: String = "",
@SerializedName("start_point")
- val startPoint: Map = mapOf(), // key 时间轴名称,value 当前时间轴第一个游戏id
+ private val _startPoint: Map = mapOf(), // key 时间轴名称,value 当前时间轴第一个游戏id
@SerializedName("data_count")
- val dataCount: Map = mapOf(), //key 时间轴名称,value 当前时间轴所包含的游戏数量
+ private val _dataCount: Map = mapOf(), //key 时间轴名称,value 当前时间轴所包含的游戏数量
@SerializedName("time_type")
val timeType: String = "",
@SerializedName("recommend_left_surplus_num") //首页推荐左侧剩余游戏数量
@@ -46,7 +46,39 @@ data class HomeItemTestV2Entity(
// 用来判断是不是下拉刷新
@Expose(serialize = false, deserialize = false)
var isRefresh: Boolean = true
-) : Parcelable
+) : Parcelable {
+
+ val dataCount: List
+ get() {
+ val dataCountList = arrayListOf()
+ // 需要将 推荐 类型的数据放在第一位
+ _dataCount.forEach { (key, value) ->
+ if (timeType == TIME_TYPE_RECOMMEND && key == TIME_TYPE_RECOMMEND) {
+ dataCountList.add(0, DataCount(key, value))
+ } else {
+ dataCountList.add(DataCount(key, value))
+ }
+ }
+ return dataCountList
+ }
+
+ val startPoint: List
+ get() {
+ val startPointList = arrayListOf()
+ _startPoint.forEach { (key, value) ->
+ if (timeType == TIME_TYPE_RECOMMEND && key == TIME_TYPE_RECOMMEND) {
+ startPointList.add(0, StartPoint(key, value))
+ } else {
+ startPointList.add(StartPoint(key, value))
+ }
+ }
+ return startPointList
+ }
+
+ companion object {
+ private const val TIME_TYPE_RECOMMEND = "recommend"
+ }
+}
@Keep
@Entity
@@ -100,3 +132,13 @@ data class GameDataWrapper(
"gameName = ${gameData?.name})"
}
}
+
+data class DataCount(
+ val timeType: String,
+ val count: Int
+)
+
+data class StartPoint(
+ val timeType: String,
+ val id: String
+)
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomePluggableFilterEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/HomePluggableFilterEntity.kt
index 6aadbaa5f1..f31e600e61 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomePluggableFilterEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomePluggableFilterEntity.kt
@@ -9,6 +9,6 @@ import androidx.room.PrimaryKey
class HomePluggableFilterEntity(
@PrimaryKey
val pkgName: String,
- val tag: String, // gameVersion or never
+ var tag: String, // gameVersion or never
var active: Boolean // 是否可用
)
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeRecommend.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeRecommend.kt
index d93c22f395..f609055d05 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomeRecommend.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomeRecommend.kt
@@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
+import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
@@ -15,18 +16,26 @@ data class HomeRecommend(
val icon: String = "",
val name: String = "",
val display: Display = Display(),
+ @SerializedName("image")
+ private val _image: String? = null,
+ @SerializedName("link_community")
+ private val community: CommunityEntity? = null,
// 绑定的曝光实体
var exposureEvent: ExposureEvent? = null,
) {
+ val image: String
+ get() = _image ?: ""
+
fun transformLinkEntity(): LinkEntity {
return LinkEntity(
name = name,
type = linkType,
display = display,
link = linkId,
- text = linkText
+ text = linkText,
+ community = community
)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeSlide.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeSlide.kt
index 12a88f429c..ee4688db92 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomeSlide.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomeSlide.kt
@@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
+import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
@@ -19,7 +20,9 @@ data class HomeSlide(
val title: String = "",
val text: String = "",
@SerializedName("placeholder_color")
- val placeholderColor: String = "#5C9599"
+ val placeholderColor: String = "#5C9599",
+ @SerializedName("link_community")
+ val community: CommunityEntity? = null
) {
fun transformLinkEntity(): LinkEntity {
@@ -27,7 +30,8 @@ data class HomeSlide(
name = title,
type = linkType,
link = linkId,
- text = linkText
+ text = linkText,
+ community = community
)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeSubSlide.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeSubSlide.kt
index 10a8f98fa0..dfd4fd6598 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomeSubSlide.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/HomeSubSlide.kt
@@ -28,7 +28,9 @@ data class HomeSubSlide(
val cardData: CardData = CardData(),
val image: String = "",
val title: String = "",
- var sequence: Int = -1 // 本地字段
+ // 本地字段
+ var sequence: Int = -1,
+ var repeatCount: Int = -1
) {
fun toLinkEntity(): LinkEntity {
return if (linkType.isNotEmpty()) {
diff --git a/app/src/main/java/com/gh/gamecenter/entity/MultiTabNav.kt b/app/src/main/java/com/gh/gamecenter/entity/MultiTabNav.kt
new file mode 100644
index 0000000000..f0b7c22538
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/MultiTabNav.kt
@@ -0,0 +1,40 @@
+package com.gh.gamecenter.entity
+
+import android.graphics.Color
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.google.gson.annotations.SerializedName
+
+data class MultiTabNav(
+ @SerializedName("_id")
+ val id: String = "",
+ val title: String = "",
+ @SerializedName("link_multi_tab_nav")
+ val linkMultiTabNav: List = ArrayList()
+) {
+ data class LinkMultiTabNav(
+ @SerializedName("_id")
+ val id: String = "",
+ val name: String = "",
+ val img: String = "",
+ @SerializedName("tab_show_img")
+ var showImgOnSelected: Boolean? = false, // 选中时是否显示图片
+ @SerializedName("is_default_page")
+ var default: Boolean = false, // 是否为默认显示页
+ val link: LinkEntity? = null, // 通用链接
+
+ // 本地字段
+ var style: TabStyle = TabStyle(),
+ var showPullDownPush: Boolean = false,
+ var exposureEvent: ExposureEvent? = null, // 绑定的曝光实体
+ ) {
+ data class TabStyle(
+ var useLightStyle: Boolean = false,
+ var primaryColor: Int = Color.WHITE,
+ var offsetRatio: Float = 0F,
+ var currentSelectColor: Int = 0,
+ var isSlideBackgroundColorEnable: Boolean = false, // 是否启用首页轮播图背景颜色
+ var isSlideBackgroundColorShow: Boolean = false, // 是否正在显示首页轮播图背景颜色
+ )
+ }
+}
\ No newline at end of file
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 51839b56ba..6926dad8e2 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt
@@ -235,8 +235,6 @@ data class PersonalHistoryEntity(
val id: String = "",
@SerializedName("name")
private var mName: String = "",
- @SerializedName("name_suffix")
- val nameSuffix: String = "",
val icon: String = "",
@SerializedName(value = "new_tag_style")
diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomePush.kt b/app/src/main/java/com/gh/gamecenter/entity/PullDownPush.kt
similarity index 64%
rename from app/src/main/java/com/gh/gamecenter/entity/HomePush.kt
rename to app/src/main/java/com/gh/gamecenter/entity/PullDownPush.kt
index 01de6872c5..05c0f74a6b 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/HomePush.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/PullDownPush.kt
@@ -3,7 +3,7 @@ package com.gh.gamecenter.entity
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
-data class HomePush(
+data class PullDownPush(
@SerializedName("_id")
val id: String = "",
@SerializedName("pop_switch")
@@ -13,6 +13,9 @@ data class HomePush(
val imgUrl: String = "",
val video: Video? = null,
val game: GameEntity? = null,
+ var isSlideBackgroundColorEnable: Boolean = false, // 本地字段,是否启用首页轮播图背景颜色
+ var customPageId: String = "", // 本地字段,自定义页面ID
+ var customPageName: String = "", // 本地字段,自定义页面名称
)
data class Video(
diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt
index 46483f6a75..b748e232bc 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt
@@ -2,6 +2,8 @@ package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.feature.entity.GameSubjectData
+import com.gh.gamecenter.home.custom.model.CustomPageItem
+import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
@Parcelize
@@ -15,8 +17,8 @@ class SubjectData(
var filter: String = "", // Filter: 类型(分类)
var tagType: String? = "", // 游戏Item 标签类型
var briefStyle: String = "",
- var showSuffix: Boolean = true,
var isQQMiniGame: Boolean = false,
+ var subjectStyle: String = "",
var requireUpdateSetting: Boolean = false, // 多专题页面需要专题页面自行获取专题配置
var isAdData: Boolean = false,
@@ -24,6 +26,10 @@ class SubjectData(
var codeId: String = "" // 广告CODE_ID(本地字段),不为空时为广告专题
) : Parcelable, Cloneable {
+ @IgnoredOnParcel
+ val subjectStyleChinese: String
+ get() = CustomPageItem.subjectTypeToComponentStyle[subjectStyle] ?: ""
+
fun deepCopy(): SubjectData {
return super.clone() as SubjectData
}
@@ -34,7 +40,6 @@ class SubjectData(
name = subjectName,
isOrder = isOrder ?: false,
briefStyle = briefStyle,
- isShowSuffix = showSuffix,
tag = tagType
)
}
diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt
index 02b7c6462c..eb585b5dfa 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt
@@ -9,6 +9,8 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
+import kotlin.math.max
+import kotlin.math.min
/**
* Created by LGT on 2016/7/1.
@@ -32,7 +34,8 @@ data class SubjectEntity(
@SerializedName("relation_column_id")
var relatedColumnId: String? = null,
var style: String? = "", // 值为 "top" 时表示此专题(合集)为排行榜 https://gitlab.ghzs.com/pm/halo-app-issues/issues/699
- val list: Int = 0,
+ @SerializedName("list")
+ private val _list: Int? = null,
@SerializedName("common_collection_content")
var commonCollectionList: MutableList? = null,
@SerializedName("home_page_style")
@@ -48,8 +51,6 @@ data class SubjectEntity(
@SerializedName("show_name")
var showName: Boolean = true, // 是否显示“专题名字”,true、false
- @SerializedName("show_suffix")
- var showSuffix: Boolean = true, // 是否显示”游戏后缀“,true、false
@SerializedName("type_style")
var typeStyle: String = "", // 横屏样式,不显示(default)、评分(star)、备注(remark)
@SerializedName("brief_style")
@@ -101,7 +102,10 @@ data class SubjectEntity(
@SerializedName("is_qq_column")
var isQQColumn: Boolean = false,
- var explain: String = "" // 游戏单合集说明
+ var explain: String = "", // 游戏单合集说明
+
+ @SerializedName("show_star")
+ private val _showStar: Boolean? = null
) : Parcelable {
@IgnoredOnParcel
@@ -111,10 +115,13 @@ data class SubjectEntity(
mData = value
}
+ val showStar: Boolean
+ get() = _showStar ?: false
+
fun getFilterName(): String {
- if (!TextUtils.isEmpty(name) && !Config.isShowPlugin()) {
- name = name?.replace("插件", "游戏")
- }
return if (name == null) "" else name!!
}
+
+ val list: Int
+ get() = max(min(_list ?: 0, data?.size ?: 0), 1)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectSettingEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectSettingEntity.kt
index 8fc7a3fec0..980b2071b9 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/SubjectSettingEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectSettingEntity.kt
@@ -16,8 +16,6 @@ class SubjectSettingEntity(
var filter: String = "", // rows: off/on
var order: Boolean = false, // 是否显示序号
- @SerializedName("show_suffix")
- var showSuffix: Boolean = true,
@SerializedName("brief_style")
var briefStyle: String = "",
@@ -28,6 +26,8 @@ class SubjectSettingEntity(
var filterOptions: List = ArrayList(), // 过滤选项,推荐、最新、评分、更新
@SerializedName("ad_icon_active")
var adIconActive: Boolean = false,
+ @SerializedName("column_style")
+ var columnStyle: String = "", // 对应自定义页面的专题样式
) : Parcelable {
@Parcelize
class TypeEntity(
diff --git a/app/src/main/java/com/gh/gamecenter/entity/VideoEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/VideoEntity.kt
index b44062980a..a4d7283e1d 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/VideoEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/VideoEntity.kt
@@ -25,8 +25,6 @@ open class VideoEntity(
val gameId: String = "",
@SerializedName("game_name")
private var mGameName: String = "",
- @SerializedName("name_suffix")
- var nameSuffix: String? = null,
@SerializedName("game_icon")
val gameIcon: String = "",
@SerializedName("category_id")
@@ -73,7 +71,7 @@ open class VideoEntity(
@IgnoredOnParcel
val gameName: String
- get() = mGameName.removeSuffix(".") + (nameSuffix ?: "")
+ get() = mGameName.removeSuffix(".")
fun getThumb(): String {
val configProvider = ARouter.getInstance().build(RouteConsts.provider.config).navigation() as? IConfigProvider
diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBSkip.java b/app/src/main/java/com/gh/gamecenter/eventbus/EBSkip.java
index c44408d178..f4878835a8 100644
--- a/app/src/main/java/com/gh/gamecenter/eventbus/EBSkip.java
+++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBSkip.java
@@ -7,12 +7,18 @@ public class EBSkip {
private String type;
private int currentItem;
+ private String linkType;
public EBSkip(String type, int currentItem) {
this.type = type;
this.currentItem = currentItem;
}
+ public EBSkip(String type, String linkType) {
+ this.type = type;
+ this.linkType = linkType;
+ }
+
public String getType() {
return type;
}
@@ -21,4 +27,8 @@ public class EBSkip {
return currentItem;
}
+ public String getLinkType() {
+ return linkType;
+ }
+
}
diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBUISwitch.java b/app/src/main/java/com/gh/gamecenter/eventbus/EBUISwitch.java
index e92733b39e..8fcc198e55 100644
--- a/app/src/main/java/com/gh/gamecenter/eventbus/EBUISwitch.java
+++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBUISwitch.java
@@ -4,12 +4,18 @@ public class EBUISwitch {
private String from;
private int position;
+ private String linkType;
public EBUISwitch(String from, int position) {
this.position = position;
this.from = from;
}
+ public EBUISwitch(String from, String linkType) {
+ this.linkType = linkType;
+ this.from = from;
+ }
+
public int getPosition() {
return position;
}
@@ -26,4 +32,11 @@ public class EBUISwitch {
this.from = from;
}
+ public String getLinkType() {
+ return linkType;
+ }
+
+ public void setLinkType(String linkType) {
+ this.linkType = linkType;
+ }
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
index 411bb078fb..45a1c18d4b 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
@@ -16,12 +16,12 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.MD5Utils
-import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
+import com.gh.gamecenter.databinding.FragmentForumArticleAskListBinding
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBUserFollow
-import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.feature.entity.AnswerEntity
+import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import org.greenrobot.eventbus.Subscribe
@@ -32,7 +32,7 @@ class ForumArticleAskListFragment : LazyListFragment
- (mBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin = insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
+ if (!mIsFromTabWrapper) {
+ ViewCompat.setOnApplyWindowInsetsListener(mBinding.forumAppbar) { _, insets ->
+ (mBinding.toolbar.layoutParams as MarginLayoutParams).topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
+ }
+ }
+ if (mIsFromMainWrapper) {
+ (mBinding.toolbar.layoutParams as MarginLayoutParams).topMargin = DisplayUtils.getStatusBarHeight(requireContext().resources)
}
-
mBinding.toolbar.setNavigationOnClickListener {
NewLogUtils.logForumDetailEnterOrClick("click_forum_detail_return", mBbsId, mBbsType)
requireActivity().finish()
@@ -382,7 +347,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
false
) == true
) mEntrance else "论坛详情页点击"
- com.gh.common.util.NewFlatLogUtils.logClickBBSDetailGameZoneTab(
+ NewFlatLogUtils.logClickBBSDetailGameZoneTab(
mBbsId,
entrance,
mForumDetail?.zone?.link ?: ""
@@ -440,6 +405,60 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
updateTabStyle(tab, true)
}
})
+
+ mViewModel?.answerLiveData?.observeNonNull(viewLifecycleOwner) {
+ insertDataToAllTab(it)
+ }
+ mViewModel?.forumDetail?.observe(this) {
+ mSkeleton.hide()
+ mBinding.reuseLoading.reuseLlLoading.visibility = View.GONE
+ if (it.status == Status.SUCCESS) {
+ mBinding.communityEdit.visibility = View.VISIBLE
+ mBinding.forumContainer.visibility = View.VISIBLE
+ mBinding.reuseNoConnection.reuseNoConnection.visibility = View.GONE
+ if (it.data != null) {
+ mForumDetail = it.data
+ mBbsType = if (it.data!!.type == "official_bbs") "综合论坛" else "游戏论坛"
+ val userId = UserManager.getInstance().userId
+ NewLogUtils.logForumDetailEnterOrClick(
+ "view_forum_detail",
+ mBbsId,
+ mBbsType,
+ userId,
+ entrance = if (mEntrance.contains("游戏详情")) "游戏详情页" else "论坛tab页"
+ )
+ mBaseHandler.postDelayed({
+ SensorsBridge.trackEvent(
+ "ViewForum",
+ "bbs_id",
+ mBbsId,
+ "forum_name",
+ mForumDetail?.name ?: "",
+ "bbs_type",
+ mBbsType
+ )
+ }, 3000)
+ initUI()
+ }
+ } else {
+ mBinding.communityEdit.visibility = View.GONE
+ mBinding.forumContainer.visibility = View.GONE
+ if (it.exception != null && it.exception!!.code() == 404) {
+ mBinding.reuseNoneData.reuseNoneDataTv.text = "内容不见了~"
+ mBinding.reuseNoneData.reuseNoneDataDescTv.text = "先去看看其它的内容吧"
+ mBinding.reuseNoneData.reuseNoneDataIv.setImageResource(R.drawable.ic_data_load_exception)
+ mBinding.reuseNoneData.reuseNoneData.visibility = View.VISIBLE
+ mBinding.reuseNoConnection.reuseNoConnection.visibility = View.GONE
+ ToastUtils.showToast("内容可能已被删除")
+ } else {
+ mBinding.reuseNoneData.reuseNoneData.visibility = View.GONE
+ mBinding.reuseNoConnection.reuseNoConnection.visibility = View.VISIBLE
+ }
+ }
+ }
+ mViewModel?.statusEntity?.observeNonNull(this) {
+ mStatus = it
+ }
}
override fun onFragmentResume() {
@@ -555,12 +574,6 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
}
private fun initUI() {
- if (mIsFromMainWrapper) {
- mBinding.communityEdit.layoutParams = (mBinding.communityEdit.layoutParams as MarginLayoutParams).apply {
- setMargins(0, 0, 12F.dip2px(), 74F.dip2px())
- }
- mBinding.titleContainer.setPadding(21F.dip2px(), 0, 0, 0)
- }
mForumDetail?.apply {
mBinding.forumTopMaskContainer.goneIf(background.isEmpty())
mBinding.forumDefaultBackground.goneIf(background.isNotEmpty())
@@ -579,8 +592,9 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat)
mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat)
}
- if (mIsFromMainWrapper) {
+ if (mIsFromMainWrapper || mIsFromTabWrapper) {
mBinding.toolbar.navigationIcon = null
+ mBinding.titleContainer.setPadding(21F.dip2px(), 0, 0, 0)
} else {
mBinding.toolbar.setNavigationIcon(if (!mIsDarkModeOn) R.drawable.ic_bar_back else R.drawable.ic_bar_back_light)
}
@@ -673,7 +687,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
) else null
)
mBinding.sectionMoreIv.setOnClickListener {
- com.gh.common.util.NewFlatLogUtils.logClickMoreSection()
+ NewFlatLogUtils.logClickMoreSection()
showSectionsPopupWindow()
}
@@ -724,7 +738,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
val location = IntArray(2)
moderatorTv.getLocationOnScreen(location)
moderatorGuideContainer.layoutParams =
- (moderatorGuideContainer.layoutParams as ViewGroup.MarginLayoutParams).apply {
+ (moderatorGuideContainer.layoutParams as MarginLayoutParams).apply {
leftMargin = location[0] - 16F.dip2px()
}
moderatorGuideContainer.alpha = 0F
@@ -764,7 +778,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
ForumOrUserSearchActivity.getIntent(
requireContext(),
mBbsId,
- "论坛详情",
+ ENTRANCE,
SOURCE_ENTRANCE,
mForumDetail?.name ?: ""
)
@@ -918,7 +932,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
)
}
mBinding.gameDetailTv.setOnClickListener {
- com.gh.common.util.NewFlatLogUtils.logClickBBSDetailGameDetail()
+ NewFlatLogUtils.logClickBBSDetailGameDetail()
GameDetailActivity.startGameDetailActivity(
requireContext(), mForumDetail?.game?.id
?: "", "(论坛详情)"
@@ -940,13 +954,18 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
if (isToolbarWhite) R.color.white else R.color.transparent
)
)
- DisplayUtils.setStatusBarColor(
- requireActivity(),
- if (isToolbarWhite) R.color.white else R.color.transparent
- )
+ if (!mIsFromTabWrapper && isSupportVisible) {
+ DisplayUtils.setStatusBarColor(
+ requireActivity(),
+ if (isToolbarWhite) R.color.white else R.color.transparent
+ )
+ DisplayUtils.setLightStatusBar(requireActivity(), isToolbarWhite)
+ }
+
if (isToolbarWhite) {
- DisplayUtils.setLightStatusBar(requireActivity(), true)
- if (!mIsFromMainWrapper) mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
+ if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
+ }
mBinding.searchIv.setImageDrawable(
ContextCompat.getDrawable(
requireContext(),
@@ -954,8 +973,9 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
)
)
} else {
- DisplayUtils.setLightStatusBar(requireActivity(), false)
- if (!mIsFromMainWrapper) mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ }
mBinding.searchIv.setImageDrawable(
ContextCompat.getDrawable(
requireContext(),
@@ -980,7 +1000,9 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
requireActivity(),
if (isToolbarWhite) R.color.black else R.color.transparent
)
- if (!mIsFromMainWrapper) mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ }
mBinding.searchIv.setImageDrawable(
ContextCompat.getDrawable(
requireContext(),
@@ -1335,5 +1357,6 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
var TOP_CONTENT_TOP_MARGIN = 8F.dip2px()
const val SOURCE_ENTRANCE = "论坛"
+ const val ENTRANCE = "论坛详情"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityActivity.kt
new file mode 100644
index 0000000000..7f2c306516
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityActivity.kt
@@ -0,0 +1,28 @@
+package com.gh.gamecenter.forum.home
+
+import android.os.Bundle
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
+import com.gh.gamecenter.R
+import com.gh.gamecenter.common.base.activity.BaseActivity
+import com.gh.gamecenter.common.constant.EntranceConsts.IS_DETAIL_PAGE
+import com.gh.gamecenter.video.detail.HomeVideoFragment
+
+class CommunityActivity : BaseActivity() {
+
+ override fun getLayoutId(): Int = R.layout.activity_community
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val extras = intent.extras
+ extras?.putBoolean(IS_DETAIL_PAGE, true)
+ val fragment =
+ supportFragmentManager.findFragmentByTag(CommunityHomeFragment::class.java.name) as? CommunityHomeFragment
+ ?: CommunityHomeFragment().with(extras)
+
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.layout_activity_content, fragment, CommunityHomeFragment::class.java.name)
+ .commitNowAllowingStateLoss()
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt
index e6f6b92a7e..0e51b0a975 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt
@@ -21,12 +21,14 @@ import com.gh.common.browse.withLifecycle
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
+import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
+import com.gh.gamecenter.common.constant.EntranceConsts.IS_DETAIL_PAGE
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.AvatarBorderView
@@ -39,12 +41,9 @@ import com.gh.gamecenter.databinding.LayoutCommunityHomeVideoGuideBinding
import com.gh.gamecenter.databinding.TabItemCommunityBinding
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.eventbus.EBTypeChange
-import com.gh.gamecenter.eventbus.EBUISwitch
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
-import com.gh.gamecenter.fragment.MainWrapperFragment
-import com.gh.gamecenter.fragment.MainWrapperViewModel
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.qa.article.detail.ArticleDetailWebCacheManager
@@ -53,6 +52,7 @@ import com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
+import com.gh.gamecenter.wrapper.MainWrapperViewModel
import com.google.android.material.tabs.TabLayout
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.Subscribe
@@ -70,7 +70,8 @@ class CommunityHomeFragment : LazyFragment() {
private var mTabList = arrayListOf()
private var mDefaultSelectedTab = -1
private var mNavigationBitmap: Bitmap? = null
- private var mShowVideo = false
+ private var mShowVideo = true
+ private var mBottomTabId = ""
private val browseTimer = BrowseTimer()
.withLifecycle(this)
@@ -88,7 +89,6 @@ class CommunityHomeFragment : LazyFragment() {
override fun onFragmentFirstVisible() {
-
ArticleDetailWebCacheManager.init(requireContext().applicationContext)
mViewModel = viewModelProvider()
@@ -106,9 +106,7 @@ class CommunityHomeFragment : LazyFragment() {
insertDataToRecommendTab(it)
}
- mMainWrapperViewModel?.videoNavBar?.observe(this) {
- mShowVideo = it?.type != "video_stream"
- mBinding?.searchContainer?.goneIf(mShowVideo)
+ mMainWrapperViewModel?.bottomTabListLiveData?.observe(this) { tabList ->
mBinding?.videoAndSearchContainer?.goneIf(!mShowVideo) {
val decorView = requireActivity().window.decorView as? FrameLayout
@@ -139,27 +137,31 @@ class CommunityHomeFragment : LazyFragment() {
}
}
+ mMainWrapperViewModel?.bottomDoubleTabAction?.observe(viewLifecycleOwner) {
+ if (isSupportVisible && it.id == mBottomTabId) {
+ scrollToTop()
+ }
+ }
+
mBinding?.run {
topBg.visibleIf(!mIsDarkModeOn)
videoLottie.setOnClickListener {
DirectUtils.directToLegacyVideoDetail(requireContext(), "", VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value, referer = "视频流-社区右上角", isHomeVideo = true)
}
- listOf(searchContainer, searchIconIv).forEach {
- it.setOnClickListener {
- NewLogUtils.logCommunitySearchClick()
- NewLogUtils.logForumSearchEnter("社区搜索栏")
- NewFlatLogUtils.logAccessToBbsSearch("社区", "")
- requireContext().startActivity(
- ForumOrUserSearchActivity.getIntent(
- requireContext(),
- "",
- "论坛首页",
- SOURCE_ENTRANCE,
- SOURCE_ENTRANCE
- )
+ searchIconIv.setOnClickListener {
+ NewLogUtils.logCommunitySearchClick()
+ NewLogUtils.logForumSearchEnter("社区搜索栏")
+ NewFlatLogUtils.logAccessToBbsSearch("社区", "")
+ requireContext().startActivity(
+ ForumOrUserSearchActivity.getIntent(
+ requireContext(),
+ "",
+ "论坛首页",
+ SOURCE_ENTRANCE,
+ SOURCE_ENTRANCE
)
- }
+ )
}
communityEditBtn.setOnClickListener {
@@ -183,12 +185,21 @@ class CommunityHomeFragment : LazyFragment() {
}
}
})
+
+ val isDetailPage = arguments?.getBoolean(IS_DETAIL_PAGE) ?: false
+ ivBack.visibility = if (isDetailPage) View.VISIBLE else View.GONE
+ if (isDetailPage) {
+ ivBack.setOnClickListener {
+ activity?.finish()
+ }
+ }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
savedInstanceState?.let { mDefaultSelectedTab = it.getInt(LAST_SELECTED_POSITION) }
+ mBottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
@@ -207,7 +218,7 @@ class CommunityHomeFragment : LazyFragment() {
override fun onFragmentResume() {
super.onFragmentResume()
-
+ DisplayUtils.transparentStatusBar(requireActivity())
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
NewLogUtils.logCommunityHomeEvent("view_community")
}
@@ -623,13 +634,10 @@ class CommunityHomeFragment : LazyFragment() {
}
}
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onEventMainThread(busNine: EBUISwitch) {
- if (busNine.position == MainWrapperFragment.INDEX_BBS) {
- if (mFragmentList.isEmpty()) return
- (mFragmentList[0] as ForumArticleListFragment).scrollToTop()
- setPutQuestionButtonStatus(View.VISIBLE)
- }
+ private fun scrollToTop() {
+ if (mFragmentList.isEmpty()) return
+ (mFragmentList[0] as ForumArticleListFragment).scrollToTop()
+ setPutQuestionButtonStatus(View.VISIBLE)
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -709,8 +717,6 @@ class CommunityHomeFragment : LazyFragment() {
}
}
}
- searchTv.setHintTextColor(R.color.text_instance.toColor(requireContext()))
- searchTv.setTextColor(R.color.text_instance.toColor(requireContext()))
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt
index c34c06d5bb..1029838acc 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt
@@ -2,14 +2,14 @@ package com.gh.gamecenter.forum.home
import android.content.Context
import android.view.ViewGroup
-import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
-import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.InfoActivity
+import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
+import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.databinding.ForumWelfareItemBinding
-import com.gh.gamecenter.toolbox.ToolBoxBlockActivity
+import com.gh.gamecenter.toolbox.ToolBoxActivity
import com.lightgame.adapter.BaseRecyclerAdapter
class WelfaresAdapter(
@@ -35,7 +35,7 @@ class WelfaresAdapter(
when (entity.second) {
"游戏工具箱" -> {
NewLogUtils.logForumPageEvent("click_forum_toolbox")
- mContext.startActivity(ToolBoxBlockActivity.getIntent(mContext, "(社区-论坛:工具箱)"))
+ mContext.startActivity(ToolBoxActivity.getIntent(mContext, "(社区-论坛:工具箱)"))
}
"礼包中心" -> {
diff --git a/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListFragment.kt
index fcb21c3aa5..eb83cbae97 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListFragment.kt
@@ -4,20 +4,20 @@ import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
-import com.gh.gamecenter.common.constant.Constants
-import com.gh.common.util.*
-import com.gh.gamecenter.NewsDetailActivity
+import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
+import com.gh.gamecenter.common.base.fragment.ToolbarFragment
+import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.ifLogin
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.common.utils.viewModelProvider
-import com.gh.gamecenter.core.utils.*
+import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.FragmentModeratorListBinding
import com.gh.gamecenter.entity.ApplyModeratorStatusEntity
import com.gh.gamecenter.eventbus.EBUserFollow
-import com.gh.gamecenter.common.base.fragment.ToolbarFragment
+import com.gh.gamecenter.newsdetail.NewsDetailActivity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
index 5557291bb3..0069bf55a9 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
@@ -5,7 +5,8 @@ import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
-import com.gh.common.util.*
+import com.gh.common.util.NewFlatLogUtils
+import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
@@ -15,6 +16,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.showKeyBoard
import com.gh.gamecenter.common.utils.toColor
+import com.gh.gamecenter.forum.detail.ForumDetailFragment
import com.gh.gamecenter.search.SearchDefaultFragment
import com.lightgame.utils.Util_System_Keyboard
@@ -30,7 +32,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
mBbsId = intent.getStringExtra(EntranceConsts.KEY_BBS_ID) ?: ""
mLocation = intent.getStringExtra(EntranceConsts.KEY_LOCATION) ?: ""
mSourceEntrance = intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
- searchEt.hint = if (mEntrance == "论坛首页") {
+ searchEt.hint = if (mEntrance != ForumDetailFragment.ENTRANCE) {
"搜索论坛内容、用户"
} else {
"搜索此论坛中的内容"
@@ -39,7 +41,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
searchBtn.setTextColor(R.color.text_theme.toColor(this))
searchBtn.setOnClickListener {
val key = searchEt.text.toString().trim { it <= ' ' }
- NewLogUtils.logForumSearchClick(key, if (mEntrance == "论坛首页") "社区搜索" else "论坛详情页搜索")
+ NewLogUtils.logForumSearchClick(key, if (mEntrance != ForumDetailFragment.ENTRANCE) "社区搜索" else "论坛详情页搜索")
Util_System_Keyboard.hideSoftKeyboard(this)
search(SearchType.MANUAL, null)
}
@@ -49,7 +51,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
super.initSearchBar()
backBtn.setOnClickListener {
val key = searchEt.text.toString().trim { it <= ' ' }
- if (mEntrance == "论坛首页") {
+ if (mEntrance != ForumDetailFragment.ENTRANCE) {
NewFlatLogUtils.logClickSearchReturn(key)
} else {
NewFlatLogUtils.logClickBbsSearchReturn(key, mBbsId)
@@ -134,7 +136,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
val key = searchEt.text.toString().trim { it <= ' ' }
if (key.isNotEmpty()) {
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
- if (mEntrance == "论坛首页") {
+ if (mEntrance != ForumDetailFragment.ENTRANCE) {
NewFlatLogUtils.logViewSearchList(stayTime, key)
} else {
NewFlatLogUtils.logViewBbsSearchList(stayTime, key, mBbsId)
@@ -143,7 +145,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
}
else -> {
- if (mEntrance == "论坛首页") {
+ if (mEntrance != ForumDetailFragment.ENTRANCE) {
val fragment =
supportFragmentManager.findFragmentByTag(ForumOrUserSearchFragment::class.java.name) as? ForumOrUserSearchFragment
?: ForumOrUserSearchFragment()
@@ -177,13 +179,25 @@ class ForumOrUserSearchActivity : SearchActivity() {
bbsId: String,
mEntrance: String,
sourceEntrance: String,
- location: String
+ location: String,
+ bottomTab: String = "",
+ multiTabId: String = "",
+ multiTabName: String = "",
+ customPageId: String = "",
+ customPageName: String = "",
+ searchBoxPattern: String = ""
): Intent {
val intent = Intent(context, ForumOrUserSearchActivity::class.java)
intent.putExtra(EntranceConsts.KEY_BBS_ID, bbsId)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, mEntrance)
intent.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
intent.putExtra(EntranceConsts.KEY_LOCATION, location)
+ intent.putExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME, bottomTab)
+ intent.putExtra(EntranceConsts.KEY_MULTI_TAB_NAV_ID, multiTabId)
+ intent.putExtra(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, multiTabName)
+ intent.putExtra(EntranceConsts.KEY_CUSTOM_PAGE_ID, customPageId)
+ intent.putExtra(EntranceConsts.KEY_CUSTOM_PAGE_NAME, customPageName)
+ intent.putExtra(EntranceConsts.KEY_SEARCH_BOX_PATTERN, searchBoxPattern)
return intent
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt
index 40a4b2f76a..d6669e3650 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt
@@ -47,7 +47,7 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
mBinding.hotTagHeadContainer.root.visibility = View.GONE
mBinding.hotTagFlexContainer.visibility = View.GONE
- if (mEntrance == "论坛首页") {
+ if (mEntrance == "论坛首页" || mEntrance == "搜索栏") {
mBinding.hotHeadContainer.headTitle.text = "热门论坛"
mViewModel.getForumSearchHotContent()
} else {
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeGameWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeGameWrapperFragment.kt
index f4c913e0bb..fb89dbe73a 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/HomeGameWrapperFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeGameWrapperFragment.kt
@@ -11,6 +11,7 @@ import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
+import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
@@ -88,7 +89,7 @@ class HomeGameWrapperFragment : HomeTabWrapperFragment() {
startActivity(DownloadManagerActivity.getDownloadMangerIntent(requireContext(), "游戏库"))
}
mBinding?.menuDownloadCountHint?.typeface =
- Typeface.createFromAsset(requireContext().assets, "fonts/d_din_bold_only_number.ttf")
+ Typeface.createFromAsset(requireContext().assets, Constants.DIN_FONT_PATH)
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt
index 26ab950a26..f6519d7cf3 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt
@@ -6,7 +6,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.ColorUtils
import com.gh.common.exposure.ExposureManager
-import com.gh.common.prioritychain.AccelerateNotificationHandler
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.LogUtils
@@ -28,7 +27,7 @@ import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeElapsedHelper
import com.gh.gamecenter.databinding.FragmentMainHomeWrapperBinding
-import com.gh.gamecenter.entity.HomePush
+import com.gh.gamecenter.entity.PullDownPush
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
@@ -38,6 +37,7 @@ import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.home.HomeFragment
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
+import com.gh.gamecenter.wrapper.MainWrapperViewModel
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
@@ -75,7 +75,7 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
private var mTwoLevelOpenOffset = 0
private var mTwoLevelOpenCount = 0
private var mShowTwoLevelStartOffset = 0
- private var mHomePush: HomePush? = null
+ private var mHomePush: PullDownPush? = null
private var mExposureEvent: ExposureEvent? = null
private var mGameViewHolder: GameViewHolder? = null
@@ -155,25 +155,6 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
setHomePush()
}
}
-
- mMainWrapperViewModel?.accelerateNotificationPopup?.observeNonNull(viewLifecycleOwner) {
- if (parentFragment is MainWrapperFragment && isSupportVisible) {
- val isHandlerQueueEmpty = (parentFragment as MainWrapperFragment).isPriorityChainHandlerQueueEmpty()
- val accelerateSet =
- HashSet(SPUtils.getStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET))
- if (isHandlerQueueEmpty && it.isNotEmpty() && !accelerateSet.contains(it[0].messageId)) {
- AccelerateNotificationHandler.showAccelerateNotificationPopupWindow(
- requireActivity(),
- mMainWrapperViewModel,
- mBaseHandler as BaseHandler,
- it[0],
- null
- )
- accelerateSet.add(it[0].messageId)
- SPUtils.setStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET, accelerateSet)
- }
- }
- }
}
private fun initSmartRefresh() {
@@ -609,7 +590,7 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
}
mHomePush?.run {
- val homePushSet = HashSet(SPUtils.getStringSet(Constants.SP_HOME_PUSH_POP_UP_SET))
+ val homePushSet = HashSet(SPUtils.getStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET))
if (popSwitch == "on" && !homePushSet.contains(id)) {
// 自动弹出,5s后自动收起
twoLevelHeader.openTwoLevel(true)
@@ -620,7 +601,7 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
toolbarBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
classicsHeader.visibility = View.INVISIBLE
homePushSet.add(id)
- SPUtils.setStringSet(Constants.SP_HOME_PUSH_POP_UP_SET, homePushSet)
+ SPUtils.setStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET, homePushSet)
mBaseHandler.postDelayed({
finishTwoLevel("自动收起")
finishCallback.invoke()
@@ -997,7 +978,7 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
}
}
}
- if (reuse.type == Constants.FINISH_HOME_PUSH) {
+ if (reuse.type == Constants.FINISH_PULL_DOWN_PUSH) {
if (!mHomePushClick) {
mBaseHandler.postDelayed({
finishTwoLevel("跳转收起")
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt
index 2ef3c4dee3..a66a43cfa5 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt
@@ -5,7 +5,6 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.gh.common.filter.RegionSettingHelper
-import com.gh.common.prioritychain.FloatingWindowHandler
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.common.retrofit.BiResponse
@@ -29,7 +28,6 @@ class HomeSearchToolWrapperViewModel(application: Application) : AndroidViewMode
private var mHomeTabPosition: Int = -1
private var mHomeTab: SubjectRecommendEntity? = null
- private var mFloatingWindowHandler: FloatingWindowHandler? = null
var appBarOffset = 0
@@ -116,12 +114,4 @@ class HomeSearchToolWrapperViewModel(application: Application) : AndroidViewMode
})
}
- fun setFloatingWindowHandler(handler: FloatingWindowHandler) {
- mFloatingWindowHandler = handler
- }
-
- fun getFloatingWindowHandler(): FloatingWindowHandler? {
- return mFloatingWindowHandler
- }
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeToolbarWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeToolbarWrapperFragment.kt
index eae93531e4..113cad8d4c 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/HomeToolbarWrapperFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeToolbarWrapperFragment.kt
@@ -14,6 +14,7 @@ import androidx.appcompat.widget.Toolbar
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment
import com.facebook.drawee.view.SimpleDraweeView
+import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
@@ -79,7 +80,7 @@ class HomeToolbarWrapperFragment: LazyFragment(), ToolbarController {
try {
if (arguments != null) {
- val className = requireArguments().getString(MainWrapperFragment.WRAPPER_FRAGMENT_NAME)
+ val className = requireArguments().getString(ViewPagerFragmentHelper.WRAPPER_FRAGMENT_NAME)
mContentFragment = childFragmentManager.findFragmentById(R.id.wrapper_main_content) ?: Class.forName(className).newInstance() as Fragment
mContentFragment!!.arguments = requireArguments().clone() as Bundle
}
@@ -125,7 +126,7 @@ class HomeToolbarWrapperFragment: LazyFragment(), ToolbarController {
}
val downloadMenuView = mActionMenuView?.menu?.findItem(R.id.menu_download)?.actionView
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
- mDownloadCountHint?.typeface = Typeface.createFromAsset(requireActivity().assets, "fonts/d_din_bold_only_number.ttf")
+ mDownloadCountHint?.typeface = Typeface.createFromAsset(requireActivity().assets, Constants.DIN_FONT_PATH)
}
private fun updateDownloadCountHint(updateList: List?) {
@@ -164,7 +165,7 @@ class HomeToolbarWrapperFragment: LazyFragment(), ToolbarController {
}
// 设置标题居中
- private fun setTitleCenter() {
+ override fun setTitleCenter() {
if (mActionMenuView != null && mTitleContainer != null && mBackContainer != null) {
mActionMenuView!!.post {
val params =
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.kt
deleted file mode 100644
index 1c62e50ea7..0000000000
--- a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.kt
+++ /dev/null
@@ -1,874 +0,0 @@
-package com.gh.gamecenter.fragment
-
-import android.graphics.PorterDuff
-import android.graphics.drawable.Animatable
-import android.net.Uri
-import android.os.Bundle
-import android.text.TextUtils
-import android.view.View
-import android.widget.CheckedTextView
-import android.widget.ImageView
-import androidx.annotation.ColorRes
-import androidx.core.content.ContextCompat
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProvider
-import androidx.viewpager.widget.PagerAdapter
-import com.airbnb.lottie.LottieAnimationView
-import com.facebook.drawee.backends.pipeline.Fresco
-import com.facebook.drawee.controller.BaseControllerListener
-import com.facebook.drawee.interfaces.DraweeController
-import com.facebook.drawee.view.SimpleDraweeView
-import com.facebook.fresco.animation.drawable.AnimatedDrawable2
-import com.facebook.fresco.animation.drawable.BaseAnimationListener
-import com.facebook.imagepipeline.image.ImageInfo
-import com.gh.common.constant.Config
-import com.gh.common.prioritychain.*
-import com.gh.common.util.*
-import com.gh.common.util.LogUtils
-import com.gh.common.util.NewLogUtils
-import com.gh.gamecenter.MainActivity
-import com.gh.gamecenter.R
-import com.gh.gamecenter.ShellActivity
-import com.gh.gamecenter.adapter.MainFragmentPagerAdapter
-import com.gh.gamecenter.amway.AmwayFragment
-import com.gh.gamecenter.catalog.CatalogFragment
-import com.gh.gamecenter.category.CategoryDirectoryFragment
-import com.gh.gamecenter.category2.CategoryV2Fragment
-import com.gh.gamecenter.common.base.fragment.BaseFragment_ViewPager_Checkable
-import com.gh.gamecenter.common.base.fragment.ToolbarFragment
-import com.gh.gamecenter.common.callback.OnDoubleTapListener
-import com.gh.gamecenter.common.constant.Constants
-import com.gh.gamecenter.common.constant.EntranceConsts
-import com.gh.gamecenter.common.eventbus.EBReuse
-import com.gh.gamecenter.common.exposure.ExposureSource
-import com.gh.gamecenter.common.syncpage.SyncPageRepository
-import com.gh.gamecenter.common.tracker.TrackerLogger
-import com.gh.gamecenter.common.utils.*
-import com.gh.gamecenter.core.utils.SPUtils
-import com.gh.gamecenter.core.utils.SentryHelper
-import com.gh.gamecenter.databinding.FragmentMainBinding
-import com.gh.gamecenter.discovery.DiscoveryFragment
-import com.gh.gamecenter.entity.HomeDataEntity
-import com.gh.gamecenter.entity.SubjectData
-import com.gh.gamecenter.entity.SubjectRecommendEntity
-import com.gh.gamecenter.eventbus.EBSkip
-import com.gh.gamecenter.eventbus.EBUISwitch
-import com.gh.gamecenter.forum.detail.ForumDetailFragment
-import com.gh.gamecenter.forum.home.CommunityHomeFragment
-import com.gh.gamecenter.game.GameFragment
-import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
-import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
-import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
-import com.gh.gamecenter.login.entity.UserInfoEntity
-import com.gh.gamecenter.message.MessageUnreadRepository
-import com.gh.gamecenter.message.MessageUnreadViewModel
-import com.gh.gamecenter.personal.HaloPersonalFragment
-import com.gh.gamecenter.pkg.PkgHelper
-import com.gh.gamecenter.servers.GameServersPublishFragment
-import com.gh.gamecenter.servers.GameServersTestFragment
-import com.gh.gamecenter.subject.SubjectFragment
-import com.gh.gamecenter.video.detail.HomeVideoFragment
-import com.halo.assistant.HaloApp
-import com.halo.assistant.fragment.WebFragment
-import com.lightgame.listeners.OnBackPressedListener
-import com.lightgame.view.CheckableLinearLayout
-import com.lightgame.view.NoScrollableViewPager
-import org.greenrobot.eventbus.EventBus
-import org.greenrobot.eventbus.Subscribe
-import org.greenrobot.eventbus.ThreadMode
-import org.json.JSONObject
-
-class MainWrapperFragment : BaseFragment_ViewPager_Checkable(), OnBackPressedListener {
-
- private val mBinding by lazy { FragmentMainBinding.inflate(layoutInflater) }
- private var mViewModel: MainWrapperViewModel? = null
- private var mGameWrapperFragment: SearchToolWrapperFragment? = null
- private var mHomeFragment: HomeSearchToolWrapperFragment? = null
- private var mFourthFragment: ToolbarFragment? = null
- private var mCommunityHomeFragment: CommunityHomeFragment? = null
- private val mResAssets = arrayOf(
- "lottie/tab_home.json",
- "lottie/tab_game.json",
- "lottie/tab_forum.json",
- "lottie/tab_video.json",
- "tab_mine.gif"
- )
- private var mPopUpHomePush = false
-
- private val mPriorityChain by lazy { PriorityChain() }
-
- private var mVideoNavBarEntity: SubjectRecommendEntity? = null
-
- override fun getLayoutId(): Int = 0
- override fun getInflatedLayout() = mBinding.root
- override fun getCheckableGroupId(): Int = R.id.lightgame_tab_container
- override fun getViewPagerId(): Int = R.id.lightgame_tab_viewpager
- override fun getCurrentItem() = mViewPager.currentItem
- override fun getChildCount(): Int = 5
- override fun provideAdapter(): PagerAdapter = MainFragmentPagerAdapter(requireContext(), childFragmentManager, mFragmentsList as ArrayList)
-
- override fun initFragmentList(fragments: MutableList) {
- mHomeFragment = HomeSearchToolWrapperFragment()
- fragments.add(mHomeFragment!!)
- initGameWrapperFragment()
- fragments.add(mGameWrapperFragment!!)
- mCommunityHomeFragment = CommunityHomeFragment()
- mCommunityHomeFragment!!.arguments = arguments
- fragments.add(mCommunityHomeFragment!!)
- initFourthFragment(fragments)
- if (mViewModel!!.shouldHideVideoTab()) {
- mBinding.mainTabVideo.visibility = View.GONE
- }
- fragments.add(HaloPersonalFragment())
- }
-
- private fun initGameWrapperFragment() {
- mGameWrapperFragment = SearchToolWrapperFragment()
- val homeArgs = Bundle()
- var entity = mViewModel!!.gameNavBar.value
- if (entity == null) {
- entity = HomeBottomBarHelper.getDefaultGameBarData()
- }
- putFragmentBundle(entity, homeArgs, true)
-
- if ("block" != entity.type) {
- homeArgs.putParcelable(
- EntranceConsts.KEY_EXPOSURE_SOURCE,
- ExposureSource("游戏库", "")
- )
- }
- mGameWrapperFragment!!.arguments = homeArgs
- }
-
- private fun initFourthFragment(fragments: MutableList) {
- var entity = mViewModel!!.videoNavBar.value
- if (entity == null) {
- entity = HomeBottomBarHelper.getDefaultVideoData()
- }
-
- val fourthFragment: Fragment? = when (entity.type) {
- "video_stream" -> {
- if (mFourthFragment !is HomeVideoFragment) {
- val videoArgs = Bundle()
- videoArgs.putBoolean(EntranceConsts.KEY_IS_HOME_VIDEO, true)
- mFourthFragment = HomeVideoFragment()
- mFourthFragment!!.arguments = videoArgs
- mFourthFragment
- } else {
- null
- }
- }
-
- "top_game_comment" -> {
- if (mFourthFragment !is AmwayFragment) {
- val amwayArgs = Bundle()
- amwayArgs.putBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, true)
- mFourthFragment = AmwayFragment()
- mFourthFragment!!.arguments = amwayArgs
- mFourthFragment
- } else {
- null
- }
- }
-
- "community" -> {
- if (mFourthFragment !is ForumDetailFragment) {
- val forumArgs = Bundle()
- forumArgs.putString(EntranceConsts.KEY_BBS_ID, entity.link)
- forumArgs.putBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, true)
- mFourthFragment = ForumDetailFragment()
- mFourthFragment!!.arguments = forumArgs
- mFourthFragment
- } else {
- null
- }
- }
-
- else -> {
- // 新页面与旧页面类型不同或链接不同时才进行替换
- if (mFourthFragment !is HomeToolbarWrapperFragment || mVideoNavBarEntity?.type != entity.type || mVideoNavBarEntity?.link != entity.link) {
- val homeArgs = Bundle()
- putFragmentBundle(entity, homeArgs, false)
- mFourthFragment = HomeToolbarWrapperFragment()
- mFourthFragment!!.arguments = homeArgs
- mFourthFragment
- } else {
- null
- }
- }
- }
- if (fourthFragment != null) {
- if (mFragmentsList.size > 3) {
- // 替换第4个Fragment
- try {
- (mAdapter as MainFragmentPagerAdapter).replaceFragment(3, fourthFragment)
- } catch (e: Exception) {
- SentryHelper.onEvent(
- "REPLACE_FRAGMENT_CRASH",
- "new_fragment_type",
- entity.type,
- "old_fragment_type",
- mVideoNavBarEntity?.type,
- "new_link",
- entity.link,
- "old_link",
- mVideoNavBarEntity?.link
- )
- }
- } else {
- fragments.add(fourthFragment)
- }
- mVideoNavBarEntity = entity
- }
- }
-
- private fun putFragmentBundle(entity: SubjectRecommendEntity, homeArgs: Bundle, isGameTab: Boolean) {
- var className = HomeGameWrapperFragment::class.java.name
- val entrance = if (isGameTab) "游戏库" else entity.linkTypeChinese
- when (entity.type) {
- "block" -> {
- className = if (isGameTab) HomeGameWrapperFragment::class.java.name else GameFragment::class.java.name
- if (isGameTab) {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_SEARCH_TOOLBAR, false)
- } else {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, true)
- homeArgs.putBoolean(EntranceConsts.KEY_IS_FROM_HOME_TOOLBAR_WRAPPER, true)
- }
- homeArgs.putParcelable(EntranceConsts.KEY_BLOCK_DATA, entity)
- }
-
- "column" -> {
- className = SubjectFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- homeArgs.putParcelable(
- EntranceConsts.KEY_SUBJECT_DATA,
- SubjectData(entity.link, entity.text, false, "", "", "", "", true, false, false)
- )
- if (!isGameTab) {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, true)
- }
- }
-
- "column_collection" -> {
- className = ColumnCollectionDetailFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
- homeArgs.putInt(EntranceConsts.KEY_POSITION, 0)
- homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
- homeArgs.putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
- }
-
- "server" -> {
- className = GameServersPublishFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- if (!isGameTab) {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, true)
- }
- }
-
- "column_test" -> {
- className = GameServersTestFragment::class.java.name
- homeArgs.putString(GameServersTestFragment.TEST_COLUMN_ID, entity.link)
- if (!isGameTab) {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, true)
- }
- }
-
- "catalog" -> {
- className = CatalogFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_CATALOG_ID, entity.link)
- homeArgs.putString(EntranceConsts.KEY_CATALOG_TITLE, entity.text)
- }
-
- "category" -> {
- className = CategoryDirectoryFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_CATEGORY_ID, entity.link)
- homeArgs.putString(EntranceConsts.KEY_CATEGORY_TITLE, entity.text)
- }
-
- "category_v2" -> {
- className = CategoryV2Fragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_CATEGORY_ID, entity.link)
- homeArgs.putString(EntranceConsts.KEY_CATEGORY_TITLE, entity.text)
- if (!isGameTab) {
- homeArgs.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, true)
- }
- }
-
- "common_collection" -> {
- className = CommonCollectionDetailFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
- homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
- }
-
- "game_list" -> {
- className = GameCollectionSquareFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- homeArgs.putInt(EntranceConsts.KEY_TAB_INDEX, 0)
- homeArgs.putString(EntranceConsts.KEY_NAME, entity.name)
- homeArgs.putBoolean(EntranceConsts.KEY_IS_FROM_HOME_TOOLBAR_WRAPPER, true)
- }
-
- "web" -> {
- className = WebFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_URL, entity.link)
- homeArgs.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false)
- homeArgs.putBoolean(WebFragment.KEY_ENABLE_HORIZONTAL_SCROLL_DISPATCH, true)
- if (entity.link != null && entity.link!!.contains("leave_web_page_handle_back_pressed=true")) {
- homeArgs.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true)
- }
- }
-
- "explore_column" -> {
- className = DiscoveryFragment::class.java.name
- homeArgs.putString(EntranceConsts.KEY_ENTRANCE, entrance)
- }
- }
- homeArgs.putString(EntranceConsts.KEY_LOCATION, entrance)
- homeArgs.putString(WRAPPER_FRAGMENT_NAME, className)
- homeArgs.putBoolean(EntranceConsts.KEY_IS_HOME, true)
- }
-
- override fun restoreFragments(): ArrayList = ArrayList()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- mViewModel = viewModelProviderFromParent(MainWrapperViewModel.Factory(HaloApp.getInstance()))
-
- super.onCreate(savedInstanceState)
-
- buildPriorityChain()
-
- mViewModel?.gameNavBar?.observe(this) { updateGameBarContent(it) }
-
- mViewModel?.videoNavBar?.observe(this) { updateVideoBarContent(it) }
-
- mBinding.viewShadow.visibility = if (mIsDarkModeOn) View.GONE else View.VISIBLE
-
- ViewModelProvider(this)[MessageUnreadViewModel::class.java]
- .unreadMessageTotalLiveData.observe(this) { isShow: Boolean? ->
- mBinding.mainIvMessageHint.goneIf(!isShow!!)
- }
- }
-
- /**
- * 构建 PriorityChain,使用优先队列来决定当前需要显示哪一个弹窗
- * 正常弹窗顺序(不含首页自动下拉二楼),更新弹窗、隐私政策弹窗、消息通知权限弹窗、预约弹窗、插件化通知 popup、启动弹窗、右下悬浮窗
- * 特殊弹窗顺序(含首页自动下拉二楼,无需请求显示启动弹窗),更新弹窗、隐私政策弹窗、消息通知权限弹窗、预约弹窗、插件化通知 popup、首页自动下拉二楼、右下悬浮窗
- * 可以根据上述的顺序为弹窗预设优先级
- * 更新弹窗 (-100)
- * 隐私政策弹窗 (-99)
- * 消息通知权限弹窗 (0)
- * 预约弹窗 (1)
- * 插件化通知 popup (2)
- * 首页自动下拉二楼 (3)
- * 启动弹窗 (4)
- * 首页右下悬浮窗 (5)
- */
- private fun buildPriorityChain() {
- val homeSearchToolWrapperViewModel: HomeSearchToolWrapperViewModel = viewModelProviderFromParent()
-
- val updateDialogHandler = UpdateDialogHandler(requireContext(), -100)
- val privacyPolicyDialogHandler = PrivacyPolicyDialogHandler(-99)
- val notificationPermissionDialogHandler = NotificationPermissionDialogHandler(0)
- val reserveDialogHandler = ReserveDialogHandler(1)
- val accelerateNotificationHandler = AccelerateNotificationHandler(2)
- val homePushHandler = HomePushHandler(3)
- val welcomeDialogHandler = WelcomeDialogHandler(4)
- val floatingWindowHandler = FloatingWindowHandler(5)
-
- homeSearchToolWrapperViewModel.setFloatingWindowHandler(floatingWindowHandler)
-
- mPriorityChain.addHandler(updateDialogHandler)
- mPriorityChain.addHandler(privacyPolicyDialogHandler)
- mPriorityChain.addHandler(welcomeDialogHandler)
- mPriorityChain.addHandler(reserveDialogHandler)
- mPriorityChain.addHandler(notificationPermissionDialogHandler)
- mPriorityChain.addHandler(accelerateNotificationHandler)
- mPriorityChain.addHandler(homePushHandler)
- mPriorityChain.addHandler(floatingWindowHandler)
-
- mViewModel?.privacyPolicyDialog?.observe(this) {
- privacyPolicyDialogHandler.doPreProcess(requireActivity(), it)
- }
-
- mViewModel?.reserveDialog?.observe(this) {
- reserveDialogHandler.doPreProcess(this, it)
- MessageUnreadRepository.loadMessageUnreadData()
- }
-
- mViewModel?.accelerateNotificationPopup?.observe(this) {
- accelerateNotificationHandler.doPreProcess(
- requireActivity(),
- mBaseHandler!! as BaseHandler,
- it,
- mViewModel!!
- )
- }
-
- mViewModel?.floatingWindow?.observe(this) { windowEntityList ->
- floatingWindowHandler.setData(windowEntityList ?: arrayListOf())
- }
-
- homeSearchToolWrapperViewModel.homeDataLiveData.observe(this) { homeDataEntity: HomeDataEntity? ->
- val homePushSet =
- SPUtils.getStringSet(Constants.SP_HOME_PUSH_POP_UP_SET)
- mPopUpHomePush = homeDataEntity?.homePush != null
- && "on" == homeDataEntity.homePush?.popSwitch
- && !homePushSet.contains(homeDataEntity.homePush?.id)
-
- if (mPopUpHomePush) {
- welcomeDialogHandler.doPreProcess(this, null)
- } else {
- welcomeDialogHandler.doPreProcess(this, mViewModel!!.welcomeDialog.value)
- }
-
- homePushHandler.doPreProcess(mHomeFragment!!, mPopUpHomePush)
- }
- }
-
- fun showDialog() {
- mPriorityChain.start()
- }
-
- fun isPriorityChainHandlerQueueEmpty() = mPriorityChain.isHandlerQueueEmpty()
-
- private fun applyPkgConfig() {
- val pkgLinkEntity = PkgHelper.getPkgConfig()
- if (pkgLinkEntity != null) {
- val bottomTab = pkgLinkEntity.homeBottomTab
- if (!pkgLinkEntity.shouldStayAtMainActivity) {
- // 不停留在首页,执行跳转,标记已用
- PkgHelper.markConfigUsed()
- DirectUtils.directToLinkPage(requireContext(), pkgLinkEntity, "推广包配置", "首页")
- } else if ("home" != bottomTab) {
- // 停留首页,但选中底部 tab 不是首页的,执行选中,标记已用
- PkgHelper.markConfigUsed()
- // TODO 根据具体 tab 来作为跳转的具体位置,避免硬编码
- var targetIndex = INDEX_HOME
- when (bottomTab) {
- "game_lib" -> targetIndex = INDEX_GAME
- "community" -> targetIndex = INDEX_BBS
- "video" -> targetIndex = INDEX_VIDEO
- "gh" -> targetIndex = INDEX_PERSONAL
- }
- mViewPager.currentItem = targetIndex
- onPageChanged(targetIndex)
- changeColor(targetIndex)
- }
- }
- }
-
- private fun updateGameBarContent(navBarEntity: SubjectRecommendEntity?) {
- if (navBarEntity != null) {
- mBinding.mainTabGame.visibility = View.VISIBLE
- mBinding.mainTabGameName.text = navBarEntity.name
- ImageUtils.picasso
- .load(Uri.parse(navBarEntity.iconUnselect)) //.placeholder(R.drawable.ic_game_unselect)
- .into(mBinding.mainTabGameIcon)
- if (navBarEntity.default) currentItem = INDEX_GAME
- } else {
- mBinding.mainTabGame.visibility = View.GONE
- }
- }
-
- private fun updateVideoBarContent(navBarEntity: SubjectRecommendEntity?) {
- mBinding.mainTabVideo.visibility = View.VISIBLE
- if (navBarEntity != null) {
- mBinding.mainTabVideoName.text = navBarEntity.name
- ImageUtils.picasso
- .load(Uri.parse(navBarEntity.iconUnselect))
- .placeholder(R.drawable.ic_video_unselect)
- .into(mBinding.mainTabVideoIcon)
- if (navBarEntity.default) currentItem = INDEX_VIDEO
- initFourthFragment(mFragmentsList)
- } else {
- mBinding.mainTabVideo.visibility = View.GONE
- }
- }
-
- override fun onPause() {
- super.onPause()
- SyncPageRepository.clearSyncData()
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- if (mViewPager is NoScrollableViewPager) {
- (mViewPager as NoScrollableViewPager).setScrollable(false)
- }
-
- // 启动时即当选中第一个 tab
- onPageChanged(INDEX_HOME)
- changeColor(INDEX_HOME)
- for (i in 0 until mCheckableGroup.childCount) {
- val child = mCheckableGroup.getChildAt(i)
- child.setOnTouchListener(object : OnDoubleTapListener(context) {
- override fun onDoubleTap() {
- EventBus.getDefault().post(EBUISwitch(EB_MAIN_SCROLL_TOP, i))
- }
- })
- }
- applyPkgConfig()
-
- updateRealNameErrorContainer()
- }
-
- override fun handleOnClick(view: View): Boolean {
- val toCheck = mCheckableGroup.indexOfChild(view)
- playTabAnimation(toCheck)
- changeColor(toCheck)
- mHomeFragment?.finishTwoLevel("跳转收起")
- val trackEvent = JSONObject()
- val isFirstTime = SPUtils.getBoolean(Constants.SP_SENSORS_IS_FIRST_TIME_HOME_BOTTOM_TAB_SELECT, true)
- tryWithDefaultCatch {
- trackEvent.put("position", toCheck)
- trackEvent.put("tab_content", getTabName(toCheck))
- trackEvent.put("\$is_first_time", isFirstTime)
- }
- SPUtils.setBoolean(Constants.SP_SENSORS_IS_FIRST_TIME_HOME_BOTTOM_TAB_SELECT, false)
- SensorsBridge.trackEvent("HomeBottomTabSelect", trackEvent)
- return super.handleOnClick(view)
- }
-
- private fun getTabName(index: Int): String {
- return when (index) {
- 0 -> mBinding.mainTabHomeName.text.toString()
- 1 -> mBinding.mainTabGameName.text.toString()
- 2 -> mBinding.mainTabCommunityName.text.toString()
- 3 -> mBinding.mainTabVideoName.text.toString()
- 4 -> mBinding.mainTabMeName.text.toString()
- else -> ""
- }
- }
-
- private fun changeColor(toCheck: Int) {
- if (mFourthFragment is HomeVideoFragment && toCheck == INDEX_VIDEO) {
- mBinding.viewShadow.visibility = View.GONE
- mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.transparent))
- changeTabImageColor(R.color.text_A1A5B7, PorterDuff.Mode.SRC_ATOP, toCheck)
- } else {
- mBinding.viewShadow.visibility = if (mIsDarkModeOn) View.GONE else View.VISIBLE
- mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.ui_surface))
- changeTabImageColor(
- if (mIsDarkModeOn) R.color.text_A1A5B7 else R.color.text_50556B,
- if (mIsDarkModeOn) PorterDuff.Mode.SRC_ATOP else PorterDuff.Mode.DST,
- toCheck
- )
- }
- changeTabTextColor(toCheck)
- }
-
- private fun playTabAnimation(toCheck: Int) {
- when (toCheck) {
- INDEX_HOME -> {
- stopAnimation(mBinding.lottieGame, INDEX_GAME)
- stopAnimation(mBinding.lottieVideo, INDEX_VIDEO)
- stopAnimation(mBinding.lottieCommunity, INDEX_BBS)
- stopAnimation(mBinding.lottieMine, INDEX_PERSONAL)
- playAnimation(mBinding.lottieHome, toCheck)
- }
-
- INDEX_GAME -> {
- val value = mViewModel!!.gameNavBar.value
- if (value != null && !TextUtils.isEmpty(value.animationCode)) {
- stopAnimation(mBinding.lottieHome, INDEX_HOME)
- stopAnimation(mBinding.lottieVideo, INDEX_VIDEO)
- stopAnimation(mBinding.lottieCommunity, INDEX_BBS)
- stopAnimation(mBinding.lottieMine, INDEX_PERSONAL)
- playGameAnimation(value, toCheck)
- }
- }
-
- INDEX_BBS -> {
- stopAnimation(mBinding.lottieHome, INDEX_HOME)
- stopAnimation(mBinding.lottieGame, INDEX_GAME)
- stopAnimation(mBinding.lottieVideo, INDEX_VIDEO)
- stopAnimation(mBinding.lottieMine, INDEX_PERSONAL)
- playAnimation(mBinding.lottieCommunity, toCheck)
- }
-
- INDEX_VIDEO -> {
- val value = mViewModel!!.videoNavBar.value
- if (value != null && !TextUtils.isEmpty(value.animationCode)) {
- stopAnimation(mBinding.lottieHome, INDEX_HOME)
- stopAnimation(mBinding.lottieGame, INDEX_GAME)
- stopAnimation(mBinding.lottieCommunity, INDEX_BBS)
- stopAnimation(mBinding.lottieMine, INDEX_PERSONAL)
- playVideoAnimation(value, toCheck)
- }
- }
-
- INDEX_PERSONAL -> {
- stopAnimation(mBinding.lottieHome, INDEX_HOME)
- stopAnimation(mBinding.lottieGame, INDEX_GAME)
- stopAnimation(mBinding.lottieVideo, INDEX_VIDEO)
- stopAnimation(mBinding.lottieCommunity, INDEX_BBS)
- playAnimation(mBinding.lottieMine, toCheck)
- }
-
- else -> {}
- }
- }
-
- private fun changeTabImageColor(@ColorRes colorRes: Int, mode: PorterDuff.Mode, toCheck: Int) {
- for (i in 0 until mCheckableGroup.childCount) {
- val checkableGroupChild = mCheckableGroup.getChildAt(i) as CheckableLinearLayout
- val checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild) as? ImageView
- if (checkableView != null) {
- if (i != toCheck) {
- checkableView.setColorFilter(ContextCompat.getColor(requireContext(), colorRes), mode)
- } else {
- checkableView.colorFilter = null
- }
- }
- }
- }
-
- private fun changeTabTextColor(toCheck: Int) {
- for (i in 0 until mCheckableGroup.childCount) {
- val checkableGroupChild = mCheckableGroup.getChildAt(i) as? CheckableLinearLayout
- val checkableView = checkableGroupChild?.findCheckableTextView(checkableGroupChild) as? CheckedTextView
- val isChecked = i == toCheck
- if (checkableView != null) {
- val unselectColor: Int = if (mFourthFragment is HomeVideoFragment && toCheck == INDEX_VIDEO) R.color.text_A1A5B7 else R.color.tab_text_unselect
- checkableView.setTextColor(
- ContextCompat.getColor(requireContext(), if (isChecked) R.color.text_theme else unselectColor)
- )
- }
- }
- }
-
- private fun playGameAnimation(entity: SubjectRecommendEntity, position: Int) {
- val checkableGroupChild = mCheckableGroup.getChildAt(position) as? CheckableLinearLayout
- val checkableView = checkableGroupChild?.findCheckableImageView(checkableGroupChild)
- if (checkableView != null) checkableView.visibility = View.INVISIBLE
- mBinding.lottieGame.visibility = View.VISIBLE
- mBinding.lottieGame.setAnimationFromJson(entity.animationCode, entity.iconSelect)
- mBinding.lottieGame.playAnimation()
- mBinding.lottieGame.doOnAnimationEnd {
- mBinding.lottieGame.visibility = View.GONE
- if (checkableView != null) checkableView.visibility = View.VISIBLE
- }
- }
-
- private fun playVideoAnimation(entity: SubjectRecommendEntity, position: Int) {
- val checkableGroupChild = mCheckableGroup.getChildAt(position) as? CheckableLinearLayout
- val checkableView = checkableGroupChild?.findCheckableImageView(checkableGroupChild)
- if (checkableView != null) checkableView.visibility = View.INVISIBLE
- mBinding.lottieVideo.visibility = View.VISIBLE
- mBinding.lottieVideo.setAnimationFromJson(entity.animationCode, entity.iconSelect)
- mBinding.lottieVideo.playAnimation()
- mBinding.lottieVideo.doOnAnimationEnd {
- mBinding.lottieVideo.visibility = View.GONE
- if (checkableView != null) checkableView.visibility = View.VISIBLE
- }
- }
-
- private fun playAnimation(view: View, position: Int) {
- val checkableGroupChild = mCheckableGroup.getChildAt(position) as CheckableLinearLayout
- val checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild)
- if (checkableView != null) checkableView.visibility = View.INVISIBLE
- view.visibility = View.VISIBLE
- if (view is LottieAnimationView) {
- view.setAnimation(mResAssets[position])
- view.playAnimation()
- view.doOnAnimationEnd {
- view.visibility = View.GONE
- checkableView?.visibility = View.VISIBLE
- }
- } else {
- val lottieView = view as SimpleDraweeView
- val uri = Uri.parse("asset:///" + mResAssets[position])
- val controller: DraweeController = Fresco.newDraweeControllerBuilder()
- .setUri(uri)
- .setAutoPlayAnimations(true)
- .setControllerListener(object : BaseControllerListener() {
- override fun onFinalImageSet(id: String, imageInfo: ImageInfo?, animatable: Animatable?) {
- super.onFinalImageSet(id, imageInfo, animatable)
- if (animatable != null) {
- val animatedDrawable = animatable as AnimatedDrawable2
- animatedDrawable.setAnimationListener(object : BaseAnimationListener() {
- override fun onAnimationStop(drawable: AnimatedDrawable2) {
- super.onAnimationStop(drawable)
- lottieView.visibility = View.GONE
- checkableView?.visibility = View.VISIBLE
- }
- })
- }
- }
- }).build()
- lottieView.controller = controller
- }
- }
-
- private fun stopAnimation(lottieView: View, position: Int) {
- val checkableGroupChild = mCheckableGroup.getChildAt(position) as CheckableLinearLayout
- val checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild)
- checkableView?.visibility = View.VISIBLE
- lottieView.visibility = View.GONE
- }
-
- override fun onPageChanged(index: Int) {
- super.onPageChanged(index)
- var tabText = ""
- when (index) {
- INDEX_HOME -> {
- tabText = "首页"
- NewLogUtils.logBottomNavigationClick("首页", "", "", "", index)
- }
-
- INDEX_GAME -> {
- tabText = "游戏库"
- var entity = mViewModel!!.gameNavBar.value
- if (entity == null) {
- entity = HomeBottomBarHelper.getDefaultGameBarData()
- }
- NewLogUtils.logBottomNavigationClick(
- "游戏库",
- (if (entity.type != null) entity.type else "")!!,
- (if (entity.text != null) entity.text else "")!!, (if (entity.link != null) entity.link else "")!!,
- index
- )
- }
-
- INDEX_BBS -> {
- tabText = "论坛"
- LogUtils.uploadAccessBbsTab()
- NewLogUtils.logBottomNavigationClick("社区", "", "", "", index)
- }
-
- INDEX_VIDEO -> {
- tabText = "视频"
- var entity = mViewModel!!.videoNavBar.value
- if (entity == null) {
- entity = HomeBottomBarHelper.getDefaultVideoData()
- }
- SensorsBridge.trackAccessVideoStreaming("光环底部tab")
- NewLogUtils.logCommunityHomeEvent("click_button_video_tab")
- NewLogUtils.logBottomNavigationClick(entity.linkTypeChinese, entity.type ?: "", entity.text ?: "", entity.link ?: "", index)
- }
-
- INDEX_PERSONAL -> {
- tabText = "我的光环"
- IntegralLogHelper.log("view_me", "我的光环")
- NewLogUtils.logBottomNavigationClick("我的光环", "", "", "", index)
- }
- }
- TrackerLogger.logHomeTabSelected(index, tabText)
- val gameNavBarEntity = mViewModel!!.gameNavBar.value
- if (gameNavBarEntity != null) {
- if (index == INDEX_GAME) {
- ImageUtils.picasso
- .load(Uri.parse(gameNavBarEntity.iconSelect)) //.placeholder(R.drawable.ic_game_select)
- .into(mBinding.mainTabGameIcon)
- } else {
- ImageUtils.picasso
- .load(Uri.parse(gameNavBarEntity.iconUnselect)) //.placeholder(R.drawable.ic_game_unselect)
- .into(mBinding.mainTabGameIcon)
- }
- }
-
- val videoNavBarEntity = mViewModel!!.videoNavBar.value
- if (videoNavBarEntity != null) {
- if (index == INDEX_VIDEO) {
- ImageUtils.picasso
- .load(Uri.parse(videoNavBarEntity.iconSelect))
- .placeholder(R.drawable.ic_video_select)
- .into(mBinding.mainTabVideoIcon)
- } else {
- ImageUtils.picasso
- .load(Uri.parse(videoNavBarEntity.iconUnselect))
- .placeholder(R.drawable.ic_video_unselect)
- .into(mBinding.mainTabVideoIcon)
- }
- }
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onEventMainThread(skip: EBSkip) {
- if (MainActivity.EB_SKIP_MAIN == skip.type) {
- checkIndex(skip.currentItem)
- changeColor(skip.currentItem)
- mViewPager.setCurrentItem(skip.currentItem, false)
- }
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onEventMainThread(reuse: EBReuse) {
- if ("Refresh" == reuse.type) {
- val settings = Config.getSettings()
- if (settings != null && !settings.showCommunityEntrance()) {
- mBinding.mainTabCommunity.visibility = View.GONE
- } else {
- mBinding.mainTabCommunity.visibility = View.VISIBLE
- }
- } else if (Constants.EB_REALNAME_RESULT == reuse.type) {
- updateRealNameErrorContainer()
- }
- }
-
- private fun updateRealNameErrorContainer() {
- val deviceCertificationInfoString =
- SPUtils.getString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + HaloApp.getInstance().gid)
-
- // 未点过关闭按钮并且处于实名认证失败状态的,显示提示 view
- if (!SPUtils.getBoolean(Constants.SP_REALNAME_ERROR_HINT_IGNORED)
- && !TextUtils.isEmpty(deviceCertificationInfoString)
- ) {
- val entity: UserInfoEntity? = deviceCertificationInfoString.toObject()
- if (entity?.idCard != null && entity.idCard!!.status == 2) {
- mBinding.realNameErrorContainer.visibility = View.VISIBLE
- mBinding.realNameErrorCloseIv.enlargeTouchArea(100)
- mBinding.realNameErrorCloseIv.setOnClickListener {
- SPUtils.setBoolean(Constants.SP_REALNAME_ERROR_HINT_IGNORED, true)
- mBinding.realNameErrorContainer.visibility = View.GONE
- }
- mBinding.realNameErrorContainer.setOnClickListener {
- startActivity(ShellActivity.getIntent(requireActivity(), ShellActivity.Type.REAL_NAME_INFO, null))
- }
- } else {
- mBinding.realNameErrorContainer.visibility = View.GONE
- }
- }
- }
-
- fun setCurrentItem(page: Int) {
- mViewPager.setCurrentItem(page, false)
- changeColor(page)
- }
-
- override fun onHandleBackPressed(): Boolean {
- if (mFourthFragment is HomeVideoFragment && (mFourthFragment as HomeVideoFragment).getCurrentFragment() != null) {
- return (mFourthFragment!! as HomeVideoFragment).getCurrentFragment()!!.onHandleBackPressed()
- }
- if (mViewPager.currentItem == INDEX_VIDEO) {
- return mFourthFragment!!.onBackPressed()
- }
- if (mViewPager.currentItem == INDEX_HOME) {
- return mHomeFragment!!.onBackPressed()
- }
- if (mViewPager.currentItem == INDEX_GAME) {
- return mGameWrapperFragment!!.onBackPressed()
- }
- return if (mViewPager.currentItem == INDEX_BBS) {
- mCommunityHomeFragment!!.onBackPressed()
- } else false
- }
-
- override fun onDarkModeChanged() {
- super.onDarkModeChanged()
- changeColor(mViewPager.currentItem)
- }
-
- companion object {
- const val INDEX_HOME = 0
- const val INDEX_GAME = 1
- const val INDEX_BBS = 2
- const val INDEX_VIDEO = 3
- const val INDEX_PERSONAL = 4
-
- const val EB_MAIN_SCROLL_TOP = "main_scroll_top"
- const val WRAPPER_FRAGMENT_NAME = "WrapperFragmentName"
- }
-}
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperRepository.kt b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperRepository.kt
deleted file mode 100644
index 275a9b2d7c..0000000000
--- a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperRepository.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.gh.gamecenter.fragment
-
-import android.annotation.SuppressLint
-import androidx.lifecycle.MutableLiveData
-import com.gh.common.util.HomeBottomBarHelper
-import com.gh.gamecenter.BuildConfig
-import com.gh.gamecenter.common.retrofit.BiResponse
-import com.gh.gamecenter.core.utils.SingletonHolder
-import com.gh.gamecenter.entity.SubjectRecommendEntity
-import com.gh.gamecenter.retrofit.RetrofitManager
-import com.halo.assistant.HaloApp
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
-import retrofit2.HttpException
-
-class MainWrapperRepository {
-
- private val mSensitiveApi = RetrofitManager.getInstance().api
-
- private val mGameNavBar = MutableLiveData()
- private val mVideoNavBar = MutableLiveData()
-
- fun getGameNavBarLiveData() = mGameNavBar
- fun getVideoNavBarLiveData() = mVideoNavBar
-
- @SuppressLint("CheckResult")
- fun getHomeNavBar() {
- mSensitiveApi.getHomeNavBarV2s(HaloApp.getInstance().channel, BuildConfig.VERSION_NAME)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : BiResponse>() {
- override fun onSuccess(data: List) {
- var isVideoConfigurated = false
- data.forEach {
- if (it.position == TAB_GAME_POSITION) {
- HomeBottomBarHelper.updateDefaultGameBarData(it)
- mGameNavBar.postValue(it)
- } else if (it.position == TAB_VIDEO_POSITION) {
- isVideoConfigurated = true
- HomeBottomBarHelper.updateDefaultVideoBarData(it)
- mVideoNavBar.postValue(it)
- }
- }
- // 没有配置底部tab第4位时默认展示视频tab
- if (!isVideoConfigurated) {
- val defaultVideoEntity = HomeBottomBarHelper.getDefaultVideoEntity()
- HomeBottomBarHelper.updateDefaultVideoBarData(defaultVideoEntity)
- mVideoNavBar.postValue(defaultVideoEntity)
- }
- }
-
- override fun onFailure(exception: Exception) {
- if (exception is HttpException && exception.code() == 404) {
- mGameNavBar.postValue(null)
- HomeBottomBarHelper.updateDefaultGameBarData(SubjectRecommendEntity())
-
- val defaultVideoEntity = HomeBottomBarHelper.getDefaultVideoEntity()
- mVideoNavBar.postValue(defaultVideoEntity)
- HomeBottomBarHelper.updateDefaultVideoBarData(defaultVideoEntity)
- } else {
- mGameNavBar.postValue(HomeBottomBarHelper.getDefaultGameBarData())
- mVideoNavBar.postValue(HomeBottomBarHelper.getDefaultVideoData())
- }
- }
- })
- }
-
-
- companion object : SingletonHolder({ MainWrapperRepository() }) {
- const val TAB_GAME_POSITION = 2
- const val TAB_VIDEO_POSITION = 4
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperViewModel.kt b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperViewModel.kt
deleted file mode 100644
index 30030d9cb0..0000000000
--- a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperViewModel.kt
+++ /dev/null
@@ -1,228 +0,0 @@
-package com.gh.gamecenter.fragment
-
-import android.annotation.SuppressLint
-import android.app.Application
-import android.preference.PreferenceManager
-import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-import com.alibaba.android.arouter.launcher.ARouter
-import com.gh.common.util.CheckLoginUtils
-import com.gh.common.util.PackageUtils
-import com.gh.gamecenter.common.constant.Constants
-import com.gh.gamecenter.common.constant.RouteConsts
-import com.gh.gamecenter.common.entity.SimpleGameEntity
-import com.gh.gamecenter.common.retrofit.BiResponse
-import com.gh.gamecenter.common.retrofit.Response
-import com.gh.gamecenter.core.provider.IFloatingWindowProvider
-import com.gh.gamecenter.core.utils.SPUtils
-import com.gh.gamecenter.entity.DialogEntity
-import com.gh.gamecenter.entity.SubjectRecommendEntity
-import com.gh.gamecenter.feature.entity.GameEntity
-import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
-import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
-import com.gh.gamecenter.login.user.UserManager
-import com.gh.gamecenter.retrofit.RetrofitManager
-import com.halo.assistant.HaloApp
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
-import okhttp3.MediaType
-import okhttp3.RequestBody
-import okhttp3.ResponseBody
-import org.json.JSONObject
-import retrofit2.HttpException
-
-class MainWrapperViewModel(application: Application, repository: MainWrapperRepository) :
- AndroidViewModel(application) {
- private val mApi = RetrofitManager.getInstance().api
- private val mSensitiveApi = RetrofitManager.getInstance().api
-
- val gameNavBar: MutableLiveData = repository.getGameNavBarLiveData()
- val videoNavBar: MutableLiveData = repository.getVideoNavBarLiveData()
-
- val welcomeDialog = MutableLiveData()
- val reserveDialog = MutableLiveData?>()
- val privacyPolicyDialog = MutableLiveData()
- val accelerateNotificationPopup = MutableLiveData?>()
- val floatingWindow = MutableLiveData?>()
-
- /**
- * 请求各种弹窗的数据
- */
- fun requestAllDialogData() {
- requestOpeningData()
- requestReserveDialog()
- requestAccelerateNotificationPopup()
- requestFloatingWindowList()
- }
-
- /**
- * 获取弹窗
- */
- @SuppressLint("CheckResult")
- private fun requestOpeningData() {
-
- val sp = PreferenceManager.getDefaultSharedPreferences(getApplication())
-
- val lastId = SPUtils.getString(sp, Constants.SP_LAST_OPENING_ID, "")
- val lastTime = SPUtils.getLong(sp, Constants.SP_LAST_OPENING_TIME, 0)
- val openType = if (HaloApp.getInstance().isNewForThisVersion) "first" else "not_first_time"
-
- mSensitiveApi.getOpeningDialog(HaloApp.getInstance().channel, lastId, lastTime, openType)
- .subscribeOn(Schedulers.io())
- .subscribe(object : BiResponse() {
- override fun onSuccess(data: DialogEntity) {
- val welcomeDialogEntity = data.welcomeDialog
- val privacyPolicyDialogEntity = data.privacyPolicyDialog
-
- // 类型为游戏时判断是否本地已安装该游戏,已安装不弹弹窗
- if (welcomeDialogEntity != null) {
- updateWelcomeDialogData(null, welcomeDialogEntity)
- if (welcomeDialogEntity.type == "game") {
- if (welcomeDialogEntity.packages == null) {
- welcomeDialog.postValue(data.welcomeDialog)
- } else {
- for (packageName in data.welcomeDialog.packages!!) {
- if (PackageUtils.isInstalled(getApplication(), packageName)) {
- welcomeDialog.postValue(null)
- return
- }
- }
- welcomeDialog.postValue(data.welcomeDialog)
- }
- } else {
- welcomeDialog.postValue(data.welcomeDialog)
- }
- }
-
- // 全新安装忽略隐私弹窗
- if (privacyPolicyDialogEntity != null) {
- val id = privacyPolicyDialogEntity.id
- val lastAcceptedId = SPUtils.getString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, "")
- if (HaloApp.getInstance().isBrandNewInstall) {
- SPUtils.setString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, id)
- privacyPolicyDialog.postValue(null)
- } else {
- if (id != lastAcceptedId) {
- privacyPolicyDialog.postValue(privacyPolicyDialogEntity)
- } else {
- privacyPolicyDialog.postValue(null)
- }
- }
- } else {
- privacyPolicyDialog.postValue(null)
- }
- }
-
- override fun onFailure(exception: Exception) {
- privacyPolicyDialog.postValue(null)
- }
- })
- }
-
- @SuppressLint("CheckResult")
- private fun requestReserveDialog() {
- if (CheckLoginUtils.isLogin()) {
- mApi.getReserveDialog(UserManager.getInstance().userId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : BiResponse>() {
- override fun onSuccess(data: List) {
- reserveDialog.postValue(data)
- }
-
- override fun onFailure(exception: Exception) {
- reserveDialog.postValue(null)
- }
- })
- } else {
- reserveDialog.postValue(null)
- }
- }
-
- fun requestAccelerateNotificationPopup() {
- if (CheckLoginUtils.isLogin()) {
- mApi.getAccelerateNotificationPopup(UserManager.getInstance().userId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response>() {
- override fun onResponse(response: List?) {
- super.onResponse(response)
- accelerateNotificationPopup.postValue(response)
- }
-
- override fun onFailure(e: HttpException?) {
- super.onFailure(e)
- accelerateNotificationPopup.postValue(null)
- }
- })
- } else {
- accelerateNotificationPopup.postValue(null)
- }
- }
-
- private fun requestFloatingWindowList() {
- val floatingWindowProvider =
- ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
- .navigation() as? IFloatingWindowProvider
-
- floatingWindowProvider?.getFloatingWindowOnly { anies, throwable ->
- if (anies != null) {
- updateWelcomeDialogData(anies as ArrayList, null)
- floatingWindow.postValue(anies)
- } else if (throwable != null) {
- floatingWindow.postValue(arrayListOf())
- }
- }
- }
-
- /**
- * 更新启动弹窗是否需要显示消失动画的标记
- * 当启动弹窗绑定的 windowId 与右下角悬浮窗的第一个 window 的 id 一样时才显示消失动画
- */
- private fun updateWelcomeDialogData(
- floatingWindowList: ArrayList?,
- welcomeDialogEntity: WelcomeDialogEntity?
- ) {
- val finalFloatingWindowList = floatingWindowList ?: floatingWindow.value
- val finalWelcomeDialogEntity = welcomeDialogEntity ?: welcomeDialog.value
-
- if (finalFloatingWindowList != null && finalWelcomeDialogEntity != null) {
- if (finalFloatingWindowList.firstOrNull()?.id == finalWelcomeDialogEntity.floatingWindowId) {
- finalWelcomeDialogEntity.shouldShowExitAnimation = true
- }
- }
- }
-
- fun postMessageRead(messageId: String) {
- val jsonObject = JSONObject()
- jsonObject.put("type", "system_message")
- val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
- RetrofitManager.getInstance().api.postMessageRead(UserManager.getInstance().userId, messageId, body)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response() {
- })
- }
-
- /**
- * 特殊渠道隐藏视频 tab
- */
- fun shouldHideVideoTab(): Boolean {
- val channelInInteger = HaloApp.getInstance().channel.toIntOrNull()
- return if (channelInInteger == null) false else channelInInteger in 1001..1050
- }
-
- class Factory(
- private val mApplication: Application,
- ) : ViewModelProvider.NewInstanceFactory() {
- override fun create(modelClass: Class): T {
- return MainWrapperViewModel(mApplication, MainWrapperRepository.getInstance()) as T
- }
- }
-
- companion object {
- const val SHOULD_SHOW_OPENING_DIALOG = "show_opening_dialog"
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/ReloadFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/ReloadFragment.kt
new file mode 100644
index 0000000000..129e3a338e
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/fragment/ReloadFragment.kt
@@ -0,0 +1,47 @@
+package com.gh.gamecenter.fragment
+
+import android.os.Bundle
+import android.view.View
+import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
+import com.gh.gamecenter.common.utils.observeNonNull
+import com.gh.gamecenter.common.utils.viewModelProviderFromParent
+import com.gh.gamecenter.core.utils.DisplayUtils
+import com.gh.gamecenter.databinding.FragmentReloadBinding
+import com.gh.gamecenter.wrapper.MainWrapperRepository
+import com.gh.gamecenter.wrapper.MainWrapperViewModel
+import com.halo.assistant.HaloApp
+
+class ReloadFragment: BaseLazyFragment() {
+
+ private val mBinding by lazy { FragmentReloadBinding.inflate(layoutInflater) }
+ private val mViewModel: MainWrapperViewModel by lazy { viewModelProviderFromParent(MainWrapperViewModel.Factory(HaloApp.getInstance())) }
+
+ override fun getLayoutId(): Int = 0
+ override fun getInflatedLayout(): View = mBinding.root
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mBinding.reuseLoading.root.visibility = View.VISIBLE
+ mBinding.reuseNoConnection.connectionReloadTv.setOnClickListener {
+ MainWrapperRepository.getInstance().getDataUnion()
+ mBinding.reuseNoConnection.root.visibility = View.GONE
+ mBinding.reuseLoading.root.visibility = View.VISIBLE
+ }
+ mViewModel.errorLiveData.observeNonNull(this) {
+ mBinding.reuseNoConnection.root.visibility = View.VISIBLE
+ mBinding.reuseLoading.root.visibility = View.GONE
+ }
+ }
+
+ override fun onFragmentFirstVisible() {
+ super.onFragmentFirstVisible()
+ mBaseHandler.post { DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn) }
+ }
+
+ override fun onDarkModeChanged() {
+ super.onDarkModeChanged()
+ if (isSupportVisible) {
+ DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolWrapperFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolWrapperFragment.java
index 26f19fd4fd..4669dbbebe 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolWrapperFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolWrapperFragment.java
@@ -8,6 +8,7 @@ import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.gh.common.constant.Config;
+import com.gh.common.util.ViewPagerFragmentHelper;
import com.gh.gamecenter.R;
import com.gh.gamecenter.common.base.fragment.LazyFragment;
import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
@@ -53,7 +54,7 @@ public class SearchToolWrapperFragment extends LazyFragment {
try {
Bundle arguments = getArguments();
if (arguments != null) {
- String className = Objects.requireNonNull(arguments.getString(MainWrapperFragment.WRAPPER_FRAGMENT_NAME));
+ String className = Objects.requireNonNull(arguments.getString(ViewPagerFragmentHelper.WRAPPER_FRAGMENT_NAME));
mContentFragment = contentFragment != null ? contentFragment : (Fragment) Class.forName(className).newInstance();
Bundle bundle = new Bundle();
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
index 7fa3803dca..6099ee439b 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/fragment/SearchToolbarFragment.java
@@ -213,8 +213,8 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
new MessageUnreadViewModel.Factory(HaloApp.getInstance().getApplication())).get(MessageUnreadViewModel.class);
mUnreadViewModel.getMessageCenterUnreadCountLiveData().observe(this, this::setMessageUnread);
- mDownloadHintTv.setTypeface(Typeface.createFromAsset(requireContext().getAssets(), "fonts/d_din_bold_only_number.ttf"));
- mMessageUnread.setTypeface(Typeface.createFromAsset(requireContext().getAssets(), "fonts/d_din_bold_only_number.ttf"));
+ mDownloadHintTv.setTypeface(Typeface.createFromAsset(requireContext().getAssets(), Constants.DIN_FONT_PATH));
+ mMessageUnread.setTypeface(Typeface.createFromAsset(requireContext().getAssets(), Constants.DIN_FONT_PATH));
}
private void setMessageUnread(int unreadCount) {
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/UpdateDialogFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/UpdateDialogFragment.kt
new file mode 100644
index 0000000000..f9ca0a7041
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/fragment/UpdateDialogFragment.kt
@@ -0,0 +1,333 @@
+package com.gh.gamecenter.fragment
+
+import android.annotation.SuppressLint
+import android.app.Dialog
+import android.content.Context
+import android.content.DialogInterface
+import android.os.Bundle
+import android.text.Html
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.PackageInstaller
+import com.gh.download.DownloadManager
+import com.gh.gamecenter.R
+import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
+import com.gh.gamecenter.common.utils.*
+import com.gh.gamecenter.common.view.CustomLinkMovementMethod
+import com.gh.gamecenter.core.AppExecutor
+import com.gh.gamecenter.core.utils.*
+import com.gh.gamecenter.databinding.AppUpdateHintDialogBinding
+import com.gh.gamecenter.databinding.AppUpdatingDialogBinding
+import com.gh.gamecenter.databinding.DialogUpdateBinding
+import com.gh.gamecenter.entity.AppEntity
+import com.gh.gamecenter.update.UpdateHelper
+import com.lightgame.download.DataWatcher
+import com.lightgame.download.DownloadEntity
+import com.lightgame.download.DownloadStatus
+import java.text.DecimalFormat
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.math.roundToInt
+
+/**
+ * 更新弹窗 DialogFragment
+ */
+class UpdateDialogFragment : BaseDialogFragment() {
+
+ private var mUpdateEntity: AppEntity? = null
+ private var mDismissCallback: EmptyCallback? = null
+ private val mIsDismissByTouchInside = AtomicBoolean(false)
+ private val mBinding by lazy { DialogUpdateBinding.inflate(layoutInflater) }
+
+ private var mIsDisplayingDownloadingStyle = false // 是否正在显示更新中样式
+
+ private val mDataWatcher = object : DataWatcher() {
+ override fun onDataChanged(downloadEntity: DownloadEntity) {
+ if (downloadEntity.name.contains("光环助手")) {
+ if (mIsDisplayingDownloadingStyle) {
+ updateDownloadingView(
+ mBinding.updatingContainerView,
+ downloadEntity,
+ mUpdateEntity!!
+ )
+ } else {
+ if (DownloadStatus.done == downloadEntity.status) {
+ updateUpdateHintView(
+ mBinding.updateHintContainerView,
+ mUpdateEntity!!,
+ UpdateHelper.isUpdateFileDownloaded(mUpdateEntity!!)
+ )
+ }
+ }
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ if (savedInstanceState != null) {
+ dismiss()
+ return
+ }
+
+ DownloadManager.getInstance().addObserver(mDataWatcher)
+
+ mUpdateEntity = arguments?.getParcelable(UPDATE_ENTITY)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ showUpdateHintStyle(requireContext(), mUpdateEntity!!)
+
+ return mBinding.root
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return super.onCreateDialog(savedInstanceState).apply {
+ val cancelable = !mUpdateEntity!!.isForce
+
+ setCancelable(cancelable)
+ setCanceledOnTouchOutside(cancelable)
+ this@UpdateDialogFragment.isCancelable = cancelable
+ }
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ super.onDismiss(dialog)
+
+ if (!mIsDismissByTouchInside.get()) {
+ SensorsBridge.trackVersionUpdateDialogClick(
+ buttonName = "关闭弹窗",
+ keyDialogReminderTime = mUpdateEntity?.alert,
+ keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
+ )
+ }
+
+ mDismissCallback?.onCallback()
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+
+ DownloadManager.getInstance().removeObserver(mDataWatcher)
+ }
+
+ /**
+ * 显示更新弹窗(提示样式)
+ * @param context 上下文
+ * @param updateEntity 更新实体
+ */
+ private fun showUpdateHintStyle(context: Context, updateEntity: AppEntity) {
+ mIsDisplayingDownloadingStyle = false
+
+ val updateHintBinding = mBinding.updateHintContainerView
+ val updatingBinding = mBinding.updatingContainerView
+
+ updatingBinding.root.visibility = View.GONE
+ updateHintBinding.root.visibility = View.VISIBLE
+
+ val cancelUpdateTextView = updateHintBinding.cancel
+ val confirmTextView = updateHintBinding.confirm
+
+ if (!TextUtils.isEmpty(updateEntity.spareLink)) {
+ val defaultText = "部分设备若无法更新安装,请前往官网进行下载安装:"
+ val externalTextTv = updateHintBinding.externalTextTv
+ val builder = SpanBuilder(defaultText + updateEntity.spareLink)
+ .click(
+ context,
+ defaultText.length,
+ defaultText.length + updateEntity.spareLink!!.length,
+ R.color.text_theme,
+ false
+ ) {
+ DirectUtils.directToExternalBrowser(context, updateEntity.spareLink!!)
+ }
+ .build()
+ externalTextTv.text = builder
+ externalTextTv.movementMethod = CustomLinkMovementMethod.getInstance()
+ externalTextTv.visibility = View.VISIBLE
+ }
+
+ val updateFileIsDownloaded = UpdateHelper.isUpdateFileDownloaded(updateEntity)
+
+ if (NetworkUtils.isWifiConnected(context)) {
+ if (!updateFileIsDownloaded) {
+ updateUpdateHintView(updateHintBinding, updateEntity, false)
+ UpdateHelper.createUpdate(updateEntity, true)
+ } else {
+ updateUpdateHintView(updateHintBinding, updateEntity, true)
+ }
+ } else {
+ updateUpdateHintView(updateHintBinding, updateEntity, updateFileIsDownloaded)
+ }
+
+ updateHintBinding.desc.text = Html.fromHtml(updateEntity.content)
+ updateHintBinding.version.text = java.lang.String.format("版本%s更新日志:", updateEntity.version)
+ updateHintBinding.size.text = java.lang.String.format("大小 %s", updateEntity.size)
+
+ cancelUpdateTextView.setOnClickListener {
+ val cancelText: String = cancelUpdateTextView.text.toString()
+ SensorsBridge.trackVersionUpdateDialogClick(
+ buttonName = cancelText,
+ keyDialogReminderTime = mUpdateEntity?.alert,
+ keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
+ )
+ mIsDismissByTouchInside.set(true)
+ if (updateEntity.isForce) {
+ AppExecutor.uiExecutor.executeWithDelay({ UpdateHelper.exitApp() }, 500L)
+ } else {
+ dismiss()
+ }
+ }
+
+ confirmTextView.setOnClickListener {
+ // 产品不接受显示下载完成文案从立即更新变为立即安装,所以文案为立即更新时一律不执行安装
+ if (UpdateHelper.isUpdateFileDownloaded(updateEntity) && confirmTextView.text != "立即更新") {
+ DataLogUtils.uploadUpgradeLog(context, "install") //上传更新安装数据
+ PackageInstaller.install(context, false, UpdateHelper.getUpdateDownloadPath(updateEntity), null)
+ } else {
+ showDownloadingStyle(updateEntity)
+ }
+
+ val buttonName: String = confirmTextView.text.toString()
+ SensorsBridge.trackVersionUpdateDialogClick(
+ buttonName = buttonName,
+ keyDialogReminderTime = mUpdateEntity?.alert,
+ keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
+ )
+ }
+
+ SensorsBridge.trackVersionUpdateDialogShow(
+ keyDialogReminderTime = mUpdateEntity?.alert,
+ keyDialogClose = if (mUpdateEntity?.isForce == true) "关闭且强退" else "仅关闭"
+ )
+
+ DataLogUtils.uploadUpgradeLog(context, "notice") //上传更新通知弹窗数据
+ }
+
+ /**
+ * 更新更新提示的文案
+ */
+ private fun updateUpdateHintView(
+ binding: AppUpdateHintDialogBinding,
+ updateEntity: AppEntity,
+ isUpdateDownloaded: Boolean
+ ) {
+ val confirmText = if (isUpdateDownloaded) "立即安装" else "立即更新"
+ val cancelText = if (isUpdateDownloaded) {
+ if (updateEntity.isForce) "暂不安装,退出光环" else "暂不安装"
+ } else {
+ if (updateEntity.isForce) "暂不更新,退出光环" else "暂不更新"
+ }
+
+ binding.confirm.text = confirmText
+ binding.downloadedHint.visibility = if (isUpdateDownloaded) View.VISIBLE else View.GONE
+ binding.cancel.text = cancelText
+ }
+
+ /**
+ * 显示更新下载中弹窗
+ */
+ private fun showDownloadingStyle(updateEntity: AppEntity) {
+ mIsDisplayingDownloadingStyle = true
+
+ val updatingBinding = mBinding.updatingContainerView
+ val updateHintBinding = mBinding.updateHintContainerView
+
+ updatingBinding.root.visibility = View.VISIBLE
+ updateHintBinding.root.visibility = View.GONE
+
+ updatingBinding.appTvCancel.setOnClickListener {
+ DownloadManager.getInstance().cancel(updateEntity.url)
+ if (updateEntity.isForce) {
+ UpdateHelper.exitApp()
+ } else {
+ dismiss()
+ }
+ }
+
+ if (NetworkUtils.isMobileConnected(context)) {
+ ToastUtils.toast("当前使用移动数据进行下载")
+ }
+
+ UpdateHelper.createUpdate(updateEntity, false)
+ }
+
+ @SuppressLint("SetTextI18n")
+ private fun updateDownloadingView(
+ dialogBinding: AppUpdatingDialogBinding,
+ downloadEntity: DownloadEntity,
+ updateEntity: AppEntity
+ ) {
+ // 被取消任务的状态不用来更新页面
+ if (DownloadStatus.cancel != downloadEntity.status) {
+ val size = (downloadEntity.progress / 1024) / 1024F
+ val df = DecimalFormat("0.00")
+ dialogBinding.size.text = (df.format(size) + "MB")
+ dialogBinding.remain.text = String.format(
+ "剩余%s",
+ SpeedUtils.getRemainSecondTime(
+ downloadEntity.size,
+ downloadEntity.progress,
+ downloadEntity.speed * 1024
+ )
+ )
+ dialogBinding.progress.progress = (downloadEntity.percent * 10).roundToInt()
+
+ val width = dialogBinding.progress.width
+ val marLeft = (downloadEntity.percent / 100 * width)
+ val anchorLp = dialogBinding.progressAnchor.layoutParams
+ if (anchorLp is ConstraintLayout.LayoutParams) {
+ anchorLp.leftMargin = marLeft.roundToInt()
+ dialogBinding.progressAnchor.layoutParams = anchorLp
+ }
+
+ val fillingLp = dialogBinding.progressFilling.layoutParams
+ fillingLp.width = (marLeft + DisplayUtils.dip2px(5F)).toInt()
+ dialogBinding.progressFilling.layoutParams = fillingLp
+
+ dialogBinding.percent.text = "${downloadEntity.percent} %"
+ }
+
+ if (DownloadStatus.done == downloadEntity.status) {
+ DownloadManager.getInstance().cancel(downloadEntity.url, false, true, false)
+ try {
+ dismiss()
+ } catch (ignored: IllegalArgumentException) {
+ // do nothing
+ }
+ if (updateEntity.isForce) {
+ AppExecutor.uiExecutor.executeWithDelay({ UpdateHelper.exitApp() }, 1000L)
+ }
+ } else if (DownloadStatus.neterror == downloadEntity.status) {
+ ToastUtils.toast("网络错误,请稍后重试")
+ } else if (DownloadStatus.diskisfull == downloadEntity.status) {
+ ToastUtils.toast("磁盘已满,请清理后重试")
+ } else if (DownloadStatus.diskioerror == downloadEntity.status) {
+ ToastUtils.toast("磁盘 IO 异常,请稍后重试")
+ } else if (DownloadStatus.timeout == downloadEntity.status) {
+ ToastUtils.toast("请求超时,请稍后重试")
+ } else if (DownloadStatus.notfound == downloadEntity.status) {
+ ToastUtils.toast("下载链接异常,请稍后重试")
+ } else if (DownloadStatus.hijack == downloadEntity.status) {
+ ToastUtils.toast("网络劫持,请稍后重试")
+ }
+ }
+
+ companion object {
+ const val UPDATE_ENTITY = "update_entity"
+
+ fun newInstance(updateEntity: AppEntity, dismissCallback: EmptyCallback): UpdateDialogFragment {
+ val fragment = UpdateDialogFragment()
+ val bundle = Bundle()
+ bundle.putParcelable(UPDATE_ENTITY, updateEntity)
+ fragment.arguments = bundle
+ fragment.mDismissCallback = dismissCallback
+ return fragment
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/BaseGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/BaseGameViewModel.kt
index a89c31d72d..3c481c7567 100644
--- a/app/src/main/java/com/gh/gamecenter/game/BaseGameViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/BaseGameViewModel.kt
@@ -4,7 +4,6 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
-import com.gh.common.util.GameSubstituteRepositoryHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.entity.ExposureEntity
diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt
index 3cab9bb465..8976278cbe 100644
--- a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt
@@ -1,7 +1,6 @@
package com.gh.gamecenter.game
import android.graphics.Color
-import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
@@ -32,13 +31,13 @@ import com.gh.gamecenter.eventbus.EBDiscoverChanged
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBUISwitch
-import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.data.GameItemData
import com.gh.gamecenter.home.test_v2.HomeGameTestV2ViewModel
import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolder
import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolderWatcher
import com.gh.gamecenter.home.test_v2.addViewHolderWatcher
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
+import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
@@ -58,8 +57,6 @@ open class GameFragment : LazyFragment() {
private lateinit var mExposureListener: ExposureListener
private lateinit var mScrollCalculatorHelper: ScrollCalculatorHelper
- private var mIsFromHomeToolbarWrapper = false
-
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
mListAdapter.notifyItemByDownload(downloadEntity)
@@ -76,11 +73,6 @@ open class GameFragment : LazyFragment() {
override fun getRealLayoutId() = R.layout.fragment_game
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- mIsFromHomeToolbarWrapper = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_TOOLBAR_WRAPPER, false) ?: false
- }
-
override fun onFragmentFirstVisible() {
mViewModel = provideViewModel()
mViewModel.entrance = mEntrance
@@ -92,10 +84,6 @@ open class GameFragment : LazyFragment() {
super.onFragmentFirstVisible()
- if (mIsFromHomeToolbarWrapper) {
- initMenu(R.menu.menu_download)
- }
-
mViewModel.loadStatus.observe(this) {
if (it != null) {
mBinding.gameRefresh.isRefreshing = false
@@ -333,18 +321,10 @@ open class GameFragment : LazyFragment() {
if (::mListAdapter.isInitialized && "Refresh" == reuse.type) {
mListAdapter.notifyDataSetChanged()
}
- (mViewModel as GameViewModel).refreshRecentVGameIfNeeded()
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onEventMainThread(busNine: EBUISwitch) {
- if (::mLayoutManager.isInitialized &&
- MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from &&
- MainWrapperFragment.INDEX_GAME == busNine.position
- ) {
- mBinding.gameList.stopScroll()
- mLayoutManager.scrollToPosition(0)
+ if(::mViewModel.isInitialized){
+ (mViewModel as GameViewModel).refreshRecentVGameIfNeeded()
}
+
}
@Subscribe(threadMode = ThreadMode.MAIN)
diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
index e624dbcf6c..1f4868bce3 100644
--- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt
@@ -11,7 +11,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import com.gh.common.constant.Config
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.IExposable
import com.gh.common.util.*
@@ -930,7 +929,7 @@ class GameFragmentAdapter(
SensorsBridge.trackEvent("RecommendedLocationClick", json {
"position" to clickedPosition
- "Recommended_location_name" to if (Config.isShowPlugin()) entity.name else entity.nameNormal
+ "Recommended_location_name" to entity.name
"location" to "版块"
"block_name" to blockData?.text
"block_id" to blockData?.link
@@ -951,6 +950,7 @@ class GameFragmentAdapter(
"",
mViewModel.blockData?.link ?: "",
mViewModel.blockData?.text ?: "",
+ "",
exposureEvent
)
@@ -1071,12 +1071,12 @@ class GameFragmentAdapter(
source = listOf(
ExposureSource(
"推荐入口",
- if (Config.isShowPlugin()) entity.name ?: "" else entity.nameNormal ?: ""
+ entity.name ?: ""
)
)
)
event.payload.controlType = "推荐入口"
- event.payload.controlName = if (Config.isShowPlugin()) entity.name else entity.nameNormal
+ event.payload.controlName = entity.name
event.payload.controlLinkType = entity.type
event.payload.controlLinkName = entity.text
entity.exposureEvent = event
@@ -1124,19 +1124,19 @@ class GameFragmentAdapter(
ImageUtils.display(entranceIcon4, if (subjectDigestList.size > 3) subjectDigestList[3].icon else "")
ImageUtils.display(entranceIcon5, if (subjectDigestList.size > 4) subjectDigestList[4].icon else "")
entranceName1.text = if (subjectDigestList.isNotEmpty()) {
- if (Config.isShowPlugin()) subjectDigestList[0].name else subjectDigestList[0].nameNormal
+ subjectDigestList[0].name
} else "推荐入口"
entranceName2.text = if (subjectDigestList.size > 1) {
- if (Config.isShowPlugin()) subjectDigestList[1].name else subjectDigestList[1].nameNormal
+ subjectDigestList[1].name
} else "推荐入口"
entranceName3.text = if (subjectDigestList.size > 2) {
- if (Config.isShowPlugin()) subjectDigestList[2].name else subjectDigestList[2].nameNormal
+ subjectDigestList[2].name
} else "推荐入口"
entranceName4.text = if (subjectDigestList.size > 3) {
- if (Config.isShowPlugin()) subjectDigestList[3].name else subjectDigestList[3].nameNormal
+ subjectDigestList[3].name
} else "推荐入口"
entranceName5.text = if (subjectDigestList.size > 4) {
- if (Config.isShowPlugin()) subjectDigestList[4].name else subjectDigestList[4].nameNormal
+ subjectDigestList[4].name
} else "推荐入口"
}
@@ -1279,7 +1279,7 @@ class GameFragmentAdapter(
)
}
- holder.bindGameItem(gameEntity, subjectData.isShowSuffix, subjectData.briefStyle)
+ holder.bindGameItem(gameEntity, subjectData.briefStyle)
holder.initServerType(gameEntity)
runOnIoThread(true) {
@@ -2071,4 +2071,4 @@ class GameFragmentAdapter(
}
-class GameAndPosition(val entity: GameEntity?, val position: Int, val index: Int = 0)
+data class GameAndPosition(val entity: GameEntity?, val position: Int, val index: Int = 0)
diff --git a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt
index 6ed6db1b5a..2ff1c9b7cc 100644
--- a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt
@@ -73,10 +73,10 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
private var mSubjectGameIdList = hashSetOf()
init {
- if (blockData == null) {
- // 读取默认板块
- blockData = HomeBottomBarHelper.getDefaultGameBarData()
- }
+// if (blockData == null) {
+// // 读取默认板块
+// blockData = HomeBottomBarHelper.getDefaultGameBarData()
+// }
if (!blockData?.link.isNullOrEmpty()) {
initData()
@@ -722,8 +722,6 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
if (!data.isNullOrEmpty()) {
for (game in data) {
mSubjectGameIdList.add(game.id)
- // 应用专题是否显示游戏名后缀的配置
- game.shouldShowNameSuffix = subjectEntity.showSuffix
}
}
@@ -845,7 +843,6 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
addGamePositionAndPackage(game)
@@ -877,8 +874,7 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
tag = subjectEntity.tag,
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
- briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
+ briefStyle = subjectEntity.briefStyle
)
game.outerSequence = index
game.sequence = i
@@ -909,7 +905,6 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
game.outerSequence = index
game.sequence = i
@@ -1065,7 +1060,6 @@ class GameViewModel(application: Application, override var blockData: SubjectRec
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
val itemDataGame = GameItemData()
itemDataGame.game = game
diff --git a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailAdapter.kt
index c6c133426f..7cebe3aa7f 100644
--- a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailAdapter.kt
@@ -7,21 +7,21 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.gh.common.exposure.IExposable
-import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
-import com.gh.gamecenter.common.utils.ImageUtils
-import com.gh.gamecenter.core.utils.MtaHelper
-import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.R
-import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.adapter.viewholder.GameColumnCollectionItemViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
-import com.gh.gamecenter.databinding.GameColumnCollectionItemBinding
+import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.entity.LinkEntity
-import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.SensorsBridge
+import com.gh.gamecenter.common.viewholder.FooterViewHolder
+import com.gh.gamecenter.core.utils.MtaHelper
+import com.gh.gamecenter.core.utils.PageSwitchDataHelper
+import com.gh.gamecenter.databinding.GameColumnCollectionItemBinding
+import com.gh.gamecenter.feature.exposure.ExposureEvent
class ColumnCollectionDetailAdapter(
context: Context,
@@ -31,7 +31,7 @@ class ColumnCollectionDetailAdapter(
private val mEntrance: String,
private val mBlockId: String,
private val mBlockName: String,
- private val mLocation: String
+ private val mStyle: String
) : ListAdapter(context), IExposable {
private var mExposureSparseArray = SparseArray()
@@ -84,7 +84,7 @@ class ColumnCollectionDetailAdapter(
mViewModel.columnCollection.value?.name ?: "", mViewModel.collectionId
)
SensorsBridge.trackColumnCollectionClick(
- location = mLocation,
+ location = "合集详情",
blockName = mBlockName,
blockId = mBlockId,
columnCollectionName = mViewModel.columnCollection.value?.name ?: "",
@@ -98,7 +98,10 @@ class ColumnCollectionDetailAdapter(
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
null,
mBasicExposureSourceList ?: arrayListOf(),
- arrayListOf(ExposureSource("游戏专题合集", "${mViewModel.getGameColumnCollectionName()}+${mViewModel.collectionId}"))
+ arrayListOf(
+ ExposureSource("合集详情", ""),
+ ExposureSource("专题", "${data.name}+${mStyle}+${data.link}")
+ )
).apply {
payload.outerSequence = mTabIndex
payload.sequence = position
diff --git a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt
index 317d012e42..32c5463720 100644
--- a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt
@@ -3,21 +3,16 @@ package com.gh.gamecenter.game.columncollection.detail
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProviders
-import androidx.recyclerview.widget.StaggeredGridLayoutManager
-import com.ethanhua.skeleton.Skeleton
-import com.gh.common.exposure.ExposureListener
-import com.gh.gamecenter.common.constant.Constants
-import com.gh.gamecenter.common.constant.EntranceConsts
-import com.gh.gamecenter.common.utils.dip2px
-import com.gh.gamecenter.common.utils.observeNonNull
-import com.gh.gamecenter.common.utils.toColor
-import com.gh.gamecenter.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
-import com.gh.gamecenter.databinding.FragmentColumnCollectionDetailBinding
+import com.gh.gamecenter.common.constant.EntranceConsts
+import com.gh.gamecenter.common.constant.EntranceConsts.KEY_SHOW_SUBJECT_TAB
import com.gh.gamecenter.common.entity.LinkEntity
-import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.common.utils.observeNonNull
+import com.gh.gamecenter.common.utils.toColor
+import com.gh.gamecenter.databinding.FragmentColumnCollectionDetailBinding
+import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.subject.tab.SubjectTabFragment
class ColumnCollectionDetailFragment : LazyListFragment() {
@@ -25,8 +20,6 @@ class ColumnCollectionDetailFragment : LazyListFragment? = null
@@ -34,6 +27,8 @@ class ColumnCollectionDetailFragment : LazyListFragment?) {
- if (mListViewModel.columnCollection.value?.style != "top") {
- super.onChanged(list)
- } else {
- if (list != null && list.isNotEmpty()) {
- showSubjectTab(list)
- }
+ if (list != null && list.isNotEmpty()) {
+ showSubjectTab(list)
}
}
@@ -114,9 +74,11 @@ class ColumnCollectionDetailFragment : LazyListFragment? = null
): Intent {
val bundle = Bundle()
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
@@ -53,6 +55,7 @@ class CommonCollectionDetailActivity : ToolBarActivity() {
bundle.putString(EntranceConsts.KEY_BLOCK_NAME, blockName)
bundle.putString(EntranceConsts.KEY_COLLECTION_ID, collectionId)
bundle.putString(EntranceConsts.KEY_LOCATION, "合集详情")
+ bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
return getTargetIntent(
context,
CommonCollectionDetailActivity::class.java,
diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailAdapter.kt
index c6b55d0ec1..abc3b8ac20 100644
--- a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailAdapter.kt
@@ -5,9 +5,9 @@ import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.common.exposure.IExposable
-import com.gh.common.util.*
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailOneItemViewHolder
import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailTwoItemViewHolder
@@ -15,13 +15,14 @@ import com.gh.gamecenter.adapter.viewholder.CommonCollectionImageTextItemViewHol
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
-import com.gh.gamecenter.common.utils.goneIf
-import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.SensorsBridge
+import com.gh.gamecenter.common.utils.goneIf
+import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.entity.CommonCollectionContentEntity
import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.exposure.ExposureEvent
class CommonCollectionDetailAdapter(
context: Context,
@@ -32,7 +33,7 @@ class CommonCollectionDetailAdapter(
val mLocation: String,
val mTabIndex: Int,
val mEntrance: String,
- private val mBasicExposureSource: List?
+ var basicExposureSource: List?
) : ListAdapter(context), IExposable {
private val mExposureEventSparseArray = SparseArray()
@@ -117,29 +118,29 @@ class CommonCollectionDetailAdapter(
)
}
- if (linkEntity.type == "game") {
- mExposureEventSparseArray.put(
- position,
- ExposureEvent.createEventWithSourceConcat(
- GameEntity(
- id = linkEntity.link,
- name = linkEntity.name
- ).also {
- it.sequence = position
- },
- basicSource = mBasicExposureSource ?: listOf(),
- listOf(
- ExposureSource(
- "内容合集",
- "${mViewModel.commonCollectionLiveData.value?.name}+${mViewModel.commonCollectionLiveData.value?.id}"
- ),
- ExposureSource("合集详情")
- ),
- ).apply {
- this.payload.outerSequence = mTabIndex
- }
- )
+ val commonCollectionEntity = mViewModel.commonCollectionLiveData.value
+ val gameEntity = if (linkEntity.type == "game") {
+ GameEntity(id = linkEntity.link, name = linkEntity.text)
+ } else {
+ GameEntity()
}
+ mExposureEventSparseArray.put(
+ position,
+ ExposureEvent.createEventWithSourceConcat(
+ gameEntity.also {
+ it.sequence = position
+ },
+ basicSource = basicExposureSource ?: listOf(),
+ listOf(
+ ExposureSource(
+ "通用内容合集",
+ "${commonCollectionEntity?.name ?: ""}+${commonCollectionEntity?.layoutChinese ?: ""}+${commonCollectionEntity?.id ?: ""}"
+ ), ExposureSource("合集详情")
+ ),
+ ).apply {
+ this.payload.outerSequence = mTabIndex
+ }
+ )
when (holder) {
is CommonCollectionDetailOneItemViewHolder -> {
diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailFragment.kt
index 630620d8ac..172e7fb8e5 100644
--- a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailFragment.kt
@@ -14,14 +14,14 @@ 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.constant.EntranceConsts
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.FixGridLayoutManager
import com.gh.gamecenter.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
-import com.gh.gamecenter.common.entity.LinkEntity
-import com.gh.gamecenter.common.exposure.ExposureSource
class CommonCollectionDetailFragment : LazyListFragment() {
@@ -52,7 +52,7 @@ class CommonCollectionDetailFragment : LazyListFragment {
if (mAdapter == null) {
- val exposureEvent =
+ val exposureSourceList =
requireArguments().getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
mAdapter = CommonCollectionDetailAdapter(
requireContext(),
@@ -63,7 +63,7 @@ class CommonCollectionDetailFragment : LazyListFragment {
+ val fragment = targetFragment as CustomCommonCollectionDetailFragment
+ return if (fragment.arguments != null) {
+ Pair(
+ fragment.requireArguments().getString(EntranceConsts.KEY_COLLECTION_ID) ?: "",
+ fragment.requireArguments().getString(EntranceConsts.KEY_BLOCK_ID) ?: ""
+ )
+ } else {
+ super.getBusinessId()
+ }
+ }
+
+ companion object {
+
+ fun getIntent(
+ context: Context,
+ collectionId: String,
+ layout: Int,
+ entrance: String = "",
+ exposureSourceList: ArrayList? = null
+ ): Intent {
+ val bundle = Bundle()
+ bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
+
+ bundle.putString(EntranceConsts.KEY_COLLECTION_ID, collectionId)
+ bundle.putString(EntranceConsts.KEY_LOCATION, "合集详情")
+ bundle.putInt(EntranceConsts.KEY_COMMON_CONTENT_COLLECTION_LAYOUT, layout)
+ bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
+ return getTargetIntent(
+ context,
+ CustomCommonCollectionDetailActivity::class.java,
+ CustomCommonCollectionDetailFragment::class.java,
+ bundle
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailAdapter.kt
new file mode 100644
index 0000000000..67e71a3f74
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailAdapter.kt
@@ -0,0 +1,205 @@
+package com.gh.gamecenter.game.commoncollection.detail
+
+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.IExposable
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.NewLogUtils
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailOneItemViewHolder
+import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailTwoItemHorizontalViewHolder
+import com.gh.gamecenter.adapter.viewholder.CommonCollectionDetailTwoItemViewHolder
+import com.gh.gamecenter.adapter.viewholder.CommonCollectionImageTextItemViewHolder
+import com.gh.gamecenter.common.baselist.ListAdapter
+import com.gh.gamecenter.common.constant.ItemViewType
+import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.common.utils.ImageUtils
+import com.gh.gamecenter.common.utils.SensorsBridge
+import com.gh.gamecenter.common.utils.goneIf
+import com.gh.gamecenter.common.utils.toBinding
+import com.gh.gamecenter.common.viewholder.FooterViewHolder
+import com.gh.gamecenter.entity.CommonCollectionContentEntity
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
+import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
+
+class CustomCommonCollectionDetailAdapter(
+ context: Context,
+ val layout: Int,
+ var collectionStyle: String,
+ val mViewModel: CustomCommonCollectionDetailViewModel,
+ val mLocation: String,
+ val mTabIndex: Int,
+ val mEntrance: String,
+ private val mBasicExposureSourceList: List?
+) : ListAdapter(context), IExposable {
+
+ private val mExposureEventSparseArray = SparseArray()
+
+ override fun areItemsTheSame(
+ oldItem: CommonCollectionContentEntity?,
+ newItem: CommonCollectionContentEntity?
+ ): Boolean {
+ return oldItem == newItem
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return if (viewType == ItemViewType.ITEM_BODY) {
+ when (collectionStyle) {
+ "1-1" -> CommonCollectionDetailOneItemViewHolder(parent.toBinding())
+ "1-2" -> if (layout == COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER ||
+ layout == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
+ ) {
+ CommonCollectionDetailTwoItemHorizontalViewHolder(parent.toBinding())
+ } else {
+ CommonCollectionDetailTwoItemViewHolder(parent.toBinding())
+ }
+
+ else -> CommonCollectionImageTextItemViewHolder(parent.toBinding())
+ }
+ } else {
+ FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return when (position) {
+ itemCount - 1 -> ItemViewType.ITEM_FOOTER
+ else -> ItemViewType.ITEM_BODY
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is FooterViewHolder) {
+ holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
+ return
+ }
+
+ val contentEntity = mEntityList[position]
+ val linkEntity = mEntityList[position].linkEntity
+
+ val listener: (v: View) -> Unit = {
+ DirectUtils.directToLinkPage(
+ mContext,
+ linkEntity,
+ "通用链接合集详情",
+ "",
+ mExposureEventSparseArray.get(position)
+ )
+ val commonLinkCollection = mViewModel.commonCollectionLiveData.value
+ NewLogUtils.logCommonCollectionClick(
+ commonLinkCollection?.id ?: "",
+ commonLinkCollection?.name ?: "",
+ "",
+ "",
+ mEntrance,
+ "合集详情",
+ linkEntity.title ?: "",
+ contentEntity.addedContent1 ?: "",
+ contentEntity.addedContent2 ?: "",
+ linkEntity.type ?: "",
+ linkEntity.text ?: "",
+ position + 1
+ )
+ NewLogUtils.logCommonCategoryDetailContentClick(
+ contentEntity?.title ?: "",
+ linkEntity.type ?: "",
+ linkEntity.link ?: "",
+ linkEntity.text ?: "",
+ commonLinkCollection?.name ?: "",
+ commonLinkCollection?.id ?: ""
+ )
+ SensorsBridge.trackLinkContentCollectionClick(
+ location = mLocation,
+ blockName = "",
+ blockId = "",
+ linkContentCollectionId = commonLinkCollection?.id ?: "",
+ linkContentCollectionName = commonLinkCollection?.name ?: "",
+ position = position,
+ linkType = linkEntity.type ?: "",
+ linkId = linkEntity.link ?: "",
+ linkText = linkEntity.text ?: "",
+ text = "通用内容"
+ )
+ }
+
+ val commonCollectionEntity = mViewModel.commonCollectionLiveData.value
+ val gameEntity = if (linkEntity.type == "game") {
+ GameEntity(id = linkEntity.link, name = linkEntity.text)
+ } else {
+ GameEntity()
+ }
+ mExposureEventSparseArray.put(
+ position,
+ ExposureEvent.createEventWithSourceConcat(
+ gameEntity.also {
+ it.sequence = position
+ },
+ basicSource = mBasicExposureSourceList ?: listOf(),
+ listOf(
+ ExposureSource(
+ "通用内容合集",
+ "${commonCollectionEntity?.name ?: ""}+${commonCollectionEntity?.layoutChinese ?: ""}+${commonCollectionEntity?.id ?: ""}"
+ ), ExposureSource("合集详情")
+ ),
+ ).apply {
+ this.payload.outerSequence = mTabIndex
+ }
+ )
+
+ when (holder) {
+ is CommonCollectionDetailOneItemViewHolder -> {
+ holder.binding.run {
+ ImageUtils.display(commonCollectionImage, contentEntity.image)
+ maskView.goneIf(contentEntity.title.isEmpty())
+ titleTv.text = contentEntity.title
+ root.setOnClickListener(listener)
+ }
+ }
+
+ is CommonCollectionDetailTwoItemViewHolder -> {
+ holder.binding.run {
+ ImageUtils.display(commonCollectionImage, contentEntity.image)
+ maskView.goneIf(contentEntity.title.isEmpty() && contentEntity.addedContent1.isNullOrEmpty())
+ titleTv.text = contentEntity.title
+ desTv.text = contentEntity.addedContent1
+ root.setOnClickListener(listener)
+ }
+ }
+
+ is CommonCollectionDetailTwoItemHorizontalViewHolder -> {
+ holder.binding.run {
+ ImageUtils.display(commonCollectionImage, contentEntity.image)
+ maskView.goneIf(contentEntity.title.isEmpty())
+ titleTv.text = contentEntity.title
+ root.setOnClickListener(listener)
+ }
+ }
+
+ is CommonCollectionImageTextItemViewHolder -> {
+ holder.binding.run {
+ ImageUtils.display(commonCollectionImage, contentEntity.image)
+ linkTitleTv.text = contentEntity.title
+ linkDes1.text = contentEntity.addedContent1
+ linkDes2.text = contentEntity.addedContent2
+
+ root.setOnClickListener(listener)
+ }
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT
+ }
+
+ override fun getEventByPosition(pos: Int): ExposureEvent? {
+ return mExposureEventSparseArray[pos]
+ }
+
+ override fun getEventListByPosition(pos: Int): List? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailFragment.kt
new file mode 100644
index 0000000000..f05831a844
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailFragment.kt
@@ -0,0 +1,172 @@
+package com.gh.gamecenter.game.commoncollection.detail
+
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
+import androidx.recyclerview.widget.RecyclerView
+import com.ethanhua.skeleton.Skeleton
+import com.gh.common.exposure.ExposureListener
+import com.gh.common.exposure.IExposable
+import com.gh.common.util.NewLogUtils
+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.constant.EntranceConsts
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.common.utils.dip2px
+import com.gh.gamecenter.common.utils.viewModelProvider
+import com.gh.gamecenter.common.view.FixGridLayoutManager
+import com.gh.gamecenter.common.view.GridSpacingItemDecoration
+import com.gh.gamecenter.common.view.VerticalItemDecoration
+import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
+import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
+
+class CustomCommonCollectionDetailFragment : LazyListFragment() {
+
+ private var mAdapter: CustomCommonCollectionDetailAdapter? = null
+ private var mCollectionStyle: String = ""
+ private lateinit var mViewModel: CustomCommonCollectionDetailViewModel
+ private var mExposureListener: ExposureListener? = null
+ private lateinit var mBinding: FragmentListBaseSkeletonBinding
+ private var mBlockId = ""
+ private var mBlockName = ""
+ private var mLocation = ""
+ private var mTabIndexValue = 0 // 在首页的 tab 位置
+ private var mLayout = COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
+
+ override fun getRealLayoutId(): Int = R.layout.fragment_list_base_skeleton
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mBlockId = requireArguments().getString(EntranceConsts.KEY_BLOCK_ID, "")
+ mBlockName = requireArguments().getString(EntranceConsts.KEY_BLOCK_NAME, "")
+ mLocation = requireArguments().getString(EntranceConsts.KEY_LOCATION, "")
+ mTabIndexValue = requireArguments().getInt(EntranceConsts.KEY_TAB_INDEX, -1)
+ mLayout = requireArguments().getInt(EntranceConsts.KEY_COMMON_CONTENT_COLLECTION_LAYOUT, mLayout)
+ }
+
+ override fun onRealLayoutInflated(inflatedView: View) {
+ super.onRealLayoutInflated(inflatedView)
+ mBinding = FragmentListBaseSkeletonBinding.bind(inflatedView)
+ }
+
+ override fun provideListAdapter(): ListAdapter<*> {
+ if (mAdapter == null) {
+ val exposureSourceList =
+ requireArguments().getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
+ mAdapter = CustomCommonCollectionDetailAdapter(
+ requireContext(),
+ mLayout,
+ mCollectionStyle,
+ mViewModel,
+ mLocation,
+ mTabIndexValue,
+ mEntrance,
+ exposureSourceList
+ )
+ }
+ return mAdapter!!
+ }
+
+ override fun provideListViewModel(): CustomCommonCollectionDetailViewModel {
+ val collectionId = arguments?.getString(EntranceConsts.KEY_COLLECTION_ID) ?: ""
+ mViewModel = viewModelProvider(CustomCommonCollectionDetailViewModel.Factory(collectionId))
+ return mViewModel
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+ mCachedView.setPadding(16f.dip2px(), 0, 16f.dip2px(), 0)
+ mReuseNoData?.findViewById(R.id.reuseNoneDataTv)?.text = "内容不见了~"
+ mReuseNoData?.findViewById(R.id.reuseNoneDataDescTv)?.text = "先去看看其它的内容吧"
+ mReuseNoData?.findViewById(R.id.reuseResetLoadTv)?.visibility = View.GONE
+ mReuseNoData?.findViewById(R.id.reuseNoneDataIv)?.setImageResource(R.drawable.ic_data_load_exception)
+ mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton)
+ .shimmer(true)
+ .angle(Constants.SHIMMER_ANGLE)
+ .color(R.color.ui_skeleton_highlight)
+ .duration(Constants.SHIMMER_DURATION)
+ .maskWidth(Constants.MASK_WIDTH)
+ .gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
+ .load(R.layout.common_collection_detail_skeleton)
+ .show()
+ }
+
+ override fun onFragmentFirstVisible() {
+ super.onFragmentFirstVisible()
+ mExposureListener = ExposureListener(this, provideListAdapter() as IExposable)
+ mViewModel.commonCollectionLiveData.observe(viewLifecycleOwner) {
+ setNavigationTitle(it.name)
+ mCollectionStyle = it.style
+ mAdapter?.collectionStyle = mCollectionStyle
+ if (mCollectionStyle == "1-2") {
+ mLayoutManager = FixGridLayoutManager(requireContext(), 2).apply {
+ spanSizeLookup = object : SpanSizeLookup() {
+ override fun getSpanSize(position: Int): Int {
+ val itemCount = mAdapter?.itemCount ?: 0
+ return if (position == itemCount - 1) {
+ 2
+ } else {
+ 1
+ }
+ }
+ }
+ }
+ mListRv?.layoutManager = mLayoutManager
+ }
+ mListRv?.removeItemDecorationAt(0)
+ mListRv?.addItemDecoration(itemDecoration)
+ }
+ mListViewModel.loadExceptionLiveData.observe(viewLifecycleOwner) {
+ if (it != null && it.code() == 404) {
+ toast("内容可能已被删除")
+ }
+ }
+ mListRv?.addOnScrollListener(mExposureListener!!)
+ mListRv?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+ val commonLinkCollection = mViewModel.commonCollectionLiveData.value
+ var position = mLayoutManager.findLastCompletelyVisibleItemPosition()
+ if (position < 0) position = mLayoutManager.findLastVisibleItemPosition() - 1
+ if (position < 0 || position >= commonLinkCollection?.collectionList?.size ?: 0) return
+ val contentEntity = commonLinkCollection?.collectionList?.get(position)
+ val linkEntity = contentEntity?.linkEntity
+ NewLogUtils.logSlideCommonCollection(
+ commonLinkCollection?.id ?: "",
+ commonLinkCollection?.name ?: "",
+ mBlockId,
+ mBlockName,
+ mEntrance,
+ "合集详情",
+ linkEntity?.title ?: "",
+ contentEntity?.addedContent1 ?: "",
+ contentEntity?.addedContent2 ?: "",
+ position + 1
+ )
+ }
+ }
+ })
+ }
+
+ override fun getItemDecoration(): RecyclerView.ItemDecoration {
+ return if (mCollectionStyle == "1-2") {
+ GridSpacingItemDecoration(2, 8f.dip2px(), false, 16F.dip2px())
+ } else {
+ VerticalItemDecoration(requireContext(), 16f, true, R.color.ui_surface)
+ }
+ }
+
+ override fun onDarkModeChanged() {
+ super.onDarkModeChanged()
+ if ((mListRv?.itemDecorationCount ?: 0) > 0) {
+ mListRv?.removeItemDecorationAt(0)
+ mListRv?.addItemDecoration(itemDecoration)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailViewModel.kt
new file mode 100644
index 0000000000..32f7971982
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CustomCommonCollectionDetailViewModel.kt
@@ -0,0 +1,45 @@
+package com.gh.gamecenter.game.commoncollection.detail
+
+import android.app.Application
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.gh.gamecenter.common.baselist.ListViewModel
+import com.gh.gamecenter.entity.CommonCollectionContentEntity
+import com.gh.gamecenter.entity.CommonCollectionEntity
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.Observable
+
+class CustomCommonCollectionDetailViewModel(
+ application: Application,
+ private val mCollectionId: String
+) : ListViewModel(application) {
+
+ val commonCollectionLiveData = MutableLiveData()
+
+ override fun provideDataObservable(page: Int): Observable>? {
+ return if (page == 1) {
+ RetrofitManager.getInstance().api
+ .getCommonCollectionDetail(mCollectionId)
+ .map {
+ commonCollectionLiveData.postValue(it)
+ it.collectionList
+ }
+ } else {
+ RetrofitManager.getInstance().api
+ .getCommonCollectionDetail(mCollectionId, page)
+ }
+ }
+
+ override fun mergeResultLiveData() {
+ mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
+ }
+
+ class Factory(private val collectionId: String) : ViewModelProvider.NewInstanceFactory() {
+
+ override fun create(modelClass: Class): T {
+ return CustomCommonCollectionDetailViewModel(HaloApp.getInstance().application, collectionId) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt
index 31bbef51fc..de854354da 100644
--- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt
@@ -11,10 +11,6 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.utils.*
-import com.gh.gamecenter.common.utils.dip2px
-import com.gh.gamecenter.common.utils.goneIf
-import com.gh.gamecenter.common.utils.toBinding
-import com.gh.gamecenter.common.utils.toPx
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
@@ -127,6 +123,16 @@ class GameHorizontalAdapter(
clickGameName = gameEntity.name ?: "",
clickGameId = gameEntity.id
)
+ if (!gameEntity.isQQMiniGame()) {
+ SensorsBridge.trackColumnClick(
+ location = "游戏详情",
+ gameName = gameName,
+ gameId = gameId,
+ gameColumnName = mSubjectEntity.name ?: "",
+ gameColumnId = mSubjectEntity.id ?: "",
+ text = "游戏"
+ )
+ }
}
if (gameEntity.isQQMiniGame()) {
diff --git a/app/src/main/java/com/gh/gamecenter/game/rank/CustomRankGameItem.kt b/app/src/main/java/com/gh/gamecenter/game/rank/CustomRankGameItem.kt
new file mode 100644
index 0000000000..a9431b8cb6
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/game/rank/CustomRankGameItem.kt
@@ -0,0 +1,198 @@
+package com.gh.gamecenter.game.rank
+
+import android.content.Context
+import android.text.TextUtils
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.core.view.setPadding
+import com.gh.common.util.DownloadItemUtils
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.GameViewHolder
+import com.gh.gamecenter.common.utils.*
+import com.gh.gamecenter.core.AppExecutor
+import com.gh.gamecenter.feature.entity.CustomPageTrackData
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.entity.TagStyleEntity
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
+import com.gh.gamecenter.home.custom.model.CustomPageData
+
+class CustomRankGameItem(val rankItemUi: RankGameItemUi) {
+
+ fun updateGameItem(
+ ui: RankGameItemUi,
+ gameEntity: GameEntity,
+ exposureEventList: ArrayList?,
+ position: Int,
+ subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity?,
+ eventHelper: GameSubjectCollectionEventHelper,
+ createTrackData: () -> CustomPageTrackData
+ ) {
+
+ // 为什么要用 post 呢?
+ // 因为普通用 recyclerView 来实现的纵向列表用的 notifyPositionChanged 是延时更新 UI 的
+ // 如果不添加延时,刚开始下载任务时可能会出现奇怪的状态 "下载中 -> 下载 -> 下载中"
+ // 为了避免更改其它地方的逻辑,就这里先 post 延时处理了
+ ui.root.post {
+ ui.run {
+ iconIv.displayGameIcon(gameEntity)
+ nameTv.text = gameEntity.name
+
+ updateTag(tagContainer, gameEntity)
+ updateOrder(orderTv, position)
+
+ val entrance = "(专题合集-排行榜:${subject?.title})"
+ val exposureEvent = exposureEventList?.getOrNull(position)
+ root.setOnClickListener {
+ eventHelper.navigateToGameDetailPage(position, gameEntity, subject)
+ }
+
+ gameEntity.customPageTrackData = createTrackData()
+ DownloadItemUtils.setOnClickListener(
+ root.context,
+ downloadTv,
+ gameEntity,
+ position,
+ null,
+ entrance,
+ location = "专题合集-排行榜-${subject?.title}:${gameEntity.name}",
+ traceEvent = exposureEvent,
+ clickCallback = {
+ eventHelper.onDownloadButtonClick(position, gameEntity, subject)
+ },
+ refreshCallback = {
+ DownloadItemUtils.updateItem(root.context, gameEntity, GameViewHolder(root).also {
+ it.gameDownloadBtn = downloadTv
+ it.gameDownloadTips = downloadTipsLottie
+ it.multiVersionDownloadTv = multiVersionDownloadTv
+ })
+ },
+ allStateClickCallback = null
+ )
+
+ DownloadItemUtils.updateItem(root.context, gameEntity, GameViewHolder(root).also {
+ it.gameDownloadBtn = downloadTv
+ it.gameDownloadTips = downloadTipsLottie
+ it.multiVersionDownloadTv = multiVersionDownloadTv
+ })
+
+ downloadTv.putWidgetBusinessName("专题合集")
+ }
+ }
+ }
+
+ fun getGameTagView(context: Context, tagEntity: TagStyleEntity): TextView {
+ return TextView(context).apply {
+ updateGameTagView(this, tagEntity)
+ }
+ }
+
+ private fun updateTag(tagContainer: LinearLayout, gameEntity: GameEntity) {
+ tagContainer.run {
+ for (i in 0 until childCount) {
+ getChildAt(i).visibility = View.GONE
+ }
+
+ gameEntity.tagStyle.forEachIndexed { index, tagStyleEntity ->
+ if (index < childCount) {
+ updateGameTagView(getChildAt(index) as TextView, tagStyleEntity)
+ } else {
+ AppExecutor.lightWeightIoExecutor.execute {
+ val tagView = getGameTagView(context, tagStyleEntity)
+ AppExecutor.uiExecutor.execute { addView(tagView) }
+ }
+ }
+ if (index >= 2) return
+ }
+ }
+ }
+
+ private fun updateOrder(orderTv: TextView, position: Int) {
+ orderTv.run {
+ visibility = View.VISIBLE
+ text = (position + 1).toString()
+ setPadding(0)
+ when (position + 1) {
+ 1 -> {
+ setTextColor(R.color.white.toColor())
+ setBackgroundResource(R.drawable.subject_top_first)
+ textSize = 9F
+ setPadding(0, 2F.dip2px(), 0, 0)
+ layoutParams?.let {
+ it.height = 16F.dip2px()
+ it.width = 16F.dip2px()
+ if (it is ViewGroup.MarginLayoutParams) {
+ it.leftMargin = 8F.dip2px()
+ it.rightMargin = 8F.dip2px()
+ }
+ }
+ }
+
+ 2 -> {
+ setTextColor(R.color.white.toColor())
+ setBackgroundResource(R.drawable.subject_top_second)
+ textSize = 9F
+ setPadding(0, 2F.dip2px(), 0, 0)
+ layoutParams?.let {
+ it.height = 16F.dip2px()
+ it.width = 16F.dip2px()
+ if (it is ViewGroup.MarginLayoutParams) {
+ it.leftMargin = 8F.dip2px()
+ it.rightMargin = 8F.dip2px()
+ }
+ }
+ }
+
+ 3 -> {
+ setTextColor(R.color.white.toColor())
+ setBackgroundResource(R.drawable.subject_top_third)
+ textSize = 9F
+ setPadding(0, 2F.dip2px(), 0, 0)
+ layoutParams?.let {
+ it.height = 16F.dip2px()
+ it.width = 16F.dip2px()
+ if (it is ViewGroup.MarginLayoutParams) {
+ it.leftMargin = 8F.dip2px()
+ it.rightMargin = 8F.dip2px()
+ }
+ }
+ }
+
+ else -> {
+ textSize = 16F
+ background = null
+ setTextColor(R.color.text_989898.toColor())
+ layoutParams?.let {
+ it.height = 24F.dip2px()
+ it.width = 24F.dip2px()
+ if (it is ViewGroup.MarginLayoutParams) {
+ it.leftMargin = 4F.dip2px()
+ it.rightMargin = 4F.dip2px()
+ } else throwExceptionInDebug()
+ }
+ }
+ }
+ }
+ }
+
+ private fun updateGameTagView(textView: TextView, tagEntity: TagStyleEntity) {
+ textView.run {
+ visibility = View.VISIBLE
+
+ if (text == tagEntity.name) return
+
+ isSingleLine = true
+ ellipsize = TextUtils.TruncateAt.END
+ includeFontPadding = false
+ textSize = 10F
+ text = tagEntity.name
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).apply { rightMargin = 8F.dip2px() }
+ setTextColor(("#" + if (tagEntity.column?.isNotEmpty() == true) tagEntity.column else tagEntity.color).hexStringToIntColor())
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt
index 662483f844..17c1bcf864 100644
--- a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt
@@ -10,7 +10,6 @@ import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.utils.*
-import com.gh.gamecenter.common.view.AsyncUi
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.GameSubjectData
@@ -45,7 +44,7 @@ class GameVerticalAdapter(
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleGameItemViewHolder {
- return SimpleGameItemViewHolder(AsyncGameItemUi(parent.context).apply { inflate() })
+ return SimpleGameItemViewHolder(GameItemUi(parent.context))
}
override fun getItemCount(): Int {
@@ -122,11 +121,7 @@ class GameVerticalAdapter(
}
}
- class AsyncGameItemUi(context: Context) : AsyncUi(context) {
- override fun provideUi(context: Context) = GameItemUi(context)
- }
-
- class SimpleGameItemViewHolder(view: AsyncGameItemUi) : ViewHolder(view) {
+ class SimpleGameItemViewHolder(private val ui: GameItemUi) : ViewHolder(ui.root) {
var placeholderGameViewHolder: GameViewHolder? = null
fun bindSimpleGameItem(
@@ -159,84 +154,81 @@ class GameVerticalAdapter(
ViewGroup.LayoutParams(maxWidth - 1, height)
}
- (itemView as AsyncGameItemUi).bindWhenInflated {
- (itemView as AsyncGameItemUi).ui!!.run {
- gameNameTv.setTextColor(R.color.text_primary.toColor(context))
- serverTypeTv.setTextColor(R.color.primary_theme.toColor(context))
- downloadTv.background = R.drawable.download_button_normal_style.toDrawable(context)
- gameDesTv.setTextColor(R.color.text_tertiary.toColor(context))
+ with(ui) {
+ gameNameTv.setTextColor(R.color.text_primary.toColor(context))
+ serverTypeTv.setTextColor(R.color.primary_theme.toColor(context))
+ downloadTv.background = R.drawable.download_button_normal_style.toDrawable(context)
+ gameDesTv.setTextColor(R.color.text_tertiary.toColor(context))
- BindingAdapters.setGameName(
- gameNameTv,
- gameEntity,
- false,
- subjectData?.isShowSuffix
- )
- BindingAdapters.setGame(iconIv, gameEntity)
- BindingAdapters.setGameTags(gameTagContainer, gameEntity)
- GameItemViewHolder.initServerType(gameNameTv, serverTypeTv, gameEntity)
- gameDesTv.text = gameEntity.decoratedDes
- GameItemViewHolder.initGameSubtitleAndAdLabel(
- gameEntity,
- gameSubtitleTv,
- gameNameContainer,
- gameNameTv,
- gameEntity.adIconActive,
- adLabelTv
- )
+ BindingAdapters.setGameName(
+ gameNameTv,
+ gameEntity,
+ false
+ )
+ BindingAdapters.setGame(iconIv, gameEntity)
+ BindingAdapters.setGameTags(gameTagContainer, gameEntity)
+ GameItemViewHolder.initServerType(gameNameTv, serverTypeTv, gameEntity)
+ gameDesTv.text = gameEntity.decoratedDes
+ GameItemViewHolder.initGameSubtitleAndAdLabel(
+ gameEntity,
+ gameSubtitleTv,
+ gameNameContainer,
+ gameNameTv,
+ gameEntity.adIconActive,
+ adLabelTv
+ )
- var gameRatingPaddingEnd = 0
- var gameRatingDrawableStart: Drawable? = null
- var gameRatingTextColor = R.color.primary_theme.toColor(context)
- var gameRatingText = ""
+ var gameRatingPaddingEnd = 0
+ var gameRatingDrawableStart: Drawable? = null
+ var gameRatingTextColor = R.color.primary_theme.toColor(context)
+ var gameRatingText = ""
- gameRatingTv.textSize = if (gameEntity.commentCount > 3) 12F else 10F
+ gameRatingTv.textSize = if (gameEntity.commentCount > 3) 12F else 10F
- if (gameEntity.commentCount > 3) {
- gameRatingPaddingEnd = 8F.dip2px()
- gameRatingDrawableStart = R.drawable.game_horizontal_rating.toDrawable()
- gameRatingTextColor = R.color.text_theme.toColor(context)
- gameRatingText =
- if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
+ if (gameEntity.commentCount > 3) {
+ gameRatingPaddingEnd = 8F.dip2px()
+ gameRatingDrawableStart = R.drawable.game_horizontal_rating.toDrawable()
+ gameRatingTextColor = R.color.text_theme.toColor(context)
+ gameRatingText =
+ if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
+ }
+
+ gameRatingTv.setDrawableStart(gameRatingDrawableStart)
+ gameRatingTv.setPadding(0, 0, gameRatingPaddingEnd, 0)
+ gameRatingTv.setTextColor(gameRatingTextColor)
+ gameRatingTv.text = gameRatingText
+
+ // 没错,产品就把这个通用样式叫推荐榜单专题
+ downloadTv.putWidgetBusinessName("推荐榜单专题")
+
+ // Fuck this view holder
+ val tempViewHolder =
+ placeholderGameViewHolder ?: GameViewHolder(root).apply {
+ placeholderGameViewHolder = this
}
+ tempViewHolder.gameDes = gameDesTv
+ tempViewHolder.gameDownloadBtn = downloadTv
+ tempViewHolder.multiVersionDownloadTv = multiVersionDownloadTv
+ tempViewHolder.gameDownloadTips = downloadTipsLottie
+ tempViewHolder.gameLabelList = gameTagContainer
+ tempViewHolder.recommendIv = recommendIv
+ tempViewHolder.recommendTv = recommendTv
+ tempViewHolder.recommendContainer = recommendConstraintLayout
+ tempViewHolder.gameServerType = serverTypeTv
- gameRatingTv.setDrawableStart(gameRatingDrawableStart)
- gameRatingTv.setPadding(0, 0, gameRatingPaddingEnd, 0)
- gameRatingTv.setTextColor(gameRatingTextColor)
- gameRatingTv.text = gameRatingText
-
- // 没错,产品就把这个通用样式叫推荐榜单专题
- downloadTv.putWidgetBusinessName("推荐榜单专题")
-
- // Fuck this view holder
- val tempViewHolder =
- placeholderGameViewHolder ?: GameViewHolder(this@run.root).apply {
- placeholderGameViewHolder = this
- }
- tempViewHolder.gameDes = gameDesTv
- tempViewHolder.gameDownloadBtn = downloadTv
- tempViewHolder.multiVersionDownloadTv = multiVersionDownloadTv
- tempViewHolder.gameDownloadTips = downloadTipsLottie
- tempViewHolder.gameLabelList = gameTagContainer
- tempViewHolder.recommendIv = recommendIv
- tempViewHolder.recommendTv = recommendTv
- tempViewHolder.recommendContainer = recommendConstraintLayout
- tempViewHolder.gameServerType = serverTypeTv
-
- DownloadItemUtils.updateItem(
- context,
- gameEntity,
- tempViewHolder,
- subjectData?.briefStyle
- )
+ DownloadItemUtils.updateItem(
+ context,
+ gameEntity,
+ tempViewHolder,
+ subjectData?.briefStyle
+ )
DownloadItemUtils.setOnClickListener(
context, downloadTv, gameEntity, position,
adapter, entrance, location = location, traceEvent = gameEntity.exposureEvent
)
- root.setPadding(paddingStart, 8F.dip2px(), paddingEnd, 8F.dip2px())
- }
+ root.setPadding(paddingStart, 8F.dip2px(), paddingEnd, 8F.dip2px())
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/game/vertical/SpanCountPagerSnapHelper.java b/app/src/main/java/com/gh/gamecenter/game/vertical/SpanCountPagerSnapHelper.java
index 7575855fbb..d6115a8f78 100644
--- a/app/src/main/java/com/gh/gamecenter/game/vertical/SpanCountPagerSnapHelper.java
+++ b/app/src/main/java/com/gh/gamecenter/game/vertical/SpanCountPagerSnapHelper.java
@@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView;
public class SpanCountPagerSnapHelper extends PagerSnapHelper {
- private final int mSpanCount;
+ private int mSpanCount;
private final boolean mAddOffsetToSolveWeirdBug;
@Nullable
@@ -30,6 +30,10 @@ public class SpanCountPagerSnapHelper extends PagerSnapHelper {
return mSpanCount;
}
+ public void setSpanCount(int spanCount) {
+ mSpanCount = spanCount;
+ }
+
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
super.attachToRecyclerView(recyclerView);
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt
index 670f50a318..c3eb4d4552 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt
@@ -575,7 +575,7 @@ open class GameCollectionDetailAdapter(
gameIconView.displayGameIcon(gameEntity)
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
- BindingAdapters.setGameName(gameName, gameEntity, false, null)
+ BindingAdapters.setGameName(gameName, gameEntity, false)
BindingAdapters.setGameTags(labelList, gameEntity)
gameRating.setDrawableStart(
if (gameEntity.commentCount > 3) R.drawable.game_horizontal_rating.toDrawable(mContext) else null
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt
index fe8ed20419..bb0170abb4 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt
@@ -14,6 +14,7 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
@@ -154,8 +155,8 @@ class GameCollectionDetailFragment :
mBinding?.run {
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
(toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
- insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
+ insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
}
root.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListActivity.kt
index 26ed0aafdc..ea16e2896f 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListActivity.kt
@@ -3,7 +3,6 @@ package com.gh.gamecenter.gamecollection.hotlist
import android.os.Bundle
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
-import com.gh.gamecenter.core.utils.DisplayUtils
class GameCollectionHotListActivity : BaseActivity() {
override fun getLayoutId(): Int {
@@ -13,8 +12,6 @@ class GameCollectionHotListActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- DisplayUtils.transparentStatusBar(this)
-
val containerFragment = supportFragmentManager.findFragmentByTag(
GameCollectionHotListWrapperFragment::class.java.name
)
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListAdapter.kt
index aef90ab021..fc65e9b4f1 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListAdapter.kt
@@ -17,6 +17,7 @@ import com.gh.gamecenter.R
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.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
@@ -98,7 +99,7 @@ class GameCollectionHotListAdapter(
)
}
rankTv.goneIf(realPosition < 3 || mIsFromDetail) {
- rankTv.typeface = Typeface.createFromAsset(mContext.assets, "fonts/d_din_bold_only_number.ttf")
+ rankTv.typeface = Typeface.createFromAsset(mContext.assets, Constants.DIN_FONT_PATH)
rankTv.text = "${realPosition + 1}"
}
stampIv.goneIf(entity?.stamp.isNullOrEmpty())
@@ -139,15 +140,29 @@ class GameCollectionHotListAdapter(
mGameCollectionListEntity?.name ?: "",
"游戏"
)
- SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
- "position" to mPosition
- "tab_content" to mGameCollectionListEntity?.name
- "game_list_collection_name" to mGameCollectionListEntity?.name
- "game_list_collection_id" to mGameCollectionListEntity?.id
- "text" to "游戏"
- "game_name" to gameEntity.name
- "game_id" to gameEntity.id
- })
+ if (mIsFromDetail) {
+ SensorsBridge.trackGameListCollectionClick(
+ location = "合集详情",
+ gameListCollectionId = mGameCollectionListEntity?.id ?: "",
+ gameListCollectionName = mGameCollectionListEntity?.name ?: "",
+ position = position,
+ text = "游戏",
+ otherParams = hashMapOf(
+ "game_name" to (gameEntity.name ?: ""),
+ "game_id" to gameEntity.id
+ )
+ )
+ } else {
+ SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
+ "position" to mPosition
+ "tab_content" to mGameCollectionListEntity?.name
+ "game_list_collection_name" to mGameCollectionListEntity?.name
+ "game_list_collection_id" to mGameCollectionListEntity?.id
+ "text" to "游戏"
+ "game_name" to gameEntity.name
+ "game_id" to gameEntity.id
+ })
+ }
GameDetailActivity.startGameDetailActivity(
mContext,
gameEntity.id,
@@ -172,14 +187,25 @@ class GameCollectionHotListAdapter(
mGameCollectionListEntity?.name ?: "",
"个人主页"
)
- SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
- "position" to mPosition
- "tab_content" to mGameCollectionListEntity?.name
- "game_list_collection_name" to mGameCollectionListEntity?.name
- "game_list_collection_id" to mGameCollectionListEntity?.id
- "text" to "个人主页"
- "mongold_id" to entity?.user?.id
- })
+ if (mIsFromDetail) {
+ SensorsBridge.trackGameListCollectionClick(
+ location = "合集详情",
+ gameListCollectionId = mGameCollectionListEntity?.id ?: "",
+ gameListCollectionName = mGameCollectionListEntity?.name ?: "",
+ position = position,
+ text = "个人主页",
+ otherParams = hashMapOf("mongold_id" to (entity?.user?.id ?: ""))
+ )
+ } else {
+ SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
+ "position" to mPosition
+ "tab_content" to mGameCollectionListEntity?.name
+ "game_list_collection_name" to mGameCollectionListEntity?.name
+ "game_list_collection_id" to mGameCollectionListEntity?.id
+ "text" to "个人主页"
+ "mongold_id" to entity?.user?.id
+ })
+ }
DirectUtils.directToHomeActivity(mContext, entity?.user?.id, 0, mEntrance, mPath)
}
}
@@ -190,15 +216,29 @@ class GameCollectionHotListAdapter(
mGameCollectionListEntity?.name ?: "",
"游戏单"
)
- SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
- "position" to mPosition
- "tab_content" to mGameCollectionListEntity?.name
- "game_list_collection_name" to mGameCollectionListEntity?.name
- "game_list_collection_id" to mGameCollectionListEntity?.id
- "text" to "游戏单"
- "game_collect_title" to entity?.title
- "game_collect_id" to entity?.id
- })
+ if (mIsFromDetail) {
+ SensorsBridge.trackGameListCollectionClick(
+ location = "合集详情",
+ gameListCollectionId = mGameCollectionListEntity?.id ?: "",
+ gameListCollectionName = mGameCollectionListEntity?.name ?: "",
+ position = position,
+ text = "游戏单",
+ otherParams = hashMapOf(
+ "game_collect_title" to (entity?.title ?: ""),
+ "game_collect_id" to (entity?.id ?: "")
+ )
+ )
+ } else {
+ SensorsBridge.trackEvent("ViewGameCollectHotRankTabClick", json {
+ "position" to mPosition
+ "tab_content" to mGameCollectionListEntity?.name
+ "game_list_collection_name" to mGameCollectionListEntity?.name
+ "game_list_collection_id" to mGameCollectionListEntity?.id
+ "text" to "游戏单"
+ "game_collect_title" to entity?.title
+ "game_collect_id" to entity?.id
+ })
+ }
DirectUtils.directToGameCollectionDetail(
it.context,
entity?.id ?: "",
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListFragment.kt
index 2a57f4f2ed..df4f6e08c4 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionHotListFragment.kt
@@ -21,7 +21,7 @@ import com.gh.gamecenter.entity.GameCollectionListEntity
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
class GameCollectionHotListFragment : ListFragment() {
- private lateinit var mBasicExposureSource: List
+ private lateinit var mBasicExposureSourceList: ArrayList
private lateinit var mExposureListener: ExposureListener
private lateinit var mViewModel: GameCollectionHotListViewModel
private var mAdapter: GameCollectionHotListAdapter? = null
@@ -40,7 +40,7 @@ class GameCollectionHotListFragment : ListFragment()
private var mAdapter: FragmentStateAdapter? = null
+ private var mUseAlternativeLayout = false
private var mIsCollapsed = false
- override fun getRealLayoutId(): Int = R.layout.fragment_game_collection_hot_list_wrapper
+ override fun getRealLayoutId(): Int = if (mUseAlternativeLayout) R.layout.fragment_game_collection_hot_list_wrapper_al else R.layout.fragment_game_collection_hot_list_wrapper
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mUseAlternativeLayout = mIsFromTabWrapper
+ }
override fun onFragmentPause() {
super.onFragmentPause()
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
if (mTabEntityList.isNotEmpty() && stayTime >= 3) {
+ val viewPager = if (mUseAlternativeLayout) mAlternativeBinding.viewPager else mBinding.viewPager
NewFlatLogUtils.logGameCollectionHotListExit(
stayTime,
- mTabEntityList.safelyGetInRelease(mBinding.viewPager.currentItem)?.name ?: ""
+ mTabEntityList.safelyGetInRelease(viewPager.currentItem)?.name ?: ""
)
SensorsBridge.trackEvent("ViewGameCollectHotRank", "stay_length", stayTime.toString())
}
}
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+ updateStatusBar()
+ }
+
+ private fun updateStatusBar() {
+ if (!mIsFromTabWrapper && isSupportVisible) {
+ DisplayUtils.transparentStatusBar(requireActivity())
+ DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
+ }
+ }
+
override fun onFragmentFirstVisible() {
super.onFragmentFirstVisible()
mViewModel = viewModelProvider()
@@ -61,7 +85,11 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
initViewPager()
initTabLayout()
} else {
- mBinding.reuseNoConnection.root.visibility = View.VISIBLE
+ if (mUseAlternativeLayout) {
+ mAlternativeBinding.reuseNoConnection.root.visibility = View.VISIBLE
+ } else {
+ mBinding.reuseNoConnection.root.visibility = View.VISIBLE
+ }
}
}
@@ -71,63 +99,92 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
override fun onRealLayoutInflated(inflatedView: View) {
super.onRealLayoutInflated(inflatedView)
- mBinding = FragmentGameCollectionHotListWrapperBinding.bind(inflatedView)
+ if (mUseAlternativeLayout) {
+ mAlternativeBinding = FragmentGameCollectionHotListWrapperAlBinding.bind(inflatedView)
+ } else {
+ mBinding = FragmentGameCollectionHotListWrapperBinding.bind(inflatedView)
+ }
}
override fun initRealView() {
super.initRealView()
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
- changeToolbarStyle(mIsCollapsed)
- mBinding.run {
- ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
- (toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
- insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
- }
- val collapsingTrigger = 66F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)
-
- toolbar.setNavigationOnClickListener { requireActivity().finish() }
-
- collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
- collapsingToolbar.scrimShownAction = {
- if (mIsCollapsed != it) {
- mIsCollapsed = it
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && it)
- changeToolbarStyle(it)
+ if (mUseAlternativeLayout) {
+ mAlternativeBinding.run {
+ tabContainer.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
+ reuseNoConnection.connectionReloadTv.setOnClickListener {
+ reuseNoConnection.root.visibility = View.GONE
+ mViewModel.getGameCollectionHotListTab()
}
}
-
- appbar.addOnOffsetChangedListener { _, verticalOffset ->
- val absOffset = abs(verticalOffset)
- val currentFragment = childFragmentManager.findFragmentByTag("f${mBinding.viewPager.currentItem}")
- if (currentFragment is GameCollectionPlayerCreationFragment) {
- currentFragment.setListRefreshEnable(absOffset <= 2)
- } else if (currentFragment is GameCollectionHotListFragment) {
- currentFragment.setListRefreshEnable(absOffset <= 2)
+ } else {
+ updateStatusBar()
+ changeToolbarStyle(mIsCollapsed)
+ mBinding.run {
+ val statusBarHeight = DisplayUtils.getStatusBarHeight(requireContext().resources)
+ if (!mIsFromTabWrapper) {
+ ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
+ (toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
+ insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
+ }
}
- }
+ if (mIsFromMainWrapper) {
+ (toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin = statusBarHeight
+ }
+ val collapsingTrigger = 66F.dip2px() + statusBarHeight
- reuseNoConnection.connectionReloadTv.setOnClickListener {
- reuseNoConnection.root.visibility = View.GONE
- mViewModel.getGameCollectionHotListTab()
+ if (mIsFromMainWrapper) {
+ toolbar.navigationIcon = null
+ } else {
+ toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ }
+ toolbar.setNavigationOnClickListener { requireActivity().finish() }
+
+ collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
+ collapsingToolbar.scrimShownAction = {
+ if (mIsCollapsed != it) {
+ mIsCollapsed = it
+ updateStatusBar()
+ changeToolbarStyle(it)
+ }
+ }
+
+ appbar.addOnOffsetChangedListener { _, verticalOffset ->
+ val absOffset = abs(verticalOffset)
+ val currentFragment = childFragmentManager.findFragmentByTag("f${mBinding.viewPager.currentItem}")
+ if (currentFragment is GameCollectionPlayerCreationFragment) {
+ currentFragment.setListRefreshEnable(absOffset <= 2)
+ } else if (currentFragment is GameCollectionHotListFragment) {
+ currentFragment.setListRefreshEnable(absOffset <= 2)
+ }
+ }
+
+ reuseNoConnection.connectionReloadTv.setOnClickListener {
+ reuseNoConnection.root.visibility = View.GONE
+ mViewModel.getGameCollectionHotListTab()
+ }
}
}
}
private fun changeToolbarStyle(isCollapsed: Boolean) {
if (isCollapsed) {
+ if (!mIsFromMainWrapper) {
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
+ }
mBinding.titleTv.alpha = 1F
mBinding.titleTv.visibility = View.VISIBLE
mBinding.titleTv.setTextColor(R.color.text_black.toColor(requireContext()))
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
mBinding.collapsingToolbar.setContentScrimColor(R.color.ui_surface.toColor(requireContext()))
mBinding.tabContainer.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
mBinding.tabLayout.layoutParams = (mBinding.tabLayout.layoutParams as ConstraintLayout.LayoutParams).apply {
topMargin = 12F.dip2px()
}
} else {
+ if (!mIsFromMainWrapper) {
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ }
mBinding.titleTv.visibility = View.GONE
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
mBinding.collapsingToolbar.setContentScrimColor(R.color.ui_background.toColor(requireContext()))
mBinding.tabContainer.background = null
mBinding.tabLayout.layoutParams = (mBinding.tabLayout.layoutParams as ConstraintLayout.LayoutParams).apply {
@@ -137,13 +194,15 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
}
private fun initTabLayout() {
- mBinding.tabLayout.run {
- TabLayoutMediator(this, mBinding.viewPager) { tab, position ->
+ val tabLayout = if (mUseAlternativeLayout) mAlternativeBinding.tabLayout else mBinding.tabLayout
+ val viewPager = if (mUseAlternativeLayout) mAlternativeBinding.viewPager else mBinding.viewPager
+ tabLayout.run {
+ TabLayoutMediator(this, viewPager) { tab, position ->
val tabEntity = mTabEntityList.safelyGetInRelease(position)
val view = LayoutInflater.from(context).inflate(R.layout.game_collection_hot_list_tab_item, null)
view.findViewById(R.id.tab_title)?.text = tabEntity?.name
tab.customView = view
- updateTabStyle(tab, position == mBinding.viewPager.currentItem)
+ updateTabStyle(tab, position == viewPager.currentItem)
}.attach()
val firstTabView = (getChildAt(0) as ViewGroup).getChildAt(0)
firstTabView.layoutParams = (firstTabView.layoutParams as LinearLayout.LayoutParams).also {
@@ -197,6 +256,7 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
}
private fun initViewPager() {
+ val exposureSourceList = arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST) ?: arrayListOf()
mAdapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int = mTabEntityList.size
@@ -206,7 +266,8 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
GameCollectionPlayerCreationFragment().with(
bundleOf(
EntranceConsts.KEY_ENTRANCE to mEntrance,
- EntranceConsts.KEY_PATH to "游戏单热榜"
+ EntranceConsts.KEY_PATH to "游戏单热榜",
+ EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to ArrayList(exposureSourceList)
)
)
} else {
@@ -215,24 +276,40 @@ class GameCollectionHotListWrapperFragment : LazyFragment() {
GameCollectionListEntity::class.java.simpleName to tabEntity,
EntranceConsts.KEY_POSITION to position,
EntranceConsts.KEY_ENTRANCE to mEntrance,
- EntranceConsts.KEY_PATH to "游戏单热榜"
+ EntranceConsts.KEY_PATH to "游戏单热榜",
+ EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to ArrayList(exposureSourceList)
)
)
}
}
}
- mBinding.viewPager.adapter = mAdapter
- mBinding.viewPager.isUserInputEnabled = false
- mBinding.viewPager.offscreenPageLimit = 3
+ if (mUseAlternativeLayout) {
+ mAlternativeBinding.viewPager.adapter = mAdapter
+ mAlternativeBinding.viewPager.isUserInputEnabled = false
+ mAlternativeBinding.viewPager.offscreenPageLimit = 3
+ } else {
+ mBinding.viewPager.adapter = mAdapter
+ mBinding.viewPager.isUserInputEnabled = false
+ mBinding.viewPager.offscreenPageLimit = 3
+ }
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
- changeToolbarStyle(mIsCollapsed)
- for (i in 0 until mBinding.tabLayout.tabCount) {
- val tab = mBinding.tabLayout.getTabAt(i)
+ if (!::mBinding.isInitialized && !::mAlternativeBinding.isInitialized) {
+ return
+ }
+ if (!mUseAlternativeLayout) {
+ updateStatusBar()
+ changeToolbarStyle(mIsCollapsed)
+ }
+
+ val tabCount =
+ if (mUseAlternativeLayout) mAlternativeBinding.tabLayout.tabCount else mBinding.tabLayout.tabCount
+ for (i in 0 until tabCount) {
+ val tab =
+ if (mUseAlternativeLayout) mAlternativeBinding.tabLayout.getTabAt(i) else mBinding.tabLayout.getTabAt(i)
if (tab != null) {
updateTabStyle(tab, tab.isSelected)
}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationAdapter.kt
index a18d3c8679..a05547514f 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationAdapter.kt
@@ -11,6 +11,7 @@ import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
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.entity.LinkEntity
import com.gh.gamecenter.common.exposure.ExposureSource
@@ -29,6 +30,7 @@ class GameCollectionPlayerCreationAdapter(
private val mViewModel: GameCollectionPlayerCreationViewModel,
private val mEntrance: String,
private val mPath: String,
+ private val mBasicExposureSourceList: ArrayList
) : ListAdapter(context) {
private var mTipLinkEntity: LinkEntity? = null
@@ -95,7 +97,7 @@ class GameCollectionPlayerCreationAdapter(
)
}
rankTv.goneIf(realPosition < 3) {
- rankTv.typeface = Typeface.createFromAsset(mContext.assets, "fonts/d_din_bold_only_number.ttf")
+ rankTv.typeface = Typeface.createFromAsset(mContext.assets, Constants.DIN_FONT_PATH)
rankTv.text = "${realPosition + 1}"
}
userNameTv.text = entity.user?.name
@@ -211,7 +213,11 @@ class GameCollectionPlayerCreationAdapter(
entity?.gameList?.id ?: "",
mEntrance,
mPath,
- ExposureEvent.createEvent(null, listOf(ExposureSource("游戏单热榜-玩家创作榜")))
+ ExposureEvent.createEventWithSourceConcat(
+ null,
+ mBasicExposureSourceList,
+ listOf(ExposureSource("游戏单热榜-玩家创作榜"))
+ )
)
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationFragment.kt
index 19efe041d6..61c75e162c 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/hotlist/GameCollectionPlayerCreationFragment.kt
@@ -27,7 +27,8 @@ class GameCollectionPlayerCreationFragment :
requireContext(),
provideListViewModel(),
mEntrance,
- arguments?.getString(EntranceConsts.KEY_PATH) ?: ""
+ arguments?.getString(EntranceConsts.KEY_PATH) ?: "",
+ arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST) ?: arrayListOf()
)
}
return mAdapter as GameCollectionPlayerCreationAdapter
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt
index 0405fae0a6..208b792e40 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt
@@ -10,13 +10,16 @@ import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
+import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
+import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
@@ -67,7 +70,7 @@ import java.lang.ref.WeakReference
import kotlin.math.abs
class GameCollectionSquareFragment : LazyListFragment() {
- private lateinit var mBasicExposureSource: ArrayList
+ private lateinit var mBasicExposureSourceList: ArrayList
private lateinit var mViewModel: GameCollectionSquareViewModel
private lateinit var mExposureListener: ExposureListener
@@ -78,6 +81,8 @@ class GameCollectionSquareFragment : LazyListFragment()
private var mUseAlternativeLayout = false
- private var mIsFromHomeToolbarWrapper = false
private var mIsCollapsed = false
private var mIsLoadDone = false
private var mForumName = ""
private var mGameCollectionTitle = ""
private var mGameCollectionId = ""
+ private var mIsHome = false
override fun onCreate(savedInstanceState: Bundle?) {
- mUseAlternativeLayout = arguments?.getBoolean(EntranceConsts.KEY_IS_HOME, false) ?: false
- mIsFromHomeToolbarWrapper = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_TOOLBAR_WRAPPER, false) ?: false
mForumName = arguments?.getString(EntranceConsts.KEY_FORUM_NAME, "") ?: ""
mGameCollectionTitle = arguments?.getString(EntranceConsts.KEY_GAME_COLLECTION_TITLE, "") ?: ""
mGameCollectionId = arguments?.getString(EntranceConsts.KEY_GAME_COLLECTION_ID, "") ?: ""
+ mIsHome = arguments?.getBoolean(EntranceConsts.KEY_IS_HOME, false) ?: false
super.onCreate(savedInstanceState)
+ mUseAlternativeLayout = mIsHome || mIsFromTabWrapper
}
override fun getStubLayoutId() = R.layout.fragment_stub
@@ -127,9 +132,8 @@ class GameCollectionSquareFragment : LazyListFragment(R.id.postFab)?.visibility = View.GONE
- rootView?.findViewById(R.id.refreshFab)?.visibility = View.GONE
+ mPostFabView?.visibility = View.GONE
+ mRefreshFabView?.visibility = View.GONE
mGuideContainer?.visibility = View.GONE
} else {
if (mExposureEventList.isNotEmpty()) ExposureManager.log(mExposureEventList)
@@ -160,9 +164,8 @@ class GameCollectionSquareFragment : LazyListFragment(R.id.postFab)?.visibility = View.VISIBLE
- rootView?.findViewById(R.id.refreshFab)?.visibility = View.VISIBLE
+ mPostFabView?.visibility = View.VISIBLE
+ mRefreshFabView?.visibility = View.VISIBLE
if (mIsLoadDone) {
mGuideContainer?.goneIf(
!SPUtils.getBoolean(
@@ -256,24 +259,12 @@ class GameCollectionSquareFragment : LazyListFragment {
if (mAdapter == null) {
val outerSequence = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX)
- val tabName = arguments?.getString(EntranceConsts.KEY_NAME) ?: ""
- mBasicExposureSource = arrayListOf().apply {
+ mBasicExposureSourceList = arrayListOf().apply {
val exposureSourceList = requireArguments().getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
if (exposureSourceList != null) {
addAll(exposureSourceList)
}
-
- if (mEntrance == "游戏库") {
- add(ExposureSource("游戏库"))
- add(ExposureSource("游戏单广场"))
- } else {
- add(
- ExposureSource(
- if (mUseAlternativeLayout) "顶部tab" else "游戏单广场",
- if (mUseAlternativeLayout) tabName else ""
- )
- )
- }
+ add(ExposureSource("游戏单广场"))
}
mAdapter =
GameCollectionSquareAdapter(
@@ -281,7 +272,7 @@ class GameCollectionSquareFragment : LazyListFragment
(mDefaultBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
- insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
+ insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
}
val collapsingTrigger = 66F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)
@@ -392,7 +383,7 @@ class GameCollectionSquareFragment : LazyListFragment { topMargin = headerHeight }
+
mViewModel.bannerList.observeNonNull(this) {
if (it.isNotEmpty()) {
bannerAdapter.submitList(it)
@@ -461,7 +455,7 @@ class GameCollectionSquareFragment : LazyListFragment(R.id.wrapper_main_content)
+ val headerHeight = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 4 + 16F.dip2px()
+ mGuideContainer?.setPadding(0, headerHeight, 0, 0)
+ if (mIsFromMainWrapper || (!mIsHome && mIsFromTabWrapper)) {
+ if (mIsFromMainWrapper) setNavigationTitle("游戏单广场")
+ val rootView: FrameLayout? = parentFragment?.view?.findViewById(R.id.wrapper_main_content)
+ ?: parentFragment?.parentFragment?.view?.findViewById(R.id.wrapper_main_content)
if (rootView != null) {
- rootView.addView(postFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
+ rootView.addView(mPostFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
it.gravity = Gravity.BOTTOM.xor(Gravity.END)
it.setMargins(0, 0, 8F.dip2px(), 32F.dip2px())
})
- rootView.addView(refreshFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
+ rootView.addView(mRefreshFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
it.gravity = Gravity.BOTTOM.xor(Gravity.END)
it.setMargins(0, 0, 8F.dip2px(), 92F.dip2px())
})
- rootView.addView(mGuideContainer, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT))
+ rootView.addView(mGuideContainer, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT).also {
+ if (!mIsHome && mIsFromTabWrapper) {
+ it.setMargins(0, R.dimen.tab_layout_height.toPx(), 0, 0)
+ }
+ })
}
} else {
val rootView = parentFragment?.view?.findViewById(R.id.coordinator)
if (rootView != null) {
- rootView.addView(postFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
+ rootView.addView(mPostFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
it.gravity = Gravity.BOTTOM.xor(Gravity.END)
it.setMargins(0, 0, 8F.dip2px(), 32F.dip2px())
})
- rootView.addView(refreshFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
+ rootView.addView(mRefreshFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
it.gravity = Gravity.BOTTOM.xor(Gravity.END)
it.setMargins(0, 0, 8F.dip2px(), 92F.dip2px())
})
rootView.addView(mGuideContainer, CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.MATCH_PARENT, CoordinatorLayout.LayoutParams.MATCH_PARENT).apply {
behavior = AppBarLayout.ScrollingViewBehavior()
- setMargins(0, 52F.dip2px(), 0, 0)
+ if (parentFragment?.view?.findViewById(R.id.tabContainer)?.isVisible == true) {
+ setMargins(0, 48F.dip2px(), 0, 0)
+ }
})
}
}
@@ -610,11 +613,11 @@ class GameCollectionSquareFragment : LazyListFragment {
- if (mGameEntity != null && mNewGameDetailEntity != null) {
- GameDetailMoreDialog.showMoreDialog(
- requireActivity() as AppCompatActivity,
- mGameEntity,
- mNewGameDetailEntity?.shortId ?: "",
- mShowConcernOnMenu,
- mNewGameDetailEntity!!.me?.isGameConcerned ?: false
- )
- MtaHelper.onEvent("游戏详情_新", "更多按钮", mViewModel.game?.name ?: "")
- }
- }
-
- R.id.menu_search -> {
- LogUtils.uploadSearchGame("access_to_search", "游戏详情", "", "")
- val intent = SearchActivity.getIntent(requireContext(), false, "", "游戏详情", "游戏详情")
- startActivity(intent)
- }
- }
- }
- }
-
- mMoreMenuItem?.setOnMenuItemClickListener(menuItemClickListener)
- mSearchMenuItem?.setOnMenuItemClickListener(menuItemClickListener)
- mDownloadMenuItem?.actionView?.setOnClickListener {
- MtaHelper.onEvent("游戏详情_新", "下载管理图标", mViewModel.game?.name ?: "")
- val intent = DownloadManagerActivity.getDownloadMangerIntent(requireContext(), mEntrance)
- startActivity(intent)
- }
-
- updateDownloadIcon()
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
for (fragment in childFragmentManager.fragments) {
@@ -441,7 +395,13 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ customPageTrackData =
+ arguments?.getParcelable(EntranceConsts.KEY_CUSTOM_PAGE_TRACK_DATA) as? CustomPageTrackData
savedInstanceState?.let { mDestinationTab = it.getInt(LAST_SELECTED_POSITION) }
+ }
+
+ override fun onFragmentFirstVisible() {
+ super.onFragmentFirstVisible()
mBinding.reuseNoneData.reuseNoneDataTv.text = "页面不见了"
mBodyBinding.gamedetailVp.setScrollable(true)
mBodyBinding.gamedetailVp.offscreenPageLimit = 5
@@ -575,6 +535,80 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
})
observeData()
+
+ initMenu()
+
+ mOrientationUtils = OrientationUtils(requireActivity(), mVideoBinding.player)
+ mOrientationUtils?.isEnable = false
+ setListener()
+
+ // toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
+ // [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
+ if (!mIsFromTabWrapper) {
+ ViewCompat.setOnApplyWindowInsetsListener(mBodyBinding.gamedetailAppbar) { _, insets ->
+ (mBodyBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
+ insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
+ WindowInsetsCompat.CONSUMED
+ }
+ }
+ if (mIsFromMainWrapper) {
+ (mBodyBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
+ DisplayUtils.getStatusBarHeight(requireContext().resources)
+ }
+
+ updateDivider()
+ }
+
+ private fun initMenu() {
+ mBodyBinding.run {
+ toolbar.inflateMenu(R.menu.menu_game_detail)
+ if (mIsFromMainWrapper || mIsFromTabWrapper) {
+ toolbar.navigationIcon = null
+ toolbarContainer.translationX = 16F.dip2px().toFloat()
+ }
+ toolbar.setNavigationOnClickListener { requireActivity().finish() }
+ mMoreMenuItem = toolbar.menu.findItem(R.id.menu_more)
+ mSearchMenuItem = toolbar.menu.findItem(R.id.menu_search)
+ mDownloadMenuItem = toolbar.menu.findItem(R.id.menu_download)
+ mDownloadMenuItem?.isVisible = Config.isShow()
+ }
+
+ mDownloadMenuIcon = mDownloadMenuItem?.actionView?.findViewById(R.id.menu_download_iv)
+
+ val menuItemClickListener = MenuItem.OnMenuItemClickListener {
+ consume {
+ when (it.itemId) {
+ R.id.menu_more -> {
+ if (mGameEntity != null && mNewGameDetailEntity != null) {
+ GameDetailMoreDialog.showMoreDialog(
+ requireActivity() as AppCompatActivity,
+ mGameEntity,
+ mNewGameDetailEntity?.shortId ?: "",
+ mShowConcernOnMenu,
+ mNewGameDetailEntity!!.me?.isGameConcerned ?: false
+ )
+ MtaHelper.onEvent("游戏详情_新", "更多按钮", mViewModel.game?.name ?: "")
+ }
+ }
+
+ R.id.menu_search -> {
+ LogUtils.uploadSearchGame("access_to_search", "游戏详情", "", "")
+ val intent = SearchActivity.getIntent(requireContext(), false, "", "游戏详情", "游戏详情")
+ startActivity(intent)
+ }
+ }
+ }
+ }
+
+ mMoreMenuItem?.setOnMenuItemClickListener(menuItemClickListener)
+ mSearchMenuItem?.setOnMenuItemClickListener(menuItemClickListener)
+ mDownloadMenuItem?.actionView?.setOnClickListener {
+ MtaHelper.onEvent("游戏详情_新", "下载管理图标", mViewModel.game?.name ?: "")
+ val intent = DownloadManagerActivity.getDownloadMangerIntent(requireContext(), mEntrance)
+ startActivity(intent)
+ }
+
+ updateDownloadIcon()
}
private fun initGameSubtitle(
@@ -702,25 +736,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
return (width / textWidth).toInt()
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- mOrientationUtils = OrientationUtils(requireActivity(), mVideoBinding.player)
- mOrientationUtils?.isEnable = false
- setListener()
-
- // toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
- // [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
- ViewCompat.setOnApplyWindowInsetsListener(mBodyBinding.gamedetailAppbar) { _, insets ->
- (mBodyBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin = insets.systemWindowInsetTop
- insets.consumeSystemWindowInsets()
- }
-
- updateDivider()
-
- mBodyBinding.toolbar.setNavigationOnClickListener { requireActivity().finish() }
- }
-
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(bean: EBScroll) {
if (mGameEntity?.id == bean.id) {
@@ -756,21 +771,48 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
DataLogUtils.uploadGameLog(context, mGameEntity!!.id, mGameEntity!!.name, mEntrance)
- SensorsBridge.trackEventWithExposureSource(
- "GameDetailPageShow",
- mTraceEvent?.source,
- "game_id", mGameEntity?.id ?: "",
- "game_name", mGameEntity?.name ?: "",
- "download_status", mGameEntity?.downloadStatusChinese ?: "",
- "cloud_save_tab_status", if (data.showArchive) "开启" else "关闭",
- "game_type", mGameEntity?.categoryChinese ?: "",
- "page_name", getCurrentPageEntity().pageName,
- "page_id", getCurrentPageEntity().pageId,
- "page_business_id", getCurrentPageEntity().pageBusinessId,
- "last_page_name", getLastPageEntity().pageName,
- "last_page_id", getLastPageEntity().pageId,
- "last_page_business_id", getLastPageEntity().pageBusinessId
- )
+ postDelayedRunnable({
+ val buttonName = when {
+ mDownloadBinding.detailProgressbar.text.isNotBlank() -> mDownloadBinding.detailProgressbar.text
+ mDownloadBinding.overlayTv.isVisible && mDownloadBinding.overlayTv.text.isNotBlank() ->
+ mDownloadBinding.overlayTv.text.toString()
+
+ mDownloadBinding.multiVersionDownloadTv.isVisible && mDownloadBinding.multiVersionDownloadTv.text.isNotBlank() ->
+ mDownloadBinding.multiVersionDownloadTv.text.toString()
+
+ else -> ""
+ }
+ SensorsBridge.trackEventWithExposureSource(
+ "GameDetailPageShow",
+ mTraceEvent?.source,
+ "game_id", mGameEntity?.id ?: "",
+ "game_name", mGameEntity?.name ?: "",
+ "download_status", mGameEntity?.downloadStatusChinese ?: "",
+ "cloud_save_tab_status", if (data.showArchive) "开启" else "关闭",
+ "game_type", mGameEntity?.categoryChinese ?: "",
+ "page_name", getCurrentPageEntity().pageName,
+ "page_id", getCurrentPageEntity().pageId,
+ "page_business_id", getCurrentPageEntity().pageBusinessId,
+ "last_page_name", getLastPageEntity().pageName,
+ "last_page_id", getLastPageEntity().pageId,
+ "last_page_business_id", getLastPageEntity().pageBusinessId,
+ "button_name", buttonName,
+ "game_schema_type", mGameEntity?.gameBitChinese ?: "",
+ "download_type", mGameEntity?.downloadType ?: "",
+ "game_type", mGameEntity?.categoryChinese ?: "",
+ "bottom_tab", customPageTrackData?.pageLocation?.bottomTab ?: "",
+ "several_tab_page_id", customPageTrackData?.pageLocation?.severalTabPageId ?: "",
+ "several_tab_page_name", customPageTrackData?.pageLocation?.severalTabPageName ?: "",
+ "position", "${customPageTrackData?.pageLocation?.tabPosition ?: -1}",
+ "tab_content", customPageTrackData?.pageLocation?.tabContent ?: "",
+ "custom_page_id", customPageTrackData?.pageLocation?.pageId ?: "",
+ "custom_page_name", customPageTrackData?.pageLocation?.pageName ?: "",
+ "module_type", customPageTrackData?.moduleType ?: "",
+ "module_pattern", customPageTrackData?.modulePattern ?: "",
+ "link_content_id", customPageTrackData?.linkContentId ?: "",
+ "link_content_name", customPageTrackData?.linkContentName ?: ""
+ )
+ }, 120)
mNewGameDetailEntity = data
@@ -1636,7 +1678,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
if (!mIsDarkModeOn && isToolbarWhite) R.color.black else R.color.white
)
)
- mBodyBinding.toolbar.setNavigationIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_bar_back else R.drawable.ic_bar_back_light)
+ if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
+ mBodyBinding.toolbar.setNavigationIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_bar_back else R.drawable.ic_bar_back_light)
+ }
mBodyBinding.toolbar.post {
if (context != null) {
mBodyBinding.toolbar.setBackgroundColor(
@@ -1646,16 +1690,19 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
)
}
}
- DisplayUtils.setStatusBarColor(
- requireActivity(),
- if (isToolbarWhite) R.color.ui_surface else R.color.transparent,
- true
- )
updateConcernMenuIcon(mNewGameDetailEntity?.me?.isGameConcerned ?: false)
mMoreMenuItem?.setIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_menu_more else R.drawable.ic_menu_more_light)
mSearchMenuItem?.setIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_column_search else R.drawable.ic_column_search_light)
mDownloadMenuIcon?.setImageResource(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.toolbar_download else R.drawable.toolbar_download_light)
- DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && isToolbarWhite)
+ // 不在多Tab导航页内更新状态栏颜色
+ if (!mIsFromTabWrapper && isSupportVisible) {
+ DisplayUtils.setStatusBarColor(
+ requireActivity(),
+ if (isToolbarWhite) R.color.ui_surface else R.color.transparent,
+ true
+ )
+ DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && isToolbarWhite)
+ }
}
override fun onTouchEvent(event: MotionEvent) {
@@ -1824,7 +1871,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
val downloadMenuView = mBodyBinding.toolbar.menu.findItem(R.id.menu_download).actionView
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
mDownloadCountHint?.typeface =
- Typeface.createFromAsset(requireContext().assets, "fonts/d_din_bold_only_number.ttf")
+ Typeface.createFromAsset(requireContext().assets, Constants.DIN_FONT_PATH)
}
private fun updateDownloadCountHint(updateList: List?) {
@@ -1926,7 +1973,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
}
private fun releaseVideo() {
- if (mViewModel.displayTopVideo) {
+ if (::mViewModel.isInitialized && mViewModel.displayTopVideo) {
mVideoBinding.player.release()
mVideoBinding.player.disposableTimer()
}
@@ -2318,8 +2365,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
return super.onBackPressed()
}
- override fun onResume() {
- super.onResume()
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+ updateToolbarStyle(!mViewModel.displayTopVideo || mBodyBinding.gamedetailThumbSmall.visibility == View.VISIBLE)
if (!mIsPauseTopVideo && mIsPlayingWhenPause) {
resumeVideo()
}
@@ -2333,8 +2381,8 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
controlInstallHint()
}
- override fun onPause() {
- super.onPause()
+ override fun onFragmentPause() {
+ super.onFragmentPause()
if (mViewModel.displayTopVideo) {
mVideoBinding.player.postDelayed({
mVideoBinding.player.showFullPauseBitmap()
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt
index ef700640ee..b26889c7cd 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt
@@ -22,7 +22,6 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.DefaultUrlHandler
-import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.*
import com.gh.common.util.LogUtils
@@ -824,6 +823,18 @@ class DescAdapter(
itemData.moreLink?.type ?: "",
itemData.moreLink?.link ?: ""
)
+ SensorsBridge.trackColumnClick(
+ location = "游戏详情",
+ gameName = mGameName,
+ gameId = mViewModel.gameId ?: "",
+ gameColumnName = itemData.columnTitle,
+ gameColumnId = itemData.columnId,
+ linkText = itemData.moreLink?.text ?: "",
+ linkType = itemData.moreLink?.type ?: "",
+ linkId = itemData.moreLink?.link ?: "",
+ text = "右上角",
+ buttonType = itemData.displayHome
+ )
if (itemData.displayHome == "换一批") {
headPb.visibility = View.VISIBLE
moreTv.isEnabled = false
@@ -852,6 +863,8 @@ class DescAdapter(
layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
if (adapter == null) {
val subjectEntity = SubjectEntity().apply {
+ id = itemData.columnId
+ name = itemData.columnTitle
data = columnGames
}
val exposureEventList = arrayListOf()
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt
index b138ddab95..c2eaf01162 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt
@@ -298,6 +298,8 @@ class DescFragment: LazyFragment(), IScrollable {
override fun onDarkModeChanged() {
super.onDarkModeChanged()
+ if (!::mBinding.isInitialized) return
+
mBinding.recyclerview.setBackgroundColor(R.color.ui_background.toColor(requireContext()))
mBinding.recyclerview.recycledViewPool.clear()
mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
@@ -310,6 +312,7 @@ class DescFragment: LazyFragment(), IScrollable {
floatingWindowProvider?.getAndShowFloatingWindow(
mGameEntity?.id ?: "",
mGameEntity?.name ?: "",
+ "游戏详情",
this,
mBinding.recyclerview
)?.let {
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLibaoAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLibaoAdapter.kt
index e9ca50e0c9..b3ccda0625 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLibaoAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameLibaoAdapter.kt
@@ -8,7 +8,6 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.LibaoUtils
import com.gh.common.util.NewLogUtils
-import com.gh.gamecenter.LibaoDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.copyTextAndToast
import com.gh.gamecenter.common.utils.fromHtml
@@ -18,6 +17,7 @@ import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.databinding.ItemGameDetailMoreBinding
import com.gh.gamecenter.databinding.ItemGameLibaoBinding
import com.gh.gamecenter.feature.entity.LibaoEntity
+import com.gh.gamecenter.libao.LibaoDetailActivity
import com.gh.gamecenter.login.user.UserManager
class GameLibaoAdapter(
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameRaidersAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameRaidersAdapter.kt
index ad07edc9bc..e009511eeb 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameRaidersAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameRaidersAdapter.kt
@@ -5,17 +5,19 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.DefaultUrlHandler
-import com.gh.common.util.*
+import com.gh.common.util.DataCollectionUtils
+import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
-import com.gh.gamecenter.NewsDetailActivity
+import com.gh.common.util.NewsUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
-import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.MtaHelper
+import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.databinding.ItemGameRaidersBinding
import com.gh.gamecenter.databinding.ItemGameRaidersFixedTopBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.NewsEntity
+import com.gh.gamecenter.newsdetail.NewsDetailActivity
class GameRaidersAdapter(
val context: Context,
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt
index 462e7778a1..cf84fdcada 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt
@@ -122,13 +122,7 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() {
private fun getShareUtils(): ShareUtils {
val url = getShareUrl()
val shareUtils = ShareUtils.getInstance(requireContext())
- var shareEntrance: ShareUtils.ShareEntrance = ShareUtils.ShareEntrance.game
- val tagList = mGameEntity?.getTag() ?: arrayListOf()
- for (s in tagList) {
- if ("官方版" != s) {
- shareEntrance = ShareUtils.ShareEntrance.plugin
- }
- }
+ val shareEntrance: ShareUtils.ShareEntrance = ShareUtils.ShareEntrance.game
shareUtils.shareParamsDetail(
requireActivity(), url, mGameEntity?.icon ?: "",
mGameEntity?.name ?: "",
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/DetailEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/DetailEntity.kt
index f64464e793..5185880587 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/DetailEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/DetailEntity.kt
@@ -200,8 +200,6 @@ class RelatedVersion(
var gameId: String = "",
@SerializedName("game_name")
private var mGameName: String = "",
- @SerializedName("name_suffix")
- var nameSuffix: String? = "",
@SerializedName("game_icon")
var gameIcon: String = "",
@SerializedName(value = "game_tag", alternate = arrayOf("new_game_tag"))
@@ -210,5 +208,5 @@ class RelatedVersion(
) : Parcelable {
@IgnoredOnParcel
val gameName: String
- get() = mGameName.removeSuffix(".") + (nameSuffix ?: "")
+ get() = mGameName.removeSuffix(".")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/FuLiAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/FuLiAdapter.kt
index 02be843a38..13ae72b162 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/FuLiAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/FuLiAdapter.kt
@@ -11,7 +11,6 @@ import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.gamecenter.GameNewsActivity
-import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameDetailNoticeViewHolder
import com.gh.gamecenter.common.entity.SimpleGameEntity
@@ -31,6 +30,7 @@ import com.gh.gamecenter.gamedetail.fuli.answer.GameDetailAnswerAdapter
import com.gh.gamecenter.gamedetail.fuli.answer.GameDetailAnswerViewHolder
import com.gh.gamecenter.gamedetail.fuli.tools.GameDetailToolsAdapter
import com.gh.gamecenter.help.HelpAndFeedbackBridge
+import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.lightgame.adapter.BaseRecyclerAdapter
class FuLiAdapter(
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/GameNewsAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/GameNewsAdapter.kt
index 916e833332..ad1ef806a3 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/GameNewsAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/GameNewsAdapter.kt
@@ -6,12 +6,12 @@ import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.NewsUtils
+import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.DrawableView
-import com.gh.gamecenter.NewsDetailActivity
-import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameDetailNewsBinding
import com.gh.gamecenter.feature.entity.NewsEntity
+import com.gh.gamecenter.newsdetail.NewsDetailActivity
class GameNewsAdapter(
val context: Context,
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/tools/GameDetailToolsAdapter.java b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/tools/GameDetailToolsAdapter.java
index 532965f4d6..470f2a4608 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/tools/GameDetailToolsAdapter.java
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/tools/GameDetailToolsAdapter.java
@@ -6,25 +6,25 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import com.gh.common.constant.Config;
-import com.gh.gamecenter.core.utils.DisplayUtils;
-import com.gh.gamecenter.common.utils.ImageUtils;
-import com.gh.gamecenter.core.utils.MtaHelper;
-import com.gh.gamecenter.NewsDetailActivity;
-import com.gh.gamecenter.R;
-import com.gh.gamecenter.WebActivity;
-import com.gh.gamecenter.adapter.viewholder.ToolBoxViewHolder;
-import com.gh.gamecenter.databinding.ToolboxItemBinding;
-import com.gh.gamecenter.common.entity.ToolBoxEntity;
-import com.lightgame.adapter.BaseRecyclerAdapter;
-
-import java.util.List;
-
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
+import com.gh.common.constant.Config;
+import com.gh.gamecenter.R;
+import com.gh.gamecenter.WebActivity;
+import com.gh.gamecenter.adapter.viewholder.ToolBoxViewHolder;
+import com.gh.gamecenter.common.entity.ToolBoxEntity;
+import com.gh.gamecenter.common.utils.ImageUtils;
+import com.gh.gamecenter.core.utils.DisplayUtils;
+import com.gh.gamecenter.core.utils.MtaHelper;
+import com.gh.gamecenter.databinding.ToolboxItemBinding;
+import com.gh.gamecenter.newsdetail.NewsDetailActivity;
+import com.lightgame.adapter.BaseRecyclerAdapter;
+
+import java.util.List;
+
/**
* Created by khy on 25/05/17.
*/
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingFragment.kt
index 8795064908..5f32d092f1 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/myrating/MyRatingFragment.kt
@@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.DirectUtils
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
@@ -18,8 +19,8 @@ import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.FragmentListNodataSkipNewBinding
import com.gh.gamecenter.entity.RatingComment
-import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.personalhome.rating.MyRating
+import com.gh.gamecenter.wrapper.MainWrapperFragment
class MyRatingFragment : ListFragment() {
@@ -41,7 +42,7 @@ class MyRatingFragment : ListFragment() {
mBinding.reuseNoneData.reuseResetLoadTv.text = "去首页看看"
mBinding.reuseNoneData.reuseResetLoadTv.visibility = View.VISIBLE
mBinding.reuseNoneData.reuseResetLoadTv.setOnClickListener {
- MainActivity.skipToMainActivity(requireContext(), MainWrapperFragment.INDEX_HOME)
+ DirectUtils.directToHomeDefaultTab(requireContext())
MtaHelper.onEvent("我的光环_新", "我的游戏评论", "去首页看看")
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
index 1801149595..567e7d8285 100644
--- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
@@ -33,10 +33,8 @@ import com.gh.gamecenter.databinding.FragmentMainHomeBinding
import com.gh.gamecenter.eventbus.EBDiscoverChanged
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
-import com.gh.gamecenter.eventbus.EBUISwitch
import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment
import com.gh.gamecenter.fragment.HomeSearchToolWrapperViewModel
-import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.gallery.GameGallerySlideViewHolder
import com.gh.gamecenter.home.slide.HomeSlideListAdapter
import com.gh.gamecenter.home.test_v2.HomeGameTestV2ViewModel
@@ -160,8 +158,6 @@ class HomeFragment : LazyFragment() {
HomeItemGameTestV2ViewHolderWatcher()
)
- mHomeSearchViewModel.getFloatingWindowHandler()?.setView(this, mBinding.gameList)
-
mBinding.gameList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
@@ -200,7 +196,7 @@ class HomeFragment : LazyFragment() {
fun setScrollEnabled(isScrollEnabled: Boolean) {
if (::mAutomaticLayoutManager.isInitialized) {
- mAutomaticLayoutManager.isScrollEnabled = isScrollEnabled
+ mAutomaticLayoutManager.isScrollVerticallyEnabled = isScrollEnabled
}
}
@@ -366,17 +362,17 @@ class HomeFragment : LazyFragment() {
mViewModel.refreshRecentVGameIfNeeded()
}
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onEventMainThread(busNine: EBUISwitch) {
- if (::mLayoutManager.isInitialized
- && MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
- && MainWrapperFragment.INDEX_HOME == busNine.position
- ) {
- mBinding.gameList.stopScroll()
- mLayoutManager.scrollToPosition(0)
- mScrollCalculatorHelper.currentPlayer?.release()
- }
- }
+// @Subscribe(threadMode = ThreadMode.MAIN)
+// fun onEventMainThread(busNine: EBUISwitch) {
+// if (::mLayoutManager.isInitialized
+// && MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
+// && MainWrapperFragment.INDEX_HOME == busNine.position
+// ) {
+// mBinding.gameList.stopScroll()
+// mLayoutManager.scrollToPosition(0)
+// mScrollCalculatorHelper.currentPlayer?.release()
+// }
+// }
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(changed: EBDiscoverChanged) {
diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt
index 563f55f5ad..a8bacd029e 100644
--- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt
@@ -23,7 +23,6 @@ import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.feature.utils.ApkActiveUtils
-import com.gh.gamecenter.fragment.MainWrapperRepository
import com.gh.gamecenter.game.rank.RankCollectionAdapter
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
import com.gh.gamecenter.home.test_v2.HomeGameTestV2DownloadStateUpdateHelper
@@ -132,8 +131,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
refreshRecentVGameIfNeeded()
}
- fun showRecentVGame() = MainWrapperRepository.getInstance().getVideoNavBarLiveData().value?.text?.contains("畅玩广场") == false
-
fun refreshRecentVGameIfNeeded() {
if (VHelper.isVGameOn()
&& SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)
@@ -654,7 +651,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
}
// 最近在玩的畅玩游戏
- if (showRecentVGame() && mVGameList != null && !mVGameList.isNullOrEmpty()) {
+ if (mVGameList != null && !mVGameList.isNullOrEmpty()) {
val item = HomeItemData()
item.recentVGame = mVGameList
mSnapshotItemList.add(item)
@@ -736,8 +733,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
// 这个 for 循环主要功能是用来标识替换已安装的游戏
for (game in data) {
mSubjectGameIdList.add(game.id)
- // 应用专题是否显示游戏名后缀的配置
- game.shouldShowNameSuffix = subjectEntity.showSuffix
}
subjectEntity.relatedColumnId?.let {
diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt
index 10a311c662..2157bf5079 100644
--- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt
@@ -665,7 +665,7 @@ class LegacyHomeFragmentAdapterAssistant(
holder.itemView.setPadding(16F.dip2px(), 8F.dip2px(), 16F.dip2px(), 8F.dip2px())
}
- holder.bindGameItem(gameEntity, subjectData.isShowSuffix, subjectData.briefStyle)
+ holder.bindGameItem(gameEntity, subjectData.briefStyle)
holder.initServerType(gameEntity)
runOnIoThread(true) {
@@ -923,15 +923,7 @@ class LegacyHomeFragmentAdapterAssistant(
var adapter = holder.binding.recyclerView.adapter
if (mPluginDisplayStatus == PluginDisplayStatus.DEFAULT) {
- mPluginDisplayStatus = if (HaloApp.getInstance().isNewForThisVersion) {
- if (pluginList!!.size > 2) {
- PluginDisplayStatus.OPEN_TWO_AND_BUTTON
- } else {
- PluginDisplayStatus.OPEN
- }
- } else {
- PluginDisplayStatus.CLOSE
- }
+ mPluginDisplayStatus = HomePluggableHelper.getPluginDisplayedStyle(pluginList)
}
val exposureList = arrayListOf()
diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt
index 1a1d79ebdb..d47df6c180 100644
--- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt
@@ -105,7 +105,6 @@ object LegacyHomeSubjectTransformer {
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
game.outerSequence = blockPosition
game.sequence = i
@@ -139,7 +138,6 @@ object LegacyHomeSubjectTransformer {
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
game.outerSequence = blockPosition
game.sequence = i
@@ -170,7 +168,6 @@ object LegacyHomeSubjectTransformer {
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
game.outerSequence = blockPosition
game.sequence = i
@@ -250,7 +247,6 @@ object LegacyHomeSubjectTransformer {
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
game.outerSequence = blockPosition
game.sequence = i
@@ -279,7 +275,6 @@ object LegacyHomeSubjectTransformer {
position = i + if (data[0].image.isNullOrEmpty()) 1 else 0,
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
- isShowSuffix = subjectEntity.showSuffix
)
val itemDataGame = newItemInstance()
itemDataGame.blockPosition = blockPosition + 1
diff --git a/app/src/main/java/com/gh/gamecenter/home/PageConfigure.kt b/app/src/main/java/com/gh/gamecenter/home/PageConfigure.kt
new file mode 100644
index 0000000000..f56883824a
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/PageConfigure.kt
@@ -0,0 +1,27 @@
+package com.gh.gamecenter.home
+
+import com.gh.gamecenter.common.exposure.ExposureSource
+
+class PageConfigure(
+ val pageId: String = "",
+ var refreshCount: Int = 0,
+ val entrance: String = "",
+ val transparentBackground: Boolean = false,
+ val exposureSourceList: ArrayList = arrayListOf(),
+ val isInSearchToolbarTabWrapperPage: Boolean = false
+) {
+
+ private val customExposureSource = ExposureSource(CUSTOM_PAGE_SOURCE, "")
+
+ init {
+ exposureSourceList.add(customExposureSource)
+ }
+
+ fun setCustomPageExposureSource(v: String) {
+ customExposureSource.v = v
+ }
+
+ companion object {
+ private const val CUSTOM_PAGE_SOURCE = "自定义页面"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/BannerInRecyclerController.kt b/app/src/main/java/com/gh/gamecenter/home/custom/BannerInRecyclerController.kt
new file mode 100644
index 0000000000..8cf7ed4d1c
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/BannerInRecyclerController.kt
@@ -0,0 +1,87 @@
+package com.gh.gamecenter.home.custom
+
+import android.os.Handler
+import android.os.Looper
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
+
+/**
+ * 自定义页面
+ * 控制折叠轮播图轮播逻辑
+ */
+class BannerInRecyclerController(
+ private val nextPage: () -> Unit
+) : DefaultLifecycleObserver {
+
+ private val handler = Handler(Looper.getMainLooper())
+
+ private var isAttachToWindow = false
+
+ private var isActive = false
+
+ private var isParentScrolling = false
+
+ private val onScrollListener = object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ isParentScrolling = newState != RecyclerView.SCROLL_STATE_IDLE
+ if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+ start()
+ } else {
+ pause()
+ }
+ }
+ }
+
+ fun onViewAttachedToWindow(parent: RecyclerView?) {
+ isAttachToWindow = true
+ parent?.addOnScrollListener(onScrollListener)
+ }
+
+ fun onViewDetachedFromWindow(parent: RecyclerView?) {
+ isAttachToWindow = false
+ pause()
+ parent?.removeOnScrollListener(onScrollListener)
+ }
+
+ fun start() {
+ if (isActive && !isParentScrolling) {
+ handler.removeCallbacksAndMessages(null)
+ nextToPage()
+ }
+ }
+
+ fun pause() {
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ private fun destroy() {
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onResume(owner: LifecycleOwner) {
+ isActive = true
+ if (isAttachToWindow) {
+ start()
+ }
+ }
+
+ override fun onPause(owner: LifecycleOwner) {
+ isActive = false
+ pause()
+ }
+
+ override fun onDestroy(owner: LifecycleOwner) {
+ destroy()
+ }
+
+ private fun nextToPage() {
+ handler.postDelayed(nextPageRunner, GameCollectionSquareFragment.BANNER_LOOP_TIME)
+ }
+
+ private val nextPageRunner = Runnable {
+ nextPage()
+ nextToPage()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomNewGameTestUseCase.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomNewGameTestUseCase.kt
new file mode 100644
index 0000000000..c5809327a2
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomNewGameTestUseCase.kt
@@ -0,0 +1,481 @@
+package com.gh.gamecenter.home.custom
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import com.gh.common.filter.RegionSettingHelper
+import com.gh.gamecenter.BuildConfig
+import com.gh.gamecenter.common.baselist.LoadStatus
+import com.gh.gamecenter.common.retrofit.Response
+import com.gh.gamecenter.common.utils.observableToMain
+import com.gh.gamecenter.core.utils.UrlFilterUtils
+import com.gh.gamecenter.entity.*
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.home.test_v2.HomeGameTestV2DownloadStateUpdateHelper
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import com.lightgame.utils.Utils
+import retrofit2.HttpException
+
+/**
+ * description : 自定义页面-新游开测 item 的分页加载 ViewModel
+ */
+
+class CustomNewGameTestUseCase() : HomeGameTestV2DownloadStateUpdateHelper {
+
+ companion object {
+ private const val TAG = "HomeGameTestV2ViewModel"
+
+ //每页加载数据条数
+ private const val PAGE_SIZE = 36
+
+ //提前多少加载数据
+ private const val LOAD_PRE = 24
+
+ //每列条目数
+ private const val COLUMN_COUNT = 3
+ }
+
+ override var mParentPosition: Int = 0
+ override var mOnGameListAddCallback: (Int, List) -> Unit = { _, _ -> }
+
+ //埋点上报的信息,别的板块使用修改这里
+ var location: String = "首页"
+ var blockData: SubjectRecommendEntity? = null
+
+
+ private val mApi = RetrofitManager.getInstance().api
+
+ /**
+ * 加载状态livedata
+ */
+ private val mLoadStateLiveData = MutableLiveData()
+
+ /**
+ * 加载数据返回livedata
+ */
+ private val mDataLiveData = MutableLiveData>()
+
+ /**
+ * 时间线节点事件通知livedata
+ */
+ private val mTimePointLiveData = MutableLiveData()
+
+ /**
+ * 游戏列表滑动到指定position位置通知
+ */
+ private val mGameListScrollLiveData = MutableLiveData()
+
+ /**
+ * 时间轴数据
+ */
+ private var mTimePoint: List? = null
+
+ /**
+ * 记录过滤掉的游戏
+ */
+ private val mFilterGameIdSet = mutableSetOf()
+
+ /**
+ * 设置时间轴数据
+ */
+ fun setTimePoint(timePoint: List) {
+ this.mTimePoint = timePoint
+ mTimePointLiveData.value = timePoint.firstOrNull()?.timeType ?: ""
+ }
+
+ /**
+ * 设置时间轴节点游戏总数
+ * 用占位和空条目填充数据列表
+ */
+ fun setDataCount(dataCount: List) {
+ if (dataCount.isEmpty()) return
+ val rawCount = COLUMN_COUNT
+ val gameList = mutableListOf()
+ var index = 0
+ dataCount.forEach {
+ val (timeType, count) = it
+ repeat(count) {
+ gameList.add(GameDataWrapper(index++, timeType = timeType, isPlaceHolder = true))
+ }
+ val limit = rawCount - (count % rawCount)
+ repeat(limit % rawCount) {
+ gameList.add(GameDataWrapper(index++, timeType = timeType, isSpace = true))
+ }
+ }
+ mDataLiveData.value = gameList
+ }
+
+ /**
+ * 分页加载方向,
+ * action:
+ * left(左滑加载,即手指从右往左滑,也就是下一页)、
+ * right(右滑加载,即手指从左往右滑,也就是上一页)
+ */
+ enum class Action(val command: String) {
+ LEFT("left"),
+ RIGHT("right");
+
+ companion object {
+ fun getActionByCommand(command: String): Action {
+ return values().find { it.command == command } ?: LEFT
+ }
+ }
+ }
+
+ /**
+ * 分页加载
+ * @param isRefresh 是否是刷新
+ * @param action 分页加载方向
+ * @param pageId 分页id ,加载下一页为上一页最后一个id,加载上一页为下一页第一个id
+ * @param timeType 时间轴类型 time_type(recommend:推荐、xxxx-xx-xx:全部(比如:2023-01-01))
+ * @param startId //时间轴id,起始点ID(与时间轴对应):
+ * start_id(【数据从“时间轴起始点”接口获取】,刚进入页面,或者用户自己“点击切换时间轴”的时候必填。
+ * 如果是用户在数据列表里左右滑动则自动切换下一列的时候 则不用传,要用户主动切换时间轴的才传)
+ */
+ private fun loadData(
+ isRefresh: Boolean = false,
+ action: Action,
+ pageId: String,
+ timeType: String,
+ loadTimeType: String,
+ startId: String = "",
+ limit: Int = PAGE_SIZE
+ ) {
+ Utils.log(
+ TAG, "loadData: isRefresh = $isRefresh, action = ${action.command}, pageId = $pageId," +
+ "timeType = $timeType, loadTimeType = $loadTimeType, startId = $startId, limit = $limit"
+ )
+ if (isRefresh) {
+ mLoadStateLiveData.postValue(LoadStatus.INIT_LOADING)
+ } else {
+ mLoadStateLiveData.postValue(LoadStatus.LIST_LOADING)
+ }
+ val filterQuery = UrlFilterUtils.getFilterQuery(
+ "action", action.command,
+ "page_id", pageId,
+ "time_type", timeType, //时间轴类型必填:time_type(recommend:推荐、xxxx-xx-xx:全部(比如:2023-01-01))
+ "load_time_type", loadTimeType, //下一个节点的 time_type,根据action 确定是左边的还是右边的
+ "start_id", startId
+ )
+ mApi.getHomeServerTestV2(
+ BuildConfig.VERSION_NAME,
+ HaloApp.getInstance().channel,
+ limit,
+ filterQuery
+ ).compose(observableToMain())
+ .subscribe(object : Response() {
+ override fun onResponse(response: HomeItemTestV2Entity?) {
+ mLoadStateLiveData.postValue(LoadStatus.LIST_LOADED)
+ val data = response?.data ?: return
+ addGameList(
+ list = data,
+ timeType = response.timeType,
+ pageId = response.pageId,
+ action = Action.getActionByCommand(response.action),
+ isRefresh = false,
+ isSameTimeType = timeType == loadTimeType
+ )
+ }
+
+ override fun onFailure(e: HttpException?) {
+ mLoadStateLiveData.postValue(LoadStatus.INIT_FAILED)
+ }
+ })
+ }
+
+ fun getDataListLiveData(): LiveData> {
+ return mDataLiveData
+ }
+
+ fun getLoadStateLiveData(): LiveData {
+ return mLoadStateLiveData
+ }
+
+ fun getTimePointLiveData(): LiveData {
+ return mTimePointLiveData
+ }
+
+ fun getGameListScrollLiveData(): LiveData {
+ return mGameListScrollLiveData
+ }
+
+ private fun getCurrentData(): List {
+ return mDataLiveData.value ?: emptyList()
+ }
+
+ /**
+ * 根据当前条目索引,向前和向后查找LOAD_PRE个条目,如果有占位条目,则加载数据
+ */
+ fun parseActionWithPosition(position: Int) {
+ val dataList = getCurrentData()
+ if (dataList.isEmpty()) return
+ //如果当前条目是占位条目,那就前后查找有数据的借力一下
+ val currentItem = dataList[position]
+ if (currentItem.isPlaceHolder) {
+ //当前条目是占位条目,查找前后最近的有数据的条目
+ for (i in position until dataList.size) {
+ val item = dataList[i]
+ if (item.gameData != null && item.index - position <= LOAD_PRE) {
+ parseActionWithPosition(item.index)
+ return
+ }
+ }
+ for (i in position downTo 0) {
+ val item = dataList[i]
+ if (item.gameData != null && position - item.index <= LOAD_PRE) {
+ parseActionWithPosition(item.index)
+ return
+ }
+ }
+ return
+ }
+
+ //往前查找离position最近的占位条目
+ val frontList = getCurrentData().subList(0, position + 1)
+ val findFrontNearPlaceHolder = frontList.lastOrNull { it.isPlaceHolder }
+ val frontPlaceHolderPosition = findFrontNearPlaceHolder?.index ?: -1
+ if (findFrontNearPlaceHolder != null && position - frontPlaceHolderPosition <= LOAD_PRE) {
+ //position的前LOAD_PRE个条目列表
+ val list = frontList.subList(frontPlaceHolderPosition, position + 1)
+ //查找holder后面的第一个有数据的条目
+ val firstHasDataItem = list.firstOrNull { it.gameData != null }
+ if (firstHasDataItem != null && firstHasDataItem.index > frontPlaceHolderPosition) {
+ val pageId = firstHasDataItem.gameData?.id ?: return
+ loadData(
+ action = Action.RIGHT,
+ pageId = pageId,
+ timeType = firstHasDataItem.timeType,
+ loadTimeType = findFrontNearPlaceHolder.timeType
+ )
+ }
+ }
+ //往后查找离position最近的占位条目
+ val behindList = getCurrentData().subList(position, getCurrentData().size)
+ val findBehindPlaceHolder = behindList.firstOrNull { it.isPlaceHolder }
+ val behindPlaceHolderPosition = findBehindPlaceHolder?.index ?: -1
+ if (findBehindPlaceHolder != null && behindPlaceHolderPosition - position <= LOAD_PRE) {
+ val list = behindList.subList(0, behindPlaceHolderPosition - position + 1)
+ //查找holder前面的第一个有数据的条目
+ val lastHasDataItem = list.lastOrNull { it.gameData != null }
+ if (lastHasDataItem != null && lastHasDataItem.index < behindPlaceHolderPosition) {
+ val pageId = lastHasDataItem.gameData?.id ?: return
+ loadData(
+ action = Action.LEFT,
+ pageId = pageId,
+ timeType = lastHasDataItem.timeType,
+ loadTimeType = findBehindPlaceHolder.timeType
+ )
+ }
+ }
+ }
+
+
+ //添加数据到列表
+ fun addGameList(
+ list: List,
+ timeType: String,
+ pageId: String,
+ action: Action,
+ firstIndex: Int = 0, //首页推荐列表左侧剩余游戏数
+ isRefresh: Boolean = false,
+ isSameTimeType: Boolean = false //当前时间轴类型与预加载时间轴类型是否相同
+ ) {
+ val currentData = getCurrentData().toMutableList()
+ val gameList = getFilterGameAndTrimList(currentData, list)
+ if (currentData.size < gameList.size) {
+ //出现错误,没有获取到时间轴的游戏数量, 或者数量不正确
+ Utils.log(TAG, "出现错误,没有获取到时间轴的游戏数量, 或者数量不正确currentData.size < gameList.size")
+ return
+ }
+ Utils.log(
+ TAG, "加载分页完成:action = $action, timeType = $timeType, pageId = $pageId, gameList = $gameList"
+ )
+ //给数据分配位置
+ var index = firstIndex
+ if (isRefresh) {
+ //初始化分配
+ while (gameList.isNotEmpty()) {
+ val gameDataWrapper = gameList.removeFirst()
+ while (currentData.getOrNull(index)?.isPlaceHolder == false) {
+ index++
+ }
+ if (index >= currentData.size) {
+ //出现错误,没有获取到时间轴的游戏数量, 或者数量不正确
+ Utils.log(TAG, "isRefresh:出现错误,没有获取到时间轴的游戏数量, 或者数量不正确")
+ return
+ }
+ currentData[index] = gameDataWrapper.also { it.index = index }
+ }
+ } else {
+ //分页加载逻辑
+ if (action == Action.RIGHT) {
+ //如果是向前加载,列表倒序一下
+ gameList.reverse()
+ }
+ gameList.forEach {
+ addGameItemWithAction(currentData, it, action, isSameTimeType)
+ }
+ }
+ mDataLiveData.value = currentData.toMutableList()
+ //如果推荐定位不是第一个,向前加载一页
+ if (firstIndex > 0) {
+ parseActionWithPosition(firstIndex)
+ }
+ }
+
+ /**
+ * 根据条目timeType和action自动插入对应holder空位
+ */
+ private fun addGameItemWithAction(
+ dataList: MutableList,
+ gameDataWrapper: GameDataWrapper,
+ action: Action,
+ isSameTimeType: Boolean
+ ) {
+ val gameTimeType = gameDataWrapper.timeType
+ val firstLoadedRecommendPosition =
+ dataList.indexOfFirst { it.timeType == "recommend" && !it.isPlaceHolder && !it.isSpace } // 推荐类型第一个非占位的位置
+ val lastLoadedRecommendPosition =
+ dataList.indexOfLast { it.timeType == "recommend" && !it.isPlaceHolder && !it.isSpace } // 推荐类型最后一个非占位的位置
+ val shouldInsertLoadedRecommendFront =
+ gameTimeType == "recommend" && isSameTimeType && firstLoadedRecommendPosition > 0 // 推荐定位不是第一个时需要插入到已加载位置的前面
+ val shouldInsertLoadedRecommendBehind =
+ gameTimeType == "recommend" && isSameTimeType && lastLoadedRecommendPosition > 0 // 推荐定位不是第一个时需要插入到已加载位置的后面
+ val insertPosition = when (action) {
+ Action.LEFT -> if (shouldInsertLoadedRecommendBehind) lastLoadedRecommendPosition + 1 else dataList.indexOfFirst { it.timeType == gameTimeType && it.isPlaceHolder }
+ Action.RIGHT -> if (shouldInsertLoadedRecommendFront) firstLoadedRecommendPosition - 1 else dataList.indexOfLast { it.timeType == gameTimeType && it.isPlaceHolder }
+ }
+ val exist = dataList.find { it.timeType == gameTimeType && it.gameData?.id == gameDataWrapper.gameData?.id }
+ if (exist != null) {
+ Utils.log(TAG, "重复条目,不添加到列表: $exist")
+ return
+ }
+ if (insertPosition == -1) {
+ Utils.log(TAG, "出现错误,没有获取到时间轴的游戏数量, 或者数量不正确addGameItemWithAction")
+ return
+ }
+ dataList[insertPosition] = gameDataWrapper.also { it.index = insertPosition }
+ }
+
+ /**
+ * 过滤被屏蔽的游戏并清理列表中的占位,以及重新调整空白条目
+ * 返回屏蔽后的游戏列表
+ */
+ private fun getFilterGameAndTrimList(
+ dataList: MutableList,
+ list: List
+ ): MutableList {
+ val gameList = mutableListOf()
+ list.forEach { gameData ->
+ //记录被过滤的游戏id
+ val filterGameIdList = gameData.games.map { it.id }.toMutableList()
+ val gameTimeType = gameData.timeType
+ val size = gameData.games.size
+ //过滤被屏蔽的游戏
+ val filterGames = RegionSettingHelper.filterGame(gameData.games)
+ val filterGameIds = filterGames.map { it.id }
+ filterGameIdList.removeAll(filterGameIds) //剩余的就是被过滤的游戏id
+ mFilterGameIdSet.addAll(filterGameIdList)
+ //主动过滤含有id的游戏
+ filterGames.removeAll { mFilterGameIdSet.contains(it.id) }
+ //过滤掉了几个游戏,裁剪列表的占位holder,并调整空白条目
+ val filterMinusCount = size - filterGames.size
+ trimDataWithTimeType(dataList, gameTimeType, filterMinusCount)
+ //注册到外部model,用于下载按钮状态更新
+ notifyParentAddGameList(filterGames)
+ filterGames.forEach { gameEntity ->
+ gameList.add(
+ GameDataWrapper(
+ -1, //还未分配位置的数据
+ timeType = gameTimeType,
+ gameData = gameEntity,
+ isPlaceHolder = false,
+ isSpace = false
+ )
+ )
+ }
+ }
+ return gameList
+ }
+
+ /**
+ * 移除指定时间轴的count个数占位条目,
+ * 调整时间轴的空白条目数量,并把后续条目的索引前移
+ */
+ private fun trimDataWithTimeType(
+ dataList: MutableList,
+ timeType: String,
+ count: Int
+ ) {
+ if (count <= 0) return
+ Utils.log(TAG, "过滤掉了时间轴:$timeType 上 $count 个游戏。")
+ val listForTimeType = dataList.filter { it.timeType == timeType }.toMutableList()
+ if (listForTimeType.isEmpty()) return
+ //这个timeType还剩多少个holder占位条目
+ val holderCount = listForTimeType.count { it.isPlaceHolder }
+ if (holderCount < count) return
+ //找到当前timeType的第一个条目索引,后续裁剪都在这个索引之后
+ val timeTypeFirstIndex = listForTimeType.first().index
+ //先清除这个timeType的空白条目,后续裁剪holder后再补回来
+ listForTimeType.removeAll { it.isSpace }
+ //删除指定个数holder
+ val delListForTimeType = listForTimeType.filter { it.isPlaceHolder }.take(count)
+ listForTimeType.removeAll(delListForTimeType)
+ //补充空白条目
+ val rawCount = COLUMN_COUNT
+ val listForTimeTypeCount = listForTimeType.size
+ val spaceCount = rawCount - (listForTimeTypeCount % rawCount)
+ var index = timeTypeFirstIndex + listForTimeTypeCount
+ repeat(spaceCount % rawCount) {
+ listForTimeType.add(GameDataWrapper(index++, timeType = timeType, isSpace = true))
+ }
+ //替换原数组中的timeType列表
+ dataList.removeAll { it.timeType == timeType }
+ dataList.addAll(timeTypeFirstIndex, listForTimeType)
+ //重新给当前timeType以及后面的条目设置索引
+ for (i in timeTypeFirstIndex until dataList.size) {
+ dataList[i].index = i
+ }
+ }
+
+ /**
+ * 选中时间轴,如果列表内有相关数据则滑动到指定位置
+ * @param timeType 时间轴类型 time_type(recommend:推荐、xxxx-xx-xx:全部(比如:2023-01-01))
+ * 还需要做时间轴联动,列表滑动,时间轴也要跟着选中对应的
+ */
+ fun onTimePointSelected(timeType: String) {
+ mTimePointLiveData.postValue(timeType)
+ }
+
+ /**
+ * 点击时间轴, 获取时间节点数据,或者移动列表到指定位置
+ */
+ fun onTimePointClick(timeType: String) {
+ val firstItemWithTimeType = getCurrentData().find { it.timeType == timeType } ?: return
+ val index = firstItemWithTimeType.index
+ if (index != -1) {
+ mGameListScrollLiveData.postValue(index)
+ mLoadStateLiveData.postValue(LoadStatus.INIT_LOADED)
+ }
+ val startId = mTimePoint?.find { it.timeType == timeType }?.id ?: ""
+ if (firstItemWithTimeType.isPlaceHolder) {
+ //加载当前页数据 , 不足limit 则用下一页补足
+ val timeTypeList = mTimePoint?.map { it.timeType }
+ val currentTimeTypeIndex = timeTypeList?.indexOf(timeType)
+ var loadTimeType = ""
+ if (currentTimeTypeIndex != null && currentTimeTypeIndex != -1) {
+ val nextTimeType = timeTypeList.getOrNull(currentTimeTypeIndex + 1)
+ loadTimeType = nextTimeType ?: timeType
+ }
+ loadData(
+ isRefresh = false,
+ action = Action.LEFT,
+ pageId = startId,
+ timeType = timeType,
+ loadTimeType = loadTimeType,
+ startId = startId
+ )
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageExposureExt.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageExposureExt.kt
new file mode 100644
index 0000000000..cb9779d95a
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageExposureExt.kt
@@ -0,0 +1,61 @@
+package com.gh.gamecenter.home.custom
+
+import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.core.runOnIoThread
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem
+
+fun createExposureEvent(
+ game: GameEntity?,
+ source: List,
+ base: List,
+ childPosition: Int,
+ position: Int
+): ExposureEvent {
+ game?.sequence = childPosition
+ game?.outerSequence = position
+ val event = ExposureEvent.createEventWithSourceConcat(
+ gameEntity = game,
+ basicSource = base,
+ source = source
+ )
+ game?.exposureEvent = event
+ return event
+}
+
+fun fillExposureInSubjectCollection(item: CustomSubjectCollectionItem, base: List) {
+
+ val eventList = arrayListOf()
+ runOnIoThread(true) {
+ item.data.data.forEachIndexed { index, customSubject ->
+ val source = if (item.isSubjectCollection) {
+ listOf(
+ ExposureSource("专题合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
+ ExposureSource(
+ "专题",
+ "${customSubject.title}+${customSubject.styleChinese}+${customSubject.id}"
+ )
+ )
+ } else {
+ listOf(
+ ExposureSource("游戏单合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
+ ExposureSource("游戏单", "${customSubject.title}+${customSubject.id}")
+ )
+ }
+ customSubject.games.forEach { game ->
+ game.isAdData = customSubject.adIconActive
+ val event = createExposureEvent(
+ game,
+ source,
+ base,
+ index,
+ item.componentPosition
+ )
+ eventList.add(event)
+ }
+ }
+ }
+ item.exposureEventList = eventList
+
+}
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt
new file mode 100644
index 0000000000..d4b08f0ba0
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt
@@ -0,0 +1,726 @@
+package com.gh.gamecenter.home.custom
+
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.viewModels
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.OnScrollListener
+import com.gh.common.exposure.ExposureListener
+import com.gh.common.exposure.ExposureManager
+import com.gh.common.iinterface.ISearchToolbarTab
+import com.gh.common.iinterface.ISmartRefresh
+import com.gh.common.iinterface.ISmartRefreshContent
+import com.gh.common.iinterface.ISuperiorChain
+import com.gh.common.prioritychain.CustomFloatingWindowHandler
+import com.gh.common.prioritychain.PriorityChain
+import com.gh.common.prioritychain.PullDownPushHandler
+import com.gh.common.util.DefaultSearchHintHelper
+import com.gh.common.util.DialogUtils
+import com.gh.common.util.DirectUtils
+import com.gh.common.util.NewFlatLogUtils
+import com.gh.common.xapk.XapkInstaller
+import com.gh.common.xapk.XapkUnzipStatus
+import com.gh.download.DownloadManager
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.common.base.GlobalActivityManager
+import com.gh.gamecenter.common.base.fragment.LazyFragment
+import com.gh.gamecenter.common.baselist.LoadStatus
+import com.gh.gamecenter.common.constant.Constants
+import com.gh.gamecenter.common.constant.EntranceConsts
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.gh.gamecenter.common.eventbus.EBReuse
+import com.gh.gamecenter.common.exposure.ExposureSource
+import com.gh.gamecenter.common.utils.*
+import com.gh.gamecenter.common.view.OffsetLinearLayoutManager
+import com.gh.gamecenter.core.AppExecutor
+import com.gh.gamecenter.core.iinterface.IScrollable
+import com.gh.gamecenter.core.utils.MD5Utils
+import com.gh.gamecenter.core.utils.SPUtils
+import com.gh.gamecenter.databinding.FragmentCustomBinding
+import com.gh.gamecenter.discovery.DiscoveryActivity
+import com.gh.gamecenter.discovery.interestedgame.InterestedGameActivity
+import com.gh.gamecenter.entity.BottomTab
+import com.gh.gamecenter.entity.PullDownPush
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.eventbus.EBPackage
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.entity.PageLocation
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.feature.exposure.ExposureType
+import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
+import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
+import com.gh.gamecenter.home.PageConfigure
+import com.gh.gamecenter.home.custom.adapter.CustomPageAdapter
+import com.gh.gamecenter.home.custom.floatview.CustomFloatViewAnimationHelper
+import com.gh.gamecenter.home.video.ScrollCalculatorHelper
+import com.gh.gamecenter.livedata.EventObserver
+import com.gh.gamecenter.wrapper.MainWrapperViewModel
+import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperFragment
+import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
+import com.halo.assistant.HaloApp
+import com.lightgame.download.DataWatcher
+import com.lightgame.download.DownloadEntity
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
+
+ private var searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel? = null
+ private var mainWrapperViewModel: MainWrapperViewModel? = null
+
+ private val viewModel by viewModels()
+
+ private lateinit var binding: FragmentCustomBinding
+
+ private lateinit var adapter: CustomPageAdapter
+
+ private lateinit var layoutManager: OffsetLinearLayoutManager
+
+ private lateinit var scrollCalculatorHelper: ScrollCalculatorHelper
+
+ private val priorityChain by lazy { PriorityChain() }
+ private var superiorChain: ISuperiorChain? = null
+
+ private val floatViewManager = CustomFloatViewAnimationHelper()
+
+ private var customPageId = ""
+ private var customPageName = ""
+ private var bottomTabId = ""
+ private var bottomTabName = ""
+ private var tabIndex = -1
+
+ private lateinit var pageLocation: PageLocation
+
+ private var pullDownPushHandler: PullDownPushHandler? = null
+
+ private val isInSearchToolbarTabWrapperPage: Boolean
+ get() = parentFragment is SearchToolbarTabWrapperFragment
+
+ private val dataWatcher = object : DataWatcher() {
+ override fun onDataChanged(downloadEntity: DownloadEntity) {
+ adapter.notifyDownload(downloadEntity)
+
+ if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
+ showUnzipFailureDialog(downloadEntity)
+ }
+ }
+
+ override fun onDataInit(downloadEntity: DownloadEntity) {
+ adapter.notifyDownload(downloadEntity)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setNavigationTitle(arguments?.getString(EntranceConsts.KEY_NAVIGATION_TITLE, "") ?: "")
+ customPageId = arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_ID, "") ?: ""
+ customPageName = arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, "") ?: ""
+ bottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
+ bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
+ tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
+ val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: ""
+ val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
+ val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
+ val noTabLinkId = arguments?.getParcelable(LinkEntity::class.java.simpleName)?.link ?: ""
+
+ if (isInSearchToolbarTabWrapperPage) {
+ searchToolbarTabWrapperViewModel =
+ viewModelProviderFromParent(
+ SearchToolbarTabWrapperViewModel.Factory(multiTabNavId, noTabLinkId),
+ multiTabNavId
+ )
+ }
+ if (bottomTabId.isNotEmpty()) {
+ mainWrapperViewModel = viewModelProviderFromParent(MainWrapperViewModel.Factory(HaloApp.getInstance()))
+ }
+
+ val exposureSourceList = arrayListOf().apply {
+ arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE)?.let {
+ add(it)
+ }
+ arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)?.let {
+ addAll(it)
+ }
+ }
+ // todo transparentBackground的值待定
+ val transparentBackground = true
+ val pageConfigure =
+ PageConfigure(
+ customPageId,
+ 0,
+ mEntrance,
+ transparentBackground,
+ exposureSourceList,
+ isInSearchToolbarTabWrapperPage
+ )
+ pageLocation = PageLocation(
+ bottomTabName,
+ multiTabNavName,
+ multiTabNavId,
+ tabIndex,
+ tabName,
+ customPageName,
+ customPageId
+ )
+
+ viewModel.init(pageConfigure, searchToolbarTabWrapperViewModel, pageLocation)
+ }
+
+ override fun getRealLayoutId() = R.layout.fragment_custom
+
+ override fun onFragmentFirstVisible() {
+ super.onFragmentFirstVisible()
+ if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
+ initMenu(R.menu.menu_download)
+ }
+ binding.reuseSearchBar.root.setPadding(16F.dip2px(), 8F.dip2px(), 16F.dip2px(), 8F.dip2px())
+ mainWrapperViewModel?.bottomDoubleTabAction?.observe(viewLifecycleOwner) {
+ if (isSupportVisible && it.id == bottomTabId) {
+ scrollToTop()
+ }
+ }
+
+ with(viewModel) {
+ dataList.observe(viewLifecycleOwner) {
+ adapter.submitList(it)
+ }
+
+ loadStatus.observe(viewLifecycleOwner) { (status, isPullToRefresh) ->
+ binding.gameRefresh.isRefreshing = false
+
+ if (!isPullToRefresh) {
+ binding.gameList.goneIf(status == LoadStatus.INIT_LOADING || status == LoadStatus.INIT_FAILED || status == LoadStatus.INIT_EMPTY)
+ binding.reuseNoConnection.root.goneIf(status != LoadStatus.INIT_FAILED)
+ if (status == LoadStatus.INIT_LOADING) {
+ binding.reuseLoading.root.goneIf(false)
+ binding.root.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
+ } else {
+ binding.reuseLoading.root.goneIf(true)
+ binding.root.setBackgroundColor(Color.TRANSPARENT)
+ }
+ binding.reuseNoData.root.goneIf(status != LoadStatus.INIT_EMPTY)
+ } else {
+ if (status == LoadStatus.INIT_LOADED) {
+ binding.gameList.visibleIf(true)
+ binding.reuseNoConnection.root.goneIf(true)
+ binding.reuseNoData.root.goneIf(true)
+ }
+ }
+ adapter.setLoadStatus(status)
+ if (status == LoadStatus.INIT_LOADED) {
+ AppExecutor.uiExecutor.executeWithDelay({
+ scroll()
+ scrollCalculatorHelper.onScrollStateChanged(RecyclerView.SCROLL_STATE_IDLE)
+ }, 100)
+ }
+ if (status != LoadStatus.INIT_LOADING) {
+ (parentFragment as? ISmartRefresh)?.finishRefresh()
+ }
+ }
+
+ changAppBarColorAction.observe(viewLifecycleOwner, EventObserver {
+ (parentFragment as? ISearchToolbarTab)?.changeAppBarColor(it, customPageId)
+ })
+
+ pullDownPushData.observe(viewLifecycleOwner) {
+ setSwipeRefreshEnabled(it == null)
+ setPullDownPush(it)
+ }
+
+ pageSwitchData.observe(viewLifecycleOwner) {
+ // 当前自定义页面为二级页面时显示搜索栏
+ if (!requireArguments().getBoolean(EntranceConsts.KEY_IS_HOME, false) && it.topSearch.isNotEmpty()) {
+ binding.reuseSearchBar.root.visibility = View.VISIBLE
+ binding.reuseSearchBar.etSearch.visibility = View.GONE
+ binding.reuseSearchBar.searchTv.visibility = View.VISIBLE
+ setSearchHint(it.topSearch)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ binding.reuseSearchBar.etSearch.focusable = View.NOT_FOCUSABLE
+ }
+ listOf(binding.reuseSearchBar.root, binding.reuseSearchBar.searchTv).forEach { view ->
+ view.setOnClickListener { _ ->
+ DirectUtils.directToSearch(
+ requireContext(),
+ it.topSearch,
+ binding.reuseSearchBar.searchTv.hint.toString(),
+ "搜索栏",
+ "自定义页面",
+ bottomTabName,
+ customPageId = customPageId,
+ customPageName = customPageName
+ )
+ }
+ }
+ }
+ // 当前自定义页面为 底部Tab(非多Tab导航页) 关联的页面时更新搜索类型
+ if (requireArguments().getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "")
+ .isEmpty() && it.topSearch.isNotEmpty()
+ ) {
+ (parentFragment as? ISearchToolbarTab)?.setSearchStyle(BottomTab.SearchStyle(searchType = it.topSearch))
+ }
+ }
+
+ gameDetailDestination.observe(viewLifecycleOwner, EventObserver { (trackData, entrance, game) ->
+ if (game.isQQMiniGame()) {
+ GlobalActivityManager.currentActivity?.let {
+ NewFlatLogUtils.logQGameClick(game.qqMiniGameAppId, game.name)
+ DirectUtils.directToQGameById(it, game.qqMiniGameAppId)
+ }
+ } else {
+ GameDetailActivity.startGameDetailActivity(
+ requireContext(),
+ game.id,
+ entrance,
+ -1,
+ traceEvent = game.exposureEvent,
+ customPageTrackData = trackData
+ )
+ }
+
+ })
+
+ subjectDestination.observe(viewLifecycleOwner, EventObserver { subject ->
+ DirectUtils.directToSubject(
+ requireContext(), subject.id ?: "", subject.name, "自定义页面", null, subject.isQQColumn
+ )
+ })
+
+ subjectDestinationWithCustom.observe(viewLifecycleOwner, EventObserver { (subject, isQqMini) ->
+ DirectUtils.directToSubject(
+ requireContext(), subject.id, subject.title, "自定义页面", null, isQqMini
+ )
+ })
+
+ subjectCollectionDestination.observe(viewLifecycleOwner, EventObserver { (item, childPosition, subject) ->
+ val clickEvent = if (subject != null) {
+ ExposureEvent.createEventWithSourceConcat(
+ GameEntity(outerSequence = childPosition), pageConfigure.exposureSourceList, listOf(
+ ExposureSource("专题合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
+ ExposureSource("专题", "${subject.title}+${subject.styleChinese}+${subject.id}")
+ ), null, ExposureType.CLICK
+ )
+ } else null
+ clickEvent?.let { ExposureManager.log(it) }
+ DirectUtils.directToColumnCollection(
+ requireContext(),
+ item.data.id,
+ childPosition,
+ CustomPageTracker.buildSubjectCollectionEntrance(item),
+ subject?.title ?: "",
+ style = item.data.style,
+ exposureEvent = clickEvent, showSubjectTab = true
+ )
+ })
+
+ gameListDetailDestination.observe(viewLifecycleOwner, EventObserver { (item, childPosition, subject) ->
+ val clickEvent = ExposureEvent.createEventWithSourceConcat(
+ GameEntity(outerSequence = childPosition), pageConfigure.exposureSourceList, listOf(
+ ExposureSource("游戏单合集", "${item.data.name}+${item.componentStyle}+${item.data.id}"),
+ ExposureSource("游戏单", "${subject.title}+${subject.id}")
+ ), null, ExposureType.CLICK
+ )
+ ExposureManager.log(clickEvent)
+ DirectUtils.directToGameCollectionDetail(
+ requireContext(),
+ subject.id,
+ "",
+ "游戏单合集",
+ clickEvent
+ )
+ })
+
+ userDestination.observe(viewLifecycleOwner, EventObserver { (userId, entrance, path) ->
+ DirectUtils.directToHomeActivity(requireContext(), userId, 0, entrance, path)
+ })
+
+ interestedGameDestination.observe(viewLifecycleOwner, EventObserver {
+ requireContext().startActivity(
+ InterestedGameActivity.getIntent(
+ requireContext(),
+ "${pageConfigure.entrance}-发现页卡片"
+ )
+ )
+
+ })
+
+ discoverDestination.observe(viewLifecycleOwner, EventObserver {
+ requireContext().startActivity(
+ DiscoveryActivity.getIntent(
+ requireContext(),
+ "${pageConfigure.entrance}-发现页卡片"
+ )
+ )
+ })
+
+ linkDestination.observe(viewLifecycleOwner, EventObserver { data ->
+ DirectUtils.directToLinkPage(requireContext(), data.first, "自定义页面", "", data.second)
+ })
+
+ amwayDestination.observe(viewLifecycleOwner, EventObserver {
+ DirectUtils.directToAmway(requireContext(), null, "(游戏-专题:安利墙-全部)", "")
+ })
+
+ badgeWallDestination.observe(viewLifecycleOwner, EventObserver {
+ DirectUtils.directToBadgeWall(
+ requireContext(),
+ it.user.id,
+ it.user.name,
+ it.user.icon
+ )
+ })
+
+ gameDetailDestinationOnAmway.observe(
+ viewLifecycleOwner,
+ EventObserver { (trackData, gameId, exposureEvent) ->
+ GameDetailActivity.startGameDetailActivity(
+ requireContext(),
+ gameId = gameId,
+ entrance = "自定义页面",
+ defaultTab = -1,
+ traceEvent = exposureEvent,
+ customPageTrackData = trackData
+ )
+ })
+
+ ratingReplyDestination.observe(viewLifecycleOwner, EventObserver { (gameId, commentId) ->
+ val entrance = "安利墙"
+ val exposureSource =
+ arrayListOf(
+ ExposureSource("自定义页面", "${pageLocation.pageName}+${pageLocation.pageId}"),
+ ExposureSource("安利墙")
+ ).toJson()
+ val intent = RatingReplyActivity.getIntent(
+ context = requireContext(),
+ gameId = gameId,
+ commentId = commentId,
+ showKeyboardIfReplyListIsEmpty = false,
+ exposureSource = exposureSource,
+ entrance = entrance,
+ path = ""
+ )
+ requireContext().startActivity(intent)
+ })
+
+ commonCollectionDestination.observe(viewLifecycleOwner, EventObserver { (commonCollection, collectionId) ->
+ val intent = CustomCommonCollectionDetailActivity.getIntent(
+ requireContext(),
+ collectionId,
+ commonCollection.layout,
+ "自定义页面",
+ )
+ startActivity(intent)
+ })
+
+ gameListCollectionDestination.observe(viewLifecycleOwner, EventObserver {
+ DirectUtils.directToGameCollectionListDetail(
+ requireContext(),
+ it.data.id,
+ it.data.name,
+ it.data.explain,
+ "自定义页面"
+ )
+ })
+
+ gameListSquareDestination.observe(viewLifecycleOwner, EventObserver {
+ DirectUtils.directToGameCollectionSquare(
+ requireContext(),
+ "版块内容列表",
+ "",
+ collectionName = it.data.name,
+ collectionId = it.data.id
+ )
+ })
+ }
+
+ searchToolbarTabWrapperViewModel?.backgroundAlpha?.observe(viewLifecycleOwner) {
+ val viewHolder = binding.gameList.findViewHolderForAdapterPosition(0)
+ if (viewHolder is OnCustomPageRefreshStateListener) {
+ viewHolder.onBackgroundAlphaChanged(it)
+ }
+ }
+
+ SensorsBridge.trackViewCustomPage(
+ pageLocation.bottomTab,
+ pageLocation.severalTabPageId,
+ pageLocation.severalTabPageName,
+ pageLocation.tabPosition,
+ pageLocation.tabContent,
+ pageLocation.pageId,
+ pageLocation.pageName
+ )
+
+ viewModel.loadData()
+ }
+
+ private fun setSearchHint(searchType: String) {
+ when (searchType) {
+ BottomTab.SearchStyle.TYPE_HALO_GAME -> DefaultSearchHintHelper.setSearchHint(binding.reuseSearchBar.searchTv)
+ BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> binding.reuseSearchBar.searchTv.hint = "请输入小游戏关键词"
+ BottomTab.SearchStyle.TYPE_BBS -> binding.reuseSearchBar.searchTv.hint = "搜索论坛内容、用户"
+ }
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+
+ binding = FragmentCustomBinding.bind(mCachedView)
+
+ buildPriorityChain()
+
+ scrollCalculatorHelper = ScrollCalculatorHelper(binding.gameList, R.id.autoVideoView, 0)
+
+ adapter = CustomPageAdapter(
+ viewModel,
+ viewLifecycleOwner,
+ scrollCalculatorHelper,
+ )
+ layoutManager = OffsetLinearLayoutManager(requireContext())
+ binding.gameList.itemAnimator = null
+ binding.gameList.layoutManager = layoutManager
+ binding.gameList.adapter = adapter
+
+ var listScrollHeight = 0
+ binding.gameList.addOnScrollListener(object : OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ floatViewManager.onScrollChanged(newState != RecyclerView.SCROLL_STATE_IDLE)
+ scrollCalculatorHelper.onScrollStateChanged(newState)
+ }
+
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ listScrollHeight += dy
+ onScrollChanged()
+ scroll()
+ }
+ })
+
+ val exposureListener = ExposureListener(this, adapter)
+ binding.gameList.addOnScrollListener(exposureListener)
+
+ binding.reuseNoConnection.connectionReloadTv.setOnClickListener {
+ viewModel.loadFirst(false)
+ }
+
+ binding.gameRefresh.setOnRefreshListener {
+ onRefresh()
+ }
+ }
+
+ private fun buildPriorityChain() {
+ pullDownPushHandler = PullDownPushHandler(5)
+ val floatingWindowHandler = CustomFloatingWindowHandler(10)
+
+ priorityChain.addHandler(pullDownPushHandler!!)
+ priorityChain.addHandler(floatingWindowHandler)
+
+ viewModel.floatingWindows.observe(viewLifecycleOwner, EventObserver {
+ floatingWindowHandler.setData(it)
+ })
+
+ floatingWindowHandler.showFloatingAction.observe(viewLifecycleOwner, EventObserver {
+ binding.floatingView.setData(it, pageLocation, viewModel.pageConfigure.exposureSourceList)
+ floatViewManager.show(binding.floatingView)
+ })
+
+ binding.floatingView.setExpandListener { entity, hasAnimation ->
+ val dialog = CustomWelcomeDialogFragment.getInstance(entity, true, this, hasAnimation, pageLocation)
+ dialog.setDismissListener {
+ floatViewManager.resume()
+ }
+ dialog.show(childFragmentManager, CustomWelcomeDialogFragment.TAG)
+ }
+
+ if (superiorChain != null) {
+ superiorChain?.registerInferiorChain(priorityChain)
+ } else {
+ priorityChain.start()
+ }
+ }
+
+ private fun onScrollChanged(isDarkModeChanged: Boolean = false) {
+ if (parentFragment is ISearchToolbarTab &&
+ (tabIndex == (parentFragment as ISearchToolbarTab).getCurrentTabIndex() || tabIndex == -1) &&
+ ::layoutManager.isInitialized
+ ) {
+ val bannerViewHeight = layoutManager.heightMap[0] ?: 0
+ (parentFragment as ISearchToolbarTab).onScrollChanged(
+ bannerViewHeight,
+ binding.gameList.computeVerticalScrollOffset(),
+ isDarkModeChanged
+ )
+ }
+ }
+
+ private fun scroll() {
+ val firstVisibleItem = layoutManager.findFirstVisibleItemPosition()
+ val lastVisibleItem = layoutManager.findLastVisibleItemPosition()
+ scrollCalculatorHelper.onScroll(firstVisibleItem, lastVisibleItem)
+ }
+
+ override fun onFragmentPause() {
+ super.onFragmentPause()
+ pauseVideo()
+
+ if (::adapter.isInitialized) {
+ DownloadManager.getInstance().removeObserver(dataWatcher)
+ }
+
+ superiorChain?.unregisterInferiorChain(priorityChain)
+ }
+
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+ resumeVideo()
+ if (::adapter.isInitialized) {
+ DownloadManager.getInstance().addObserver(dataWatcher)
+ }
+ viewModel.pullDownPushData.value?.let { setPullDownPush(it) }
+
+ superiorChain?.registerInferiorChain(priorityChain)
+ }
+
+ private fun setPullDownPush(pullDownPush: PullDownPush?) {
+ (parentFragment as? ISmartRefresh)?.setPullDownPush(pullDownPush, pullDownPushHandler)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (::scrollCalculatorHelper.isInitialized) {
+ scrollCalculatorHelper.release()
+ }
+ }
+
+ //下载被删除事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(status: EBDownloadStatus) {
+ if (::adapter.isInitialized && "delete" == status.status) {
+ adapter.notifyDownloadDeleted(status)
+ }
+ }
+
+ //安装、卸载事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(busFour: EBPackage) {
+ if (::adapter.isInitialized) {
+ adapter.notifyInstalled(busFour)
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(reuse: EBReuse) {
+ if (::adapter.isInitialized && "Refresh" == reuse.type) {
+ setSearchHint(viewModel.pageSwitchData.value?.topSearch ?: "")
+ adapter.notifyDataSetChanged()
+ }
+ }
+
+ fun setSuperiorChain(superiorChain: ISuperiorChain?): CustomPageFragment {
+ this.superiorChain = superiorChain
+ return this
+ }
+
+ private fun pauseVideo() {
+ val currentPlayer = scrollCalculatorHelper.currentPlayer
+ if (currentPlayer != null) {
+ currentPlayer.resetDetailMask()
+ currentPlayer.onVideoPause()
+ val currentPosition = currentPlayer.getCurrentPosition()
+
+ val videoUrl = currentPlayer.getUrl()
+ if (videoUrl.isNotEmpty()) {
+ ScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(videoUrl), currentPosition)
+ }
+ }
+ }
+
+ private fun resumeVideo() {
+ val currentPlayer = scrollCalculatorHelper.currentPlayer
+ if (currentPlayer != null) {
+ val videoUrl = currentPlayer.getUrl()
+ if (videoUrl.isNotEmpty()) {
+ val position = ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(videoUrl))
+ //这里必须要延迟操作,否则会白屏
+ mBaseHandler.postDelayed({
+ if (position != 0L) {
+ scrollCalculatorHelper.currentPlayer?.seekTo(position)
+ scrollCalculatorHelper.currentPlayer?.onVideoResume(false)
+ val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
+ if (topVideoVoiceStatus) {
+ scrollCalculatorHelper.currentPlayer?.mute()
+ } else {
+ scrollCalculatorHelper.currentPlayer?.unMute()
+ }
+ } else {
+ scrollCalculatorHelper.currentPlayer?.release()
+ }
+
+ }, 50)
+ }
+ }
+ }
+
+ fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
+ val data = adapter.getGameEntityByPackage(downloadEntity.packageName)
+ for (gameAndPosition in data) {
+ val targetView = layoutManager.findViewByPosition(gameAndPosition.position)
+ if (targetView != null) {
+ if (targetView is RecyclerView) {
+ // todo 如果时竖向专题该怎么判断?
+ } else {
+ DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
+ return
+ }
+ }
+ }
+ }
+
+ override fun onDarkModeChanged() {
+ super.onDarkModeChanged()
+ if (::adapter.isInitialized && ::binding.isInitialized) {
+ binding.gameList.tryToClearRecycler()
+ binding.gameList.recycledViewPool.clear()
+
+ adapter.notifyItemRangeChanged(0, adapter.itemCount)
+ binding.gameList.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
+ binding.reuseSearchBar.searchTv.setHintTextColor(R.color.text_instance.toColor(requireContext()))
+ onScrollChanged(true)
+ }
+ }
+
+ override fun setScrollEnabled(isScrollEnabled: Boolean) {
+ if (::layoutManager.isInitialized) {
+ layoutManager.isScrollVerticallyEnabled = isScrollEnabled
+ }
+ }
+
+ override fun onRefresh() {
+ viewModel.onRefresh()
+ viewModel.loadFirst(true, true)
+ }
+
+ override fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean) {
+ if (::binding.isInitialized) {
+ binding.gameRefresh.isEnabled = isSwipeRefreshEnabled
+ }
+ }
+
+ override fun scrollToTop() {
+ if (::binding.isInitialized) {
+ binding.gameList.stopScroll()
+ binding.gameList.scrollToPosition(0)
+ }
+ }
+
+ fun getFloatingViewY(): Int = if (::binding.isInitialized) {
+ val locations = IntArray(2)
+ binding.floatingView.getLocationInWindow(locations)
+ locations[1]
+ } else {
+ 0
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageTracker.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageTracker.kt
new file mode 100644
index 0000000000..6d8032983e
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageTracker.kt
@@ -0,0 +1,123 @@
+package com.gh.gamecenter.home.custom
+
+import com.gh.gamecenter.common.entity.LinkEntity
+import com.gh.gamecenter.common.utils.SensorsBridge
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_GAME_COLLECT_ID
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_GAME_COLLECT_TITLE
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_GAME_ID
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_GAME_NAME
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_LINK_ID
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_LINK_TEXT
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_LINK_TYPE
+import com.gh.gamecenter.common.utils.SensorsBridge.KEY_MONGOLD_ID
+import com.gh.gamecenter.feature.entity.PageLocation
+import com.gh.gamecenter.home.custom.model.CustomPageData
+import com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem
+
+class CustomPageTracker(val pageLocation: PageLocation) {
+
+ fun trackGameListCollectionClickWithMore(item: CustomSubjectCollectionItem, link: LinkEntity) {
+ val otherParams = HashMap().apply {
+ put(KEY_LINK_ID, link.link ?: "")
+ put(KEY_LINK_TYPE, link.type ?: "")
+ put(KEY_LINK_TEXT, link.text ?: "")
+ }
+ trackGameListCollectionClick(item, "更多", otherParams)
+ }
+
+ fun trackGameListCollectionClickWithGameListSquare(item: CustomSubjectCollectionItem) {
+ trackGameListCollectionClick(item, "游戏单广场")
+ }
+
+ fun trackGameListCollectionClickWithUser(item: CustomSubjectCollectionItem, userId: String) {
+ val otherParams = hashMapOf(
+ KEY_MONGOLD_ID to userId
+ )
+ trackGameListCollectionClick(item, "个人主页", otherParams)
+ }
+
+ fun trackGameListCollectionClickWithGame(item: CustomSubjectCollectionItem, gameId: String, gameName: String?) {
+ val otherParams = hashMapOf(
+ KEY_GAME_ID to gameId,
+ KEY_GAME_NAME to (gameName ?: "")
+ )
+ trackGameListCollectionClick(item, "游戏", otherParams)
+ }
+
+ fun trackGameListCollectionClickWithGameCollection(
+ item: CustomSubjectCollectionItem,
+ gameCollectId: String,
+ gameCollectTitle: String
+
+ ) {
+ val otherParams = hashMapOf(
+ KEY_GAME_COLLECT_ID to gameCollectId,
+ KEY_GAME_COLLECT_TITLE to gameCollectTitle
+ )
+ trackGameListCollectionClick(item, "游戏单", otherParams)
+ }
+
+ fun trackGameListCollectionClick(
+ item: CustomSubjectCollectionItem,
+ text: String,
+ otherParams: HashMap = hashMapOf()
+ ) {
+ SensorsBridge.trackGameListCollectionClick(
+ LOCATION_CUSTOM_PAGE,
+ item.data.id,
+ item.data.name,
+ text,
+ pageLocation.bottomTab,
+ pageLocation.severalTabPageId,
+ pageLocation.severalTabPageName,
+ pageLocation.tabPosition,
+ pageLocation.tabContent,
+ pageLocation.pageId,
+ pageLocation.pageName,
+ item.componentStyle,
+ otherParams
+ )
+ }
+
+ fun trackColumnCollectionClick(
+ item: CustomSubjectCollectionItem,
+ subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity?,
+ text: String
+ ) {
+ SensorsBridge.trackColumnCollectionClick(
+ LOCATION_CUSTOM_PAGE,
+ "",
+ "",
+ item.data.name,
+ item.data.id,
+ item.position,
+ subject?.title ?: "",
+ subject?.id ?: "",
+ text,
+ item.componentStyle,
+ pageLocation.bottomTab,
+ pageLocation.severalTabPageId,
+ pageLocation.severalTabPageName,
+ pageLocation.tabPosition,
+ pageLocation.tabContent,
+ pageLocation.pageId,
+ pageLocation.pageName
+ )
+ }
+
+ companion object {
+
+ const val LOCATION_CUSTOM_PAGE = "自定义页面"
+
+ fun buildGameSubjectEntrance(subjectName: String, childPosition: Int) =
+ "(游戏-专题:${subjectName}-列表[${childPosition + 1}])"
+
+ fun buildSubjectCollectionEntrance(item: CustomSubjectCollectionItem): String {
+ return if (item.isSubjectCollection) {
+ "专题合集-${item.componentStyle}"
+ } else {
+ ""
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt
new file mode 100644
index 0000000000..7264ed6d4f
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt
@@ -0,0 +1,724 @@
+package com.gh.gamecenter.home.custom
+
+import android.app.Application
+import androidx.collection.ArrayMap
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Observer
+import com.gh.common.util.GameUtils
+import com.gh.common.util.NewFlatLogUtils
+import com.gh.common.util.NewLogUtils
+import com.gh.gamecenter.common.baselist.LoadStatus
+import com.gh.gamecenter.common.constant.Constants
+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.observableToMain
+import com.gh.gamecenter.core.utils.RandomUtils
+import com.gh.gamecenter.core.utils.SPUtils
+import com.gh.gamecenter.entity.HomeSubSlide
+import com.gh.gamecenter.entity.PullDownPush
+import com.gh.gamecenter.entity.RatingComment
+import com.gh.gamecenter.entity.SubjectEntity
+import com.gh.gamecenter.feature.entity.CustomPageTrackData
+import com.gh.gamecenter.feature.entity.GameEntity
+import com.gh.gamecenter.feature.entity.PageLocation
+import com.gh.gamecenter.feature.exposure.ExposureEvent
+import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
+import com.gh.gamecenter.home.PageConfigure
+import com.gh.gamecenter.home.custom.GamePositionAndPackageHelper.Companion.putGameWithPosition
+import com.gh.gamecenter.home.custom.eventlistener.OnCustomPageEventListener
+import com.gh.gamecenter.home.custom.model.*
+import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2
+import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST
+import com.gh.gamecenter.livedata.Event
+import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
+import com.lightgame.utils.Utils
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import retrofit2.HttpException
+import kotlin.collections.set
+
+class CustomPageViewModel(
+ application: Application
+) : AndroidViewModel(application), OnCustomPageEventListener {
+
+ private val compositeDisposable = CompositeDisposable()
+
+ val newGameTestUserCase = CustomNewGameTestUseCase().apply {
+ setOnGameListAddCallback { position, gameEntities ->
+ gameEntities.forEach {
+ gamePositionAndPackageHelper.putGamePositionAndPackage(it, position)
+ }
+ }
+ }
+
+ private val repository = CustomPageRepository.newInstance()
+
+ val gamePositionAndPackageHelper = GamePositionAndPackageHelper()
+
+ private var _pageConfigure = PageConfigure()
+ val pageConfigure: PageConfigure
+ get() = _pageConfigure
+
+ private val _customPageData = MutableLiveData()
+ val customPageData: LiveData = _customPageData
+
+ private val _dataList = MutableLiveData>()
+ val dataList: LiveData> = _dataList
+
+ private val _loadStatus = MutableLiveData>()
+ val loadStatus: LiveData> = _loadStatus
+
+ var refreshCount = 0
+
+ private val recentGamesObserver = Observer(::notifyItemChanged)
+
+ private val pluginObserver = Observer(::notifyItemChanged)
+
+ private val discoverObserver = Observer(::notifyItemChanged)
+
+ val pullDownPushData = MutableLiveData()
+ val pageSwitchData = MutableLiveData()
+
+ private var searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel? = null
+
+ private val subjectChangedMap: ArrayMap> = ArrayMap()
+
+ var slideDiscoveryGamesPage = -1
+
+ private lateinit var _pageTracker: CustomPageTracker
+
+ val pageTracker: CustomPageTracker
+ get() = _pageTracker
+
+ val pageLocation: PageLocation
+ get() = pageTracker.pageLocation
+
+ init {
+ repository.recentGamesItemLiveData.observeForever(recentGamesObserver)
+ repository.customPluginItemLiveData.observeForever(pluginObserver)
+ repository.customDiscoverItemLiveData.observeForever(discoverObserver)
+ }
+
+ fun init(
+ pageConfigure: PageConfigure,
+ searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel?,
+ pageLocation: PageLocation
+ ) {
+ this.searchToolbarTabWrapperViewModel = searchToolbarTabWrapperViewModel
+ _pageConfigure = pageConfigure
+ _pageTracker = CustomPageTracker(pageLocation)
+ }
+
+
+ fun loadData() {
+ loadFirst(false)
+ loadSuspendedWindow()
+ }
+
+ /**
+ * 由于悬浮窗每次弹出都需要计数,这里当成一次性事件处理
+ */
+ private val _floatingWindows = MutableLiveData>>()
+ val floatingWindows: LiveData>> = _floatingWindows
+
+ private fun loadSuspendedWindow() {
+ if (floatingWindows.value != null) {
+ return
+ }
+ repository.loadSuspendedWindow(pageConfigure.pageId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse>() {
+ override fun onSuccess(data: List) {
+ _floatingWindows.value = Event(data)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ _floatingWindows.value = Event(emptyList())
+ }
+
+ }).addDisposable()
+ }
+
+ fun loadFirst(isPullToRefresh: Boolean, forceLoad: Boolean = false) {
+ _loadStatus.value = LoadStatus.INIT_LOADING to isPullToRefresh
+ repository.loadFirstCustomPageData(pageConfigure.pageId, forceLoad)
+ .map { (custom, list) ->
+ Triple(custom, list, getPositionAndPackageMap(list))
+ }
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse, HashMap>>() {
+ override fun onSuccess(data: Triple, HashMap>) {
+ val (custom, list, gameWithPositionMap) = data
+
+ val isSlideBackgroundColorEnable =
+ custom.customsComponents.firstOrNull()?.linkCommonCollection?.layout == CustomPageItem.COMMON_CONTENT_COLLECTION_LAYOUT_BANNER
+ searchToolbarTabWrapperViewModel?.enableSlideBackgroundColor(
+ pageConfigure.pageId,
+ isSlideBackgroundColorEnable
+ )
+ pullDownPushData.postValue(custom.linkPullDownPush?.apply {
+ this.isSlideBackgroundColorEnable = isSlideBackgroundColorEnable
+ this.customPageId = pageLocation.pageId
+ this.customPageName = pageLocation.pageName
+ this.game?.customPageTrackData = CustomPageTrackData(pageLocation, moduleType = "下拉推送")
+ })
+
+ gamePositionAndPackageHelper.putAll(gameWithPositionMap)
+ pageConfigure.setCustomPageExposureSource("${custom.title}+${pageConfigure.pageId}")
+
+ _customPageData.value = custom
+ pageSwitchData.postValue(custom.pageSwitch)
+ _dataList.value = list
+ _loadStatus.value = if (list.isEmpty()) {
+ LoadStatus.INIT_EMPTY to isPullToRefresh
+ } else {
+ LoadStatus.INIT_LOADED to isPullToRefresh
+ }
+
+ if (custom.pageSwitch.suspendedWindow) {
+ loadSuspendedWindow()
+ }
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ _loadStatus.value = LoadStatus.INIT_FAILED to isPullToRefresh
+
+ }
+
+ }).addDisposable()
+
+ }
+
+ override fun onRefresh() {
+ refreshCount++
+ NewFlatLogUtils.logHomePagePullRefresh(refreshCount)
+ }
+
+ override fun onLoadMore() {
+ val status = loadStatus.value?.first ?: LoadStatus.INIT
+ if (status == LoadStatus.LIST_LOADING || status == LoadStatus.INIT_LOADING || status == LoadStatus.LIST_OVER) {
+ return
+ }
+ _loadStatus.value = LoadStatus.LIST_LOADING to false
+ repository.loadNextCustomPageData(pageConfigure.pageId)
+ .map {
+ it to getPositionAndPackageMap(it)
+ }
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse, HashMap>>() {
+
+ override fun onSuccess(data: Pair, HashMap>) {
+ val (list, gameWithPositionMap) = data
+ gamePositionAndPackageHelper.putAll(gameWithPositionMap)
+ _loadStatus.value = if (list.isEmpty()) {
+ LoadStatus.LIST_OVER to false
+ } else {
+ LoadStatus.LIST_LOADED to false
+ }
+ addData(list)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ _loadStatus.value = LoadStatus.LIST_FAILED to false
+ }
+ }).addDisposable()
+ }
+
+
+ override fun onRetry() {
+ loadFirst(false)
+ }
+
+ override fun onRotateRefresh(customSubjectCollectionItem: CustomSubjectCollectionItem) {
+ if (customSubjectCollectionItem.isLoadedEnd) {
+ notifyItemChanged(customSubjectCollectionItem.copy().apply {
+ showPage = customSubjectCollectionItem.showPage + 1
+ isLoading = false
+ isLoadedEnd = true
+ isBackToStart = true
+ })
+ } else {
+ repository.loadCollectionContent(customSubjectCollectionItem)
+ .map {
+ // 将新加载的游戏单添加到对应的游戏单合集中
+ it to getPositionAndPackageMap(customSubjectCollectionItem, it.firstOrNull()?.games)
+ }
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object :
+ BiResponse, HashMap>>() {
+ override fun onSuccess(data: Pair, HashMap