Compare commits

...

275 Commits

Author SHA1 Message Date
8a7d588206 fix:去除SettingEntity的是否同步认证弹窗的字段 2022-06-14 16:12:39 +08:00
42ae45c743 fix:消除警告 2022-06-14 13:49:53 +08:00
3246dd0d70 fix:修改助手是否进行了实名认证的判断 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1911#note_153274 2022-06-14 09:50:00 +08:00
06ac1fd8b0 fix:同步实名认证功能 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1911#note_153274 2022-06-13 16:24:07 +08:00
81da40d786 fix:同步实名认证功能修改02 2022-06-10 11:22:49 +08:00
9eb919b3cf fix:同步实名认证功能修改 2022-06-09 14:31:47 +08:00
b4cbff3d6a feat:新增同步实名认证功能 2022-06-09 09:59:07 +08:00
c7dfac8f46 fix: 更正实名状态为空时的处理
【单机插件】实名认证功能第二期(https://git.shanqu.cc/pm/halo-plugin-issues/-/issues/221)
2022-06-06 15:45:01 +08:00
08af4a99f8 fix: 移除无用对象声明
【单机插件】实名认证功能第二期(https://git.shanqu.cc/pm/halo-plugin-issues/-/issues/221)
2022-06-06 15:38:08 +08:00
f3a358eb2d feat: 对接未成年人字段
【单机插件】实名认证功能第二期(https://git.shanqu.cc/pm/halo-plugin-issues/-/issues/221)
2022-06-06 15:36:40 +08:00
6abac72ee7 添加简单的占位 Content Provider 2022-06-02 11:46:31 +08:00
b027c57a7c 提供实名认证ContentProvider 2022-06-02 11:42:19 +08:00
84b876394d Merge branch 'hotfix-v5.9.0-532-crashes' into 'release'
修复首页游戏单轮播引发的一些闪退

See merge request halo/android/assistant-android!256
2022-05-27 18:27:22 +08:00
3fb031c329 修复首页游戏单轮播引发的一些闪退 2022-05-27 18:25:22 +08:00
e46afac397 Merge branch 'hotfix-v5.9.0-532-crashes' into 'release'
修复首页游戏单安利墙引发的一些闪退

See merge request halo/android/assistant-android!255
2022-05-27 17:46:49 +08:00
fdf2c80667 修复首页游戏单安利墙引发的一些闪退 2022-05-27 17:34:01 +08:00
d12a1037a2 版本更新至 5.9.0-532 2022-05-24 17:51:10 +08:00
056400d4d1 Merge branch 'dev' into 'release'
累积变更

See merge request halo/android/assistant-android!253
2022-05-21 16:02:02 +08:00
26cbdeaf2d Merge branch 'feature-issues1865' into 'release'
【合规相关】单机游戏内实名校验功能(3) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1865

See merge request halo/android/assistant-android!252
2022-05-21 15:58:45 +08:00
6a5f7f8284 【合规相关】单机游戏内实名校验功能(3) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1865 2022-05-21 15:57:23 +08:00
f272e486f8 【光环助手v5.10.0】前端优化汇总5月第3周(9) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-20 11:40:29 +08:00
7b0514c055 处理 SonarQube 问题 2022-05-19 15:18:00 +08:00
909e7f33a8 Merge branch 'hotfix-v5.9.0-531-night_mode_switch' into 'release'
关闭遗漏的夜间模式切换代码

See merge request halo/android/assistant-android!251
2022-05-19 11:54:24 +08:00
677511b119 关闭遗漏的夜间模式切换代码 2022-05-19 11:52:57 +08:00
26a2605cd7 Merge branch 'hotfix-v5.9.0-530-crash' into 'release'
修复首页未初始化时切换日夜间模式导致的闪退

See merge request halo/android/assistant-android!250
2022-05-19 11:21:20 +08:00
b02f650a34 修复首页未初始化时切换日夜间模式导致的闪退 2022-05-19 11:19:25 +08:00
e1d82e7fbd 版本更新至 5.9.0-531 2022-05-18 16:21:44 +08:00
4263f53315 【光环助手v5.10.0】前端优化汇总5月第3周(6) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-18 15:14:17 +08:00
f235959372 Merge branch 'hotfix-v5.9.0-530-fragment_resume_crash' into 'release'
修复特殊场景下 fragment 恢复页面时的闪退

See merge request halo/android/assistant-android!249
2022-05-18 15:13:09 +08:00
7bc6655b99 修复特殊场景下 fragment 恢复页面时的闪退 2022-05-18 15:12:24 +08:00
7ecc227df5 修复从其他页面返回首页搜索栏变成深色的问题 2022-05-18 11:49:25 +08:00
3046d33f91 Merge branch 'hotfix-v5.9.0-530-crash' into 'release'
修复游戏单安利墙轮播发生的闪退问题,修复从其他页面返回首页搜索栏变成深色的问题

See merge request halo/android/assistant-android!248
2022-05-18 11:45:28 +08:00
a32829fd0d 【光环助手v5.10.0】前端优化汇总5月第3周(6) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-18 11:45:25 +08:00
4819bf3ddf 修复从其他页面返回首页搜索栏变成深色的问题 2022-05-18 11:15:12 +08:00
c2e02d356d 修复游戏单安利墙轮播发生的闪退问题 2022-05-18 11:09:23 +08:00
dafaeef184 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/MainActivity.java
#	app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt
#	dependencies.gradle
2022-05-17 17:10:54 +08:00
a9917c9201 Merge branch 'hotfix-v5.8.1-512-game_list_outofbounds_crash' into 'release'
修复游戏库横向滑动专题数量为空时会闪退的问题

See merge request halo/android/assistant-android!247
2022-05-17 14:44:24 +08:00
c0b61822c0 修复游戏库横向滑动专题数量为空时会闪退的问题 2022-05-17 14:29:15 +08:00
a16a16cbdf 【光环助手V5.10.0】视频模板活动问题汇总(4) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1852 2022-05-16 16:57:26 +08:00
0decb62237 【光环助手v5.10.0】前端优化汇总5月第3周(5) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-16 09:36:55 +08:00
cdedea5002 【光环助手v5.10.0】前端优化汇总5月第3周(1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-13 14:39:42 +08:00
88c4ebe5a0 Merge branch 'hotfix-v5.8.1-512-databinding' into 'release'
修复移除databinding引发的问题

See merge request halo/android/assistant-android!246
2022-05-13 14:38:26 +08:00
10cbcdd768 【光环助手v5.10.0】前端优化汇总5月第3周(1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1858 2022-05-13 14:12:51 +08:00
7afbfb30a2 【光环助手V5.10.0】视频模板活动问题汇总(2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1852 2022-05-11 15:47:35 +08:00
090a567887 版本更新至 5.8.1 2022-05-11 15:09:05 +08:00
e55faee9fe Merge branch 'hotfix-v5.8.0-511-setting_crash' into 'release'
修复快速进出设置界面可能的闪退问题

See merge request halo/android/assistant-android!244
2022-05-11 15:07:29 +08:00
362e34be8a 修复快速进出设置界面可能的闪退问题 2022-05-11 15:06:08 +08:00
bf1e5586b0 Merge branch 'hotfix-v5.8.0-511-xapk_unzip_permission_on_android_s' into 'release'
修复 XAPK 在 Android 12 授权后无法解压的问题

See merge request halo/android/assistant-android!243
2022-05-11 14:28:47 +08:00
bad10158bd 修复 XAPK 在 Android 12 授权后无法解压的问题 2022-05-11 14:21:47 +08:00
5cc58e2182 Merge branch 'hotfix-v5.8.0-511_webpage_portrait' into 'release'
修改打开网页会变为横屏问题

See merge request halo/android/assistant-android!242
2022-05-11 11:47:30 +08:00
fd836137a5 修改打开网页会变为横屏问题 2022-05-11 11:05:18 +08:00
b122e460cc 补充夜间模式开关控制 2022-05-09 17:50:26 +08:00
3b29fcbef7 处理顶部 toolbar 图标存在毛刺的问题 2022-05-09 17:01:30 +08:00
9f60a2ba86 调整编译脚本 2022-05-09 16:49:35 +08:00
8df7b3d9ee 编译脚本添加关闭夜间模式入口 2022-05-09 16:40:57 +08:00
e2040f9a2d 添加夜间模式功能全局控制开关 2022-05-09 16:36:36 +08:00
e39cd494b5 日夜间模式的切换(用户中心部分) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-09 11:49:38 +08:00
f70b721441 版本更新至 5.8.0-511 2022-05-09 10:20:20 +08:00
lyr
877acf54f4 日夜间模式的切换(新分类页面-优化) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 18:31:45 +08:00
a31d7a06f7 修复ToolbarActivity空指针闪退 2022-05-07 18:26:56 +08:00
f52937830b 新增Extensions方法 2022-05-07 18:25:00 +08:00
b5202cc931 日夜间模式的切换(资讯页面、工具箱、设置页面 补充) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 17:14:47 +08:00
dd2bfbc53f 日夜间模式的切换(游戏板块部分) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 16:48:01 +08:00
d2f3cdadf6 修改游戏详情图片重复刷新问题 2022-05-07 16:04:32 +08:00
73a88f9099 Merge branch 'dev' of git.shanqu.cc:halo/android/assistant-android into dev 2022-05-07 15:45:50 +08:00
a86c957872 日夜间模式的切换(社区论坛部分) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 15:45:45 +08:00
lyr
45588a2580 日夜间模式的切换(新分类页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 15:39:03 +08:00
3b55269319 Merge remote-tracking branch 'origin/release' into dev 2022-05-07 15:18:17 +08:00
01966a87ec 移除废弃的广点通部分代码 2022-05-07 15:18:05 +08:00
b4a8e5c68d 日夜间模式的切换(游戏单部分) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-07 14:17:18 +08:00
aeb7842299 正式包移除夜间模式功能 2022-05-07 09:55:42 +08:00
lyr
e0bcf947bf 【光环助手V5.9.0】新社区7期-论坛详情页优化(增加标签字体颜色字段)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1789#note_146539 2022-05-06 20:53:09 +08:00
30bf685962 日夜间模式的切换(专题页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-06 20:48:17 +08:00
1e6fa023dc Merge branch 'dev' of git.shanqu.cc:halo/android/assistant-android into dev 2022-05-06 20:42:44 +08:00
b5920fc409 【光环助手V5.9.0】新社区7期-新增视频模板活动优化(后台)(22020506测试反馈1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1796 2022-05-06 20:42:35 +08:00
16ceb7115e Merge remote-tracking branch 'origin/dev' into dev 2022-05-06 18:29:57 +08:00
279ed66270 处理 SonarQube 问题 2022-05-06 18:28:56 +08:00
lyr
9bfa8a33c8 【光环助手V5.9.0】后台优化汇总4月第3周(16)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1802#note_146500 2022-05-06 18:24:57 +08:00
99bd4da08a 处理合并异常 2022-05-06 18:00:13 +08:00
4824814981 Merge remote-tracking branch 'origin/dev-5.9.0' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeFragment.kt
#	app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxItemAdapter.kt
2022-05-06 17:50:41 +08:00
10237d2fde 日夜间模式的切换(搜索页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65
日夜间模式的切换(搜索页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65
2022-05-06 17:30:50 +08:00
c1b236080e Merge remote-tracking branch 'origin/dev-5.9.0' into dev-5.9.0 2022-05-06 15:18:04 +08:00
83d16a16b8 日夜间模式的切换(搜索页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-05-06 15:08:58 +08:00
52ccffb97a 添加简单的日夜间模式 View 颜色切换辅助方法 2022-05-06 15:08:45 +08:00
lyr
9ed9e22df4 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(0427UI测试问题汇总 2)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-05-06 11:30:55 +08:00
5aa29782cc Merge branch 'hotfix-v5.8.0-510-image_blurry' into 'release'
修改社区信息流横向长图显示模糊问题

See merge request halo/android/assistant-android!241
2022-05-05 18:20:57 +08:00
lyr
82fcde1245 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(0505UI测试问题汇总)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794#note_146206 2022-05-05 16:08:41 +08:00
lyr
eab945acfc 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(0427UI测试问题汇总 遗留2、7)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-05-05 15:25:24 +08:00
8ed57cbfb8 修改社区信息流横向长图显示模糊问题 2022-05-05 14:11:22 +08:00
lyr
d3ed6d750b 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(微调活动主页UI) 2022-05-05 10:59:51 +08:00
lyr
bb4878eab4 【光环助手V5.9.0】新社区7期-论坛主页优化(0427UI测试 遗留问题)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-05-05 10:11:37 +08:00
lyr
53d8444c85 Merge remote-tracking branch 'origin/dev-5.9.0' into dev-5.9.0 2022-04-29 18:30:24 +08:00
lyr
7db009a3cd 【光环助手V5.9.0】新社区7期-论坛详情页优化(0427UI测试)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1789 2022-04-29 18:30:20 +08:00
4932fc2d7b 日夜间模式的切换 https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-04-29 18:24:17 +08:00
ca55ac02b7 日夜间模式的切换(礼包页面) https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-04-29 16:27:14 +08:00
lyr
c535ffb2e0 【光环助手V5.9.0】新社区7期-论坛主页优化 (0427UI测试) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-29 11:27:39 +08:00
9c6eb22d9d 【光环助手V5.9.0】游戏单新增[活动标签]功能(0429测试1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-29 10:35:13 +08:00
lyr
9ec6ec0281 【光环助手V5.9.0】新社区7期-论坛主页优化 (0427测试反馈 3) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-28 17:10:05 +08:00
lyr
327441e62b 【光环助手V5.9.0】新社区7期-论坛主页优化(0427测试反馈 3)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-28 17:04:27 +08:00
lyr
ae3f07a3ee 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化 (活动Tab图片使用svg实现) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-28 16:49:43 +08:00
f967e1f283 日夜间模式的切换 https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-04-28 16:17:29 +08:00
ba1308c568 修复创建游戏单使用草稿时无法选择活动标签的问题 2022-04-28 15:13:13 +08:00
3144e3b007 升级 gid 依赖 2022-04-28 14:50:14 +08:00
ec1c5713ad 【光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(0428UI测试1,2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-28 14:30:34 +08:00
15adc93340 Merge remote-tracking branch 'origin/dev-5.9.0' into dev-5.9.0 2022-04-28 09:53:05 +08:00
c9b27f6ebe 【光环助手V5.9.0】游戏实名认证提示及其他相关优化(0427UI测试2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1785 2022-04-28 09:52:49 +08:00
cff7f7d2e2 修改社区帖子评论作者标签显示错误 2022-04-28 09:52:28 +08:00
cb5d0c4840 修改游戏评论详情点赞图片大小 2022-04-27 18:43:32 +08:00
dea6abe399 修改游戏评论页评论、点赞图标大小 2022-04-27 18:35:07 +08:00
lyr
20c792d4fa 【光环助手V5.9.0】新社区7期-论坛主页优化(0427测试反馈 1、2) 2022-04-27 18:27:03 +08:00
lyr
b8cbd5a0fb Merge remote-tracking branch 'origin/dev-5.9.0' into dev-5.9.0 2022-04-27 18:07:40 +08:00
lyr
0a34f23e62 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化 (0427UI测试问题汇总) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-27 18:07:17 +08:00
7413b4e4ac 【光环助手V5.9.0】游戏实名认证提示及其他相关优化(0427UI测试) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1785 2022-04-27 18:04:52 +08:00
d2025c32c9 【光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(0427UI测试2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-27 17:10:21 +08:00
5c5dd35409 Merge branch 'dev-5.9.0' of git.shanqu.cc:halo/android/assistant-android into dev-5.9.0 2022-04-27 16:45:54 +08:00
b509e9046e 游戏详情日夜间模式切换 https://git.shanqu.cc/halo/android/assistant-android/-/issues/65 2022-04-27 16:45:48 +08:00
lyr
46e99434c9 【光环助手V5.9.0】新社区7期-论坛详情页优化(0427UI测试)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1789 2022-04-27 16:11:36 +08:00
b6ff94aed3 光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(0427UI测试1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-27 14:21:19 +08:00
25e0bd19bc 【光环助手V5.9.0】游戏实名认证提示及其他相关优化 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1785 2022-04-27 11:39:24 +08:00
lyr
fe5b398fad 【光环助手V5.9.0】新社区7期-论坛主页优化(0426UI测试问题汇总)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-27 11:30:39 +08:00
lyr
417ed1401e 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(0426UI测试问题汇总)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-27 10:38:14 +08:00
48698f06cd 【光环助手V5.9.0】游戏实名认证提示及其他相关优化 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1785 2022-04-26 18:37:16 +08:00
b70a7eaf8b 【光环助手V5.9.0】游戏库新增[导航栏]功能(20220426UI测试) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783 2022-04-26 17:01:27 +08:00
lyr
ad86d7bbcc 【光环助手V5.9.0】前端优化汇总4月第5周(2)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1820 2022-04-26 15:56:53 +08:00
lyr
a2eb550099 【光环助手V5.9.0】游戏库新增[导航栏]功能(0426测试)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783 2022-04-26 15:37:59 +08:00
lyr
e736855a4a 【光环助手V5.9.0】游戏库新增[导航栏]功能(数据埋点第4点-40425测试)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783#note_145069 2022-04-26 11:48:53 +08:00
0b49f531ac 【光环助手V5.9.0】游戏单新增[轮播图]功能(0426补充)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1781 2022-04-26 10:08:59 +08:00
lyr
c36f4d9abf 【光环助手V5.9.0】新社区7期-论坛主页优化(优化顶部轮播图)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-25 18:01:08 +08:00
lyr
db72b0a5c9 【光环助手V5.9.0】游戏库新增[导航栏]功能(数据埋点 4)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783 2022-04-25 17:11:30 +08:00
lyr
b19d21fc39 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(二(1))https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-25 15:37:53 +08:00
lyr
2d172d70ad 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(一(2))https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-25 14:24:57 +08:00
cc434771c0 修复游戏单只有单个轮播图仍然自动轮播的问题 2022-04-25 10:03:58 +08:00
f5a9502261 【光环助手V5.9.0】游戏单新增[活动标签]功能(0424UI测试内容1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-24 18:07:31 +08:00
c48d970b0a 【光环助手V5.9.0】游戏单新增[轮播图]功能(0422测试2、0424UI测试内容1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1781 2022-04-24 17:49:08 +08:00
9a53c7a84e 【光环助手V5.9.0】游戏单新增[活动标签]功能(0424UI测试内容1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-24 17:46:38 +08:00
ce17ae2d2b 【光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(0424UI测试) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-24 17:22:38 +08:00
lyr
d97f65e9b3 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(一(1))https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-24 16:31:34 +08:00
9f1f3a2d66 【光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-24 14:24:08 +08:00
4c9609ba52 【光环助手V5.9.0】游戏单新增[活动标签]功能(0422测试1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-24 11:58:11 +08:00
270203266f 修复工具箱页面空指针闪退 2022-04-24 11:46:54 +08:00
lyr
edc326ff3c 【光环助手V5.9.0】新社区7期-论坛主页优化 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792 2022-04-24 10:34:45 +08:00
0856b8a2ab 添加 ANR 上报到 BETA 渠道 2022-04-24 10:16:37 +08:00
8f95517dd7 尝试处理更新管理页面的并发操作问题 2022-04-24 10:13:56 +08:00
c828f3f479 尝试处理游戏搜索页和下载管理页的ANR问题 2022-04-24 10:13:08 +08:00
b90d026a74 尝试修复工作任务过多无法被执行的问题 2022-04-23 16:21:41 +08:00
lyr
819beb779c 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(一(2)) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794 2022-04-22 09:53:59 +08:00
de31dcaf0b 【光环助手V5.9.0】游戏单新增[轮播图]功能 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1781 2022-04-21 16:29:23 +08:00
587c217b7c 修改游戏库导航栏小红点显示逻辑问题 2022-04-21 10:08:09 +08:00
b03e86f903 上传遗漏文件 2022-04-20 23:18:15 +08:00
ea80942937 【光环助手V5.9.0】新社区7期-推荐信息页&个人主页&活动主页优化(一(2)(大部分)、三) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1794
【光环助手V5.9.0】新社区7期-论坛主页优化(UI部分(因后端未出接口)) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1792
2022-04-20 23:13:40 +08:00
06153cbf58 【光环助手V5.9.0】游戏库新增[导航栏]功能(曝光数据埋点) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783 2022-04-20 17:08:11 +08:00
0b94f777a2 【光环助手V5.9.0】游戏库新增[导航栏]功能 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1783 2022-04-20 11:00:36 +08:00
3d6917cd5d Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/mygame/PlayedGameAdapter.kt
#	dependencies.gradle
2022-04-19 09:24:00 +08:00
e4300ab315 更新 sentry cli token 2022-04-19 09:22:18 +08:00
ed80533198 【光环助手V5.9.0】游戏单新增[活动标签]功能(修复数据库迁移闪退) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-18 15:24:34 +08:00
4b5c741ff9 【光环助手V5.9.0】游戏单新增[活动标签]功能(修复编辑游戏单丢失活动标签的问题) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-18 12:02:23 +08:00
0e9f267117 版本更新至 5.9.0 2022-04-18 09:35:26 +08:00
02bb977cc0 【光环助手V5.9.0】游戏单新增[活动标签]功能(修改活动标签说明字段) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-15 15:48:07 +08:00
c4a89b9302 【光环助手V5.9.0】游戏单新增[活动标签]功能 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-15 14:44:33 +08:00
cde9401b36 修复游戏动态查看大图数组越界的问题 2022-04-14 20:25:11 +08:00
edcb4a949e 【光环助手V5.9.0】新社区7期-新增视频模板活动优化(后台)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1796 2022-04-14 14:57:38 +08:00
a5c113e527 Merge remote-tracking branch 'origin/dev-5.9.0' into dev-5.9.0 2022-04-13 16:50:22 +08:00
048bdbc367 【光环助手V5.9.0】游戏单新增[活动标签]功能(UI部分) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1780 2022-04-13 16:49:14 +08:00
1e287f56e2 【光环助手V5.9.0】新社区7期-论坛详情页优化 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1789 2022-04-13 14:57:57 +08:00
2aacab80a6 【光环助手V5.9.0】新社区7期-内容(帖子、视频帖、提问帖)详情页优化(2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1795 2022-04-13 10:15:20 +08:00
25a325f7f7 Merge branch 'hotfix-v5.7.1-492-crashes' into 'dev'
修复sentry上的闪退问题

See merge request halo/android/assistant-android!233
2022-04-11 14:20:44 +08:00
6c6a7f0677 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2022-04-07 09:59:52 +08:00
a052f981c5 Merge branch 'feature-night_mode_test' into dev-5.9.0 2022-04-06 18:14:55 +08:00
5042bddec7 1.修改LoopThread名字 2.修改定时器回调到子线程 2022-04-06 17:45:52 +08:00
0803e61828 复用 Gson 对象 2022-04-06 16:21:18 +08:00
119f304e2f 尝试处理 ConnectivityManager 造成的内存泄漏问题 2022-04-06 11:35:36 +08:00
3db6f93b73 Merge branch 'release' into dev 2022-04-06 11:22:51 +08:00
3719f5e1cd Merge remote-tracking branch 'origin/release' into dev 2022-04-06 10:25:26 +08:00
cbae38b41d 修改加载图片重复调用AsyncImageLoader问题 2022-04-06 09:48:12 +08:00
021886c3cb 实现游戏单广场、安利墙、我的光环夜间模式切换颜色 2022-04-02 18:01:42 +08:00
6d62dd7fd1 删除多余代码 2022-04-02 17:35:07 +08:00
20d28525cf 处理加载图片时由于width获取为0导致图片占用内存过大的问题 2022-04-02 17:30:47 +08:00
a406127cda 统一纯白、纯黑色值 2022-04-02 15:31:13 +08:00
lyr
3301b30ec2 优化WebFragment是否成功加载的判断逻辑(补充) 2022-04-01 15:43:50 +08:00
f761715ebd 实现夜间模式切换首页tab和搜索栏颜色
实现游戏库夜间模式切换颜色
2022-04-01 15:28:30 +08:00
lyr
1f0216662a 优化WebFragment是否成功加载的判断逻辑 2022-04-01 15:03:32 +08:00
f483f1effc 清理无用 dokit 配置 2022-04-01 11:31:24 +08:00
cf5b0bcd41 添加 dokit 初始化脚本 2022-04-01 10:55:45 +08:00
4e51830c58 Update README.md 2022-04-01 09:23:51 +08:00
lyr
830a45e6d2 WebFragment网页销毁时移除JS Api 2022-03-31 21:58:27 +08:00
lyr
24c32b7a4b 【光环助手V5.8.0】游戏活动模板功能(前端部分)(优化游戏活动下载辅助类) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-31 21:56:22 +08:00
lyr
7e30f1702d Merge remote-tracking branch 'origin/dev' into dev 2022-03-31 20:57:21 +08:00
lyr
68ae4bf1b2 【光环助手V5.8.0】游戏活动模板功能(前端部分)(提供上报曝光方法) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-31 20:57:15 +08:00
0b757f24d1 缩小 Picasso 的内存 Lru size 2022-03-31 20:54:14 +08:00
lyr
99d0525c0a 【光环助手V5.8.0】游戏活动模板功能(前端部分)(0330测试 4)(增加防止web页面水平方向滑动冲突的JS Api) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-31 18:14:24 +08:00
4f3ec7aa18 处理 AppManager 的内存泄漏问题 2022-03-31 17:47:32 +08:00
bd228459fa 修复游戏详情页游戏图标的重复加载问题 2022-03-31 17:16:40 +08:00
c9227c20a2 修复列表游戏图标可能会加载不符合显示大小图片的问题 2022-03-31 17:15:31 +08:00
lyr
5270bc3ed7 【光环助手V5.8.0】游戏活动模板功能(前端部分)(0330测试 6(3)(4)) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-31 14:48:53 +08:00
e1de3dc873 缩减线程池核心规模 2022-03-31 11:37:43 +08:00
9303f534d9 修改夜间模式配色 2022-03-31 11:06:07 +08:00
629a694279 【光环助手V5.8.0】客户端内部需求 (0328测试 1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1746 2022-03-31 10:15:48 +08:00
0ef0ed7c50 Merge branch 'dev' into feature-night_mode_test 2022-03-30 11:36:34 +08:00
lyr
48d335ad67 【光环助手V5.8.0】游戏活动模板功能(前端部分)(0328测试 9) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-29 14:23:48 +08:00
231434caeb 新增设计师用包编译脚本 2022-03-29 10:22:10 +08:00
220fd340ce Merge branch 'dev' into feature-night_mode_test 2022-03-29 10:17:30 +08:00
5badb44e3e 处理编译问题 2022-03-29 09:43:11 +08:00
82d405c14c 【光环助手V5.8.0】前端优化汇总3月第2周(0328测试结果反馈4) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-28 20:32:57 +08:00
2157dcd51a Merge remote-tracking branch 'origin/dev' into dev 2022-03-28 18:38:00 +08:00
872d9d89c5 jenkins 包默认关闭 dokit 2022-03-28 18:37:52 +08:00
lyr
dae4543a82 【光环助手V5.8.0】游戏活动模板功能(前端部分)(0328测试 8) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-28 18:37:10 +08:00
60204d9ab2 测试包集成 dokit 2022-03-28 18:30:57 +08:00
0c86965260 测试包集成 dokit 2022-03-28 18:25:37 +08:00
d0ad110d9e Merge branch 'dev' into feature-night_mode_test
# Conflicts:
#	app/src/main/res/layout/questions_history_detail.xml
2022-03-28 17:40:17 +08:00
5cd88cdb7f 【光环助手V5.8.0】客户端内部需求(0328UI测试问题1)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1746 2022-03-28 17:25:08 +08:00
60acd1bac4 【光环助手V5.8.0】前端优化汇总3月第2周(0328第4点UI测试问题1,2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-28 17:10:01 +08:00
lyr
990efacb89 【光环助手V5.8.0】前端优化汇总3月第2周(UI测试问题 2)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755#note_140469 2022-03-28 14:27:49 +08:00
7076a6acaa 【光环助手V5.8.0】前端优化汇总3月第3周(4) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1763 2022-03-28 10:44:14 +08:00
acc4d6d8ab 【光环助手V5.8.0】前端优化汇总3月第2周(第6点UI测试问题1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-28 10:22:29 +08:00
lyr
0a3ae4379d 【光环助手V5.8.0】游戏活动模板功能(前端部分)(优化下载) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-24 18:21:27 +08:00
lyr
8197f161c0 【光环助手V5.8.0】游戏活动模板功能(前端部分)(修复多版本游戏无法下载问题) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-24 17:10:47 +08:00
lyr
0cd5f0d640 【光环助手V5.8.0】游戏活动模板功能(前端部分)(修改判断是否完成任务的JS调用方法) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-24 11:21:41 +08:00
lyr
790093b585 处理 SonarQube 问题 2022-03-23 18:07:00 +08:00
72a5d2881a 处理 SonarQube 问题 2022-03-23 17:31:59 +08:00
7eabb1098c 处理 SonarQube 问题 2022-03-23 17:08:36 +08:00
7a295a5d05 处理 SonarQube 问题 2022-03-23 16:36:25 +08:00
da26247d30 Merge branch 'dev-5.8.0' into dev 2022-03-23 16:02:50 +08:00
lyr
010ce39e20 【光环助手V5.8.0】游戏活动模板功能(前端部分)(修改接口) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-22 14:36:38 +08:00
lyr
9320059a76 【光环助手V5.8.0】游戏活动模板功能(前端部分)(优化判断是否完成任务的JS调用方法) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-21 19:11:43 +08:00
lyr
3003a310a0 【光环助手V5.8.0】游戏活动模板功能(前端部分)(优化游戏活动页下载按钮的JS调用方法、提供判断是否完成任务的JS调用方法) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-21 18:48:15 +08:00
91af5e6fe6 【光环助手V5.8.0】后台优化汇总3月第2周 (4) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1754 2022-03-21 11:36:51 +08:00
lyr
d02dfbdaf7 【光环助手V5.8.0】游戏活动模板功能(前端部分)(提供游戏活动页下载按钮的JS调用方法) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1741 2022-03-18 18:31:46 +08:00
c3e06cc1ff 【光环助手V5.8.0】前端优化汇总3月第3周(3)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1763 2022-03-18 17:07:47 +08:00
3e86e368d8 游戏单广场选择标签后修改为不显示骨架图 2022-03-18 16:40:22 +08:00
df231d1530 【光环助手V5.8.0】游戏单功能优化 1(1) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1739 2022-03-18 16:34:51 +08:00
006f71def7 Merge remote-tracking branch 'origin/feature-night_mode_test' into feature-night_mode_test 2022-03-17 17:16:24 +08:00
047dc9a7ae 调研日/夜间模式切换的实现 https://git.shanqu.cc/halo/android/assistant-android/-/issues/60 2022-03-17 17:13:16 +08:00
lyr
05abf00994 【光环助手V5.8.0】实名认证优化第五期(客户端 1、4)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1750 2022-03-17 11:59:39 +08:00
c8278f6364 修改帖子详情评论框弹起不能自动获取焦点问题 2022-03-17 11:37:11 +08:00
8cd951c669 Merge branch 'dev' into dev-5.8.0 2022-03-17 11:33:49 +08:00
c43700e4d6 【光环助手V5.8.0】前端优化汇总3月第3周(2) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1763 2022-03-17 11:11:11 +08:00
fa2174319e 优化版块页刷新按钮的显示逻辑 2022-03-17 10:48:22 +08:00
lyr
4d6a71c8be 升级Loghub配置方法 2022-03-17 10:35:35 +08:00
b99e579ccd 调整社区推荐页列表标题和正文的文本内边距 2022-03-15 16:37:30 +08:00
01eb074df1 优化底部导航栏显示
添加注释
2022-03-14 17:27:36 +08:00
f6473b0e5e Merge branch 'dev-5.8.0' into feature-night_mode_test 2022-03-14 17:11:51 +08:00
e244797e7d 调研日/夜间模式切换的实现 https://git.shanqu.cc/halo/android/assistant-android/-/issues/60 2022-03-14 17:00:28 +08:00
f267908122 Merge branch 'dev' into dev-5.8.0 2022-03-14 16:22:32 +08:00
32a4fda9bc 完全移除 DataBinding(修复首页排行榜显示问题)https://git.shanqu.cc/halo/android/assistant-android/-/issues/59 2022-03-14 15:42:53 +08:00
cdfda4d963 修改我的游戏分割线显示问题 2022-03-11 16:42:54 +08:00
c3b850972f 【光环助手V5.8.0】前端优化汇总3月第2周(0311测试结果反馈4,10) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-11 16:28:26 +08:00
89f8aebefe Merge branch 'dev-5.8.0' into feature-night_mode_test
# Conflicts:
#	app/src/main/res/layout/activity_ask_column_detail.xml
#	app/src/main/res/layout/activity_background_clip.xml
#	app/src/main/res/layout/activity_kaifu_patch.xml
#	app/src/main/res/layout/activity_rating_edit.xml
#	app/src/main/res/layout/activity_video_game.xml
#	app/src/main/res/layout/activity_video_uplaod.xml
#	app/src/main/res/layout/ask_search_question_item.xml
#	app/src/main/res/layout/catalog_header_item.xml
#	app/src/main/res/layout/catalog_image_item.xml
#	app/src/main/res/layout/commodity_item.xml
#	app/src/main/res/layout/common_collection_detail_one_item.xml
#	app/src/main/res/layout/common_collection_detail_two_item.xml
#	app/src/main/res/layout/common_collection_image_text_item.xml
#	app/src/main/res/layout/common_collection_item.xml
#	app/src/main/res/layout/community_follow_item.xml
#	app/src/main/res/layout/community_select_opened_item.xml
#	app/src/main/res/layout/daily_task_item.xml
#	app/src/main/res/layout/dialog_download_link.xml
#	app/src/main/res/layout/dialog_upload_schedule.xml
#	app/src/main/res/layout/download_dialog_installed_item.xml
#	app/src/main/res/layout/download_dialog_item.xml
#	app/src/main/res/layout/followers_or_fans_item.xml
#	app/src/main/res/layout/forum_search_content_list.xml
#	app/src/main/res/layout/fragment_answer_detail.xml
#	app/src/main/res/layout/fragment_answer_edit.xml
#	app/src/main/res/layout/fragment_background_preview.xml
#	app/src/main/res/layout/fragment_forum_detail.xml
#	app/src/main/res/layout/fragment_forum_video_detail.xml
#	app/src/main/res/layout/fragment_game_collection_poster.xml
#	app/src/main/res/layout/fragment_main_home.xml
#	app/src/main/res/layout/fragment_search_default.xml
#	app/src/main/res/layout/game_collection_detail_image_item.xml
#	app/src/main/res/layout/game_collection_item.xml
#	app/src/main/res/layout/game_head_item.xml
#	app/src/main/res/layout/game_image_item.xml
#	app/src/main/res/layout/game_image_slide_item.xml
#	app/src/main/res/layout/game_viewpager_item.xml
#	app/src/main/res/layout/home_amway_item.xml
#	app/src/main/res/layout/home_game_item.xml
#	app/src/main/res/layout/home_recommend_item.xml
#	app/src/main/res/layout/home_slide_list_item.xml
#	app/src/main/res/layout/item_article_detail_comment.xml
#	app/src/main/res/layout/item_forum_video.xml
#	app/src/main/res/layout/item_game_libao.xml
#	app/src/main/res/layout/item_my_game_collection.xml
#	app/src/main/res/layout/local_video_item.xml
#	app/src/main/res/layout/novice_task_item.xml
#	app/src/main/res/layout/rating_comment_item.xml
#	app/src/main/res/layout/rating_reply_item.xml
#	app/src/main/res/layout/set_wait_dialog.xml
#	app/src/main/res/layout/stairs_comment_item.xml
2022-03-11 11:41:46 +08:00
52eca3b1ab 调研日/夜间模式切换的实现 https://git.shanqu.cc/halo/android/assistant-android/-/issues/60 2022-03-11 11:18:26 +08:00
0e26943d25 【光环助手V5.8.0】前端优化汇总3月第2周(10) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-10 17:32:08 +08:00
lyr
0a8bef8ac3 【光环助手V5.8.0】前端优化汇总3月第2周(3、6(游戏单详情骨架图))https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-10 17:13:53 +08:00
a8fa4cf872 修改设置页面异步获取缓存大小 2022-03-10 12:08:49 +08:00
775f454e38 【光环助手V5.8.0】前端优化汇总3月第2周 6(游戏单、游戏单广场) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755
【光环助手V5.8.0】游戏单功能优化(UI部分)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1739
2022-03-10 11:19:36 +08:00
b7de326a21 【光环助手V5.8.0】前端优化汇总3月第2周(4) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-10 09:53:06 +08:00
5b0d2e8294 缩减线程池等待队列大小 2022-03-09 15:16:29 +08:00
ec34de4675 Merge branch 'feature-optimise_filter_api' into 'dev-5.8.0'
调整启动时获取已收录游戏及游戏更新/插件化的逻辑 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1746

See merge request halo/android/assistant-android!224
2022-03-09 15:11:25 +08:00
0f6aa5ca9f 调整启动时获取已收录游戏及游戏更新/插件化的逻辑 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1746 2022-03-09 15:09:36 +08:00
lyr
b0cdd1029e 【光环助手V5.8.0】客户端内部需求 3(修改首页部分点击游戏item使用游戏id进入游戏详情)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1746 2022-03-08 16:41:52 +08:00
e554e9ca5f 修改游戏单详情游戏推荐理由不显示问题 2022-03-08 13:25:32 +08:00
ff879454c1 【光环助手V5.8.0】新社区3期-社区数据后台-内容数据(补充share_result埋点携带信息) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1420 2022-03-08 13:03:06 +08:00
7d3baaa501 【光环助手V5.8.0】前端优化汇总3月第2周(5,7) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-08 11:28:53 +08:00
5a57a58f0a Merge branch 'feature_remove_duplicated_files' into dev-5.8.0 2022-03-08 09:57:07 +08:00
e01bfb4676 移除完全相同的冗余资源文件 https://git.shanqu.cc/halo/android/assistant-android/-/issues/62 2022-03-08 09:53:48 +08:00
de8234868a 【光环助手V5.8.0】前端优化汇总3月第2周(8) https://git.shanqu.cc/pm/halo-app-issues/-/issues/1755 2022-03-07 18:31:34 +08:00
9220f13c9e 移除完全相同的冗余资源文件 https://git.shanqu.cc/halo/android/assistant-android/-/issues/62 2022-03-07 17:42:03 +08:00
10a3ed7f15 Merge branch 'feature-remove_databinding' into dev-5.8.0
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/gamedetail/fuli/GameNewsAdapter.kt
2022-03-07 11:13:08 +08:00
554eb671b2 新增开服页面还原为DataBinding 2022-03-04 14:57:48 +08:00
9f2e46d876 完全移除 DataBinding https://git.shanqu.cc/halo/android/assistant-android/-/issues/59 2022-03-04 11:09:13 +08:00
d2efb8391c 完全移除 DataBinding https://git.shanqu.cc/halo/android/assistant-android/-/issues/59 2022-03-04 10:39:23 +08:00
ac04cc4525 修改版本说明弹窗闪退问题 2022-03-03 18:52:32 +08:00
03855609c1 完全移除 DataBinding https://git.shanqu.cc/halo/android/assistant-android/-/issues/59 2022-03-03 18:03:08 +08:00
2408af31d9 Update .gitmodules 2022-03-03 10:13:12 +08:00
3012bf6a46 版本更新至 5.8.0 2022-03-02 17:31:07 +08:00
e07529846c 完全移除 DataBinding https://git.shanqu.cc/halo/android/assistant-android/-/issues/59 2022-03-02 17:12:38 +08:00
lyr
010c41c3c9 修复从帖子详情页点赞评论后返回论坛详情页会闪退的问题 2022-03-02 11:06:36 +08:00
lyr
d7a81d2268 完全移除 Kotlin synthetics for views https://git.shanqu.cc/halo/android/assistant-android/-/issues/58 2022-03-02 10:32:19 +08:00
1491 changed files with 30420 additions and 74573 deletions

4
.gitmodules vendored
View File

@ -1,7 +1,7 @@
[submodule "libraries/LGLibrary"]
path = libraries/LGLibrary
url = git@git.ghzs.com:android/common-library.git
url = git@git.shanqu.cc:android/common-library.git
branch = master
[submodule "assistant_flutter"]
path = assistant_flutter
url = git@git.ghzs.com:halo/android/flutter-module.git
url = git@git.shanqu.cc:halo/android/flutter-module.git

View File

@ -14,9 +14,9 @@
4. 遵循最小改动原则,在提交代码前务必先检查变动的代码,尽量以可控的变动规模来构成一个 commit ,以便日后追踪问题
5. 代码规范可参考 [AOSP Java 风格](https://source.android.com/setup/contribute/code-style)
6. 尽量使用 Kotlin 来写新文件
7. 尽量不要使用 DataBinding,因为回影响编译性能
7. 尽量不要使用 DataBinding
8. Commit 前请确保不带入非项目必须文件,可手动修改 [.gitignore](https://stackoverflow.com/questions/8527597/how-do-i-ignore-files-in-a-directory-in-git) 文件忽略
9. 新页面请勿使用 ButterKnife 来进行 View 获取和绑定,请使用 ViewBinding
9. 优先使用 ViewBinding 获取 View 对象
10. No AsyncTask!
### 公用部分
@ -25,7 +25,7 @@
### 首次拉取项目代码
`git clone -b dev git@git.ghzs.com:halo/android/assistant-android.git --recursive`
`git clone -b dev git@git.shanqu.cc:halo/android/assistant-android.git --recursive`
### git 版本管理
@ -45,8 +45,8 @@
### 第三方appkey等配置
* 修改`gradle.properties`文件将各种key填入其中实现统一管理
* 通过gradle文件内的resValue/buildConfigField/manifestPlaceHolder方式实现编译期间修改具体情况请参考``./build.gradle````./app/build.gradle``配置
* 修改 `gradle.properties` 文件将各种key填入其中实现统一管理
* 通过 gradle 文件内的 resValue/buildConfigField/manifestPlaceHolder 方式实现编译期间修改,具体情况请参考 ``./build.gradle````./app/build.gradle`` 配置
### 混淆配置
@ -55,11 +55,8 @@
### APK打包配置
* 本项目使用了 [VasDolly](https://github.com/Tencent/VasDolly) 作为渠道包实现方案
* 打包命令,具体参数请见相应文件:
> 打内部测试包:`./scripts/test_build.sh`
> 正式发布包:`./scripts/build_with_simple_backup.sh`
> 邮件测试包:`./scripts/jenkins_build.sh`
### TODO

View File

@ -1,7 +1,7 @@
// This comment exists for a reason, do not delete
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' // kotlin
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'AndResGuard'
@ -9,13 +9,9 @@ import groovy.xml.XmlUtil
android {
androidExtensions {
experimental = true
}
buildFeatures {
viewBinding = true
dataBinding = true
viewBinding true
dataBinding true
}
compileOptions {
@ -48,6 +44,7 @@ android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
javaCompileOptions {
annotationProcessorOptions {
@ -92,8 +89,10 @@ android {
/**
* Build Time 供区分 jenkins 打包时间用
* IS_NIGHT_MODE_ON 供区分夜间模式功能是否启用
*/
buildConfigField "long", "BUILD_TIME", "0"
buildConfigField "boolean", "IS_NIGHT_MODE_ON", "true"
}
// gradle 2.2以上默认同时启用v1和v2优先用于Android N
@ -138,7 +137,7 @@ android {
variantFilter { variant ->
def names = variant.flavors*.name
def isDebugType = variant.buildType.name == "debug"
if ((names.contains("tea") || name.contains("gdt")) && isDebugType) {
if ((names.contains("tea")) && isDebugType) {
setIgnore(true)
}
}
@ -155,9 +154,6 @@ android {
tea {
java.srcDirs = ['src/main/java', 'src/tea/java']
}
gdt {
java.srcDirs = ['src/main/java', 'src/gdt/java']
}
}
productFlavors {
@ -186,13 +182,6 @@ android {
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
}
gdt {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
}
}
lintOptions {
@ -210,7 +199,6 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
testImplementation 'junit:junit:4.12'
@ -218,6 +206,7 @@ dependencies {
debugImplementation "com.squareup.okhttp3:logging-interceptor:${okHttp}"
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
implementation "androidx.core:core-ktx:${core}"
implementation "androidx.fragment:fragment-ktx:${fragment}"
@ -346,7 +335,7 @@ dependencies {
implementation "com.louiscad.splitties:splitties-fun-pack-android-base-with-views-dsl:${splitties}"
compileOnly "com.github.axen1314.lancet:lancet-base:$lancet_version"
compileOnly "com.github.axen1314.lancet:lancet-base:${lancet_version}"
implementation project(':libraries:LGLibrary')
implementation project(':libraries:QQShare')
@ -606,4 +595,4 @@ project.afterEvaluate {
}
}
}
}
}

View File

@ -220,10 +220,6 @@
-keepattributes Signature
-keepattributes Annotation
### 广点通
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}
### AndroidX
-keep class androidx.core.app.CoreComponentFactory { *; }
@ -267,5 +263,4 @@
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}
-keep class com.gh.gamecenter.GdtHelper { *; }
-keep class com.gh.gamecenter.TeaHelper { *; }

View File

@ -94,10 +94,6 @@
@androidx.annotation.Keep *;
}
### 广点通
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.* {*;}
### 阿里云上传
-keep class com.alibaba.sdk.android.oss.* { *; }
-dontwarn okio.**
@ -124,8 +120,7 @@
-keep class com.ut.*{*;}
-keep class com.ta.*{*;}
### GDT & TEA
-keep class com.gh.gamecenter.GdtHelper { *; }
### TEA
-keep class com.gh.gamecenter.TeaHelper { *; }
### 阿里云日志
@ -147,6 +142,9 @@
### emoji4j
-keep class emoji4j.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
# Flutter模块
-keep class com.gh.common.util.DirectUtils {
public static void directToQa(...);

View File

@ -1,77 +0,0 @@
package com.gh.gamecenter
import android.app.Application
import android.text.TextUtils
import android.util.Log
import com.gh.common.util.ToastUtils
import com.lightgame.utils.Utils
import com.qq.gdt.action.GDTAction
import org.json.JSONObject
/**
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
*
* 更换帐号 [https://gitlab.ghzs.com/pm/yunying/issues/893]
*/
object GdtHelper {
const val NETWORK_TYPE = "NETWORK_TYPE"
const val PAGE_TYPE = "PAGE_TYPE"
const val CONTENT_TYPE = "CONTENT_TYPE"
const val CONTENT_ID = "CONTENT_ID"
const val KEYWORD = "KEYWORD"
const val GAME_ID = "GAME_ID"
const val SCORE = "SCORE"
const val PLATFORM = "PLATFORM"
@JvmStatic
fun init(application: Application, channel: String) {
if (shouldUseGdtHelper()) {
if (channel == "GH_728") {
GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
} else if (channel == "GH_729") {
GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
} else if (channel == "GH_765") {
GDTAction.init(application, "1111327925", "588d503f0990f98f9b2394fbb795c570")
} else {
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
}
}
Utils.log("init GdtHelper")
}
// fun logAction(type: String) {
// if (shouldUseGdtHelper()) {
// GDTAction.logAction(type)
// Utils.log("GDT", type)
// }
// }
@JvmStatic
fun logAction(type: String, vararg kv: String?) {
try {
val actionParam = JSONObject()
for (i in kv.indices) {
if (i % 2 != 0) {
val key = kv[i - 1]
val value = kv[i]
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
actionParam.put(key, value)
}
}
}
Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
GDTAction.logAction(type, actionParam)
} catch (e: Exception) {
e.printStackTrace()
}
}
// TODO 确认开启的渠道条件
private fun shouldUseGdtHelper(): Boolean {
return true
//
// val channel = HaloApp.getInstance().channel
// return !(TextUtils.isEmpty(channel) || channel.contains("GDT".toLowerCase(Locale.CHINA)))
}
}

View File

@ -165,7 +165,8 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.WebActivity" />
android:name="com.gh.gamecenter.WebActivity"
android:screenOrientation="portrait"/>
<activity
android:name="com.gh.gamecenter.SingletonWebActivity"
@ -388,14 +389,6 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="stateVisible" />
<activity
android:name="com.gh.gamecenter.qa.questions.edit.manager.HistoryDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.questions.edit.manager.HistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity"
android:screenOrientation="portrait" />
@ -739,6 +732,10 @@
android:name="com.gh.gamecenter.toolbox.ToolBoxBlockActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.subject.CommunitySubjectActivity"
android:screenOrientation="portrait" />
<activity
android:name="${applicationId}.wxapi.WXEntryActivity"
android:exported="true"
@ -762,6 +759,12 @@
android:resource="@xml/provider_paths" />
</provider>
<provider
android:name="com.gh.gamecenter.provider.GhContentProvider"
android:authorities="${applicationId}.provider"
android:enabled="true"
android:exported="true"/>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -280,12 +280,8 @@ RE.replaceAllDfImage = function(imgRuleFlag, gifRuleFlag) {
i--;
} else {
if(img.src.indexOf(".gif") > 0) {
if(gifRuleFlag.indexOf(",default") > 0) {
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
img.src = img.src.split("?")[0] + gifRuleFlag
}
img.src = img.src.split("?")[0] + gifRuleFlag
} else {
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
img.src = img.src.split("?")[0] + imgRuleFlag
}
}
@ -301,7 +297,7 @@ RE.hideShowBigPic = function() {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf(",thumbnail") > 0 && img.src.indexOf(".gif") == -1) {
if (img.src.indexOf(".gif") == -1) {
j++;
}
}
@ -327,7 +323,6 @@ RE.replaceDfImageByUrl = function(imgUrl, imgRuleFlag, gifRuleFlag) {
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if (img.src.indexOf(imgUrl) != -1) {
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
if(img.src.indexOf(".gif") > 0) {
img.src = img.src.split("?")[0] + gifRuleFlag
} else {

View File

@ -1,6 +1,9 @@
package com.gh.base;
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
@ -14,6 +17,7 @@ import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
@ -21,7 +25,9 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import androidx.core.view.LayoutInflaterCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
@ -33,10 +39,11 @@ import com.gh.common.util.DialogUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.EnvHelper;
import com.gh.common.util.PackageFlavorHelper;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NetworkUtils;
import com.gh.common.util.NightModeUtils;
import com.gh.common.util.PackageFlavorHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.QuickLoginHelper;
import com.gh.common.util.RunningUtils;
@ -66,10 +73,8 @@ import java.util.List;
import kotlin.Pair;
import pub.devrel.easypermissions.EasyPermissions;
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
/**
* 只提供基础的服务(EventBus/ButterKnife/Share/GlobalDialog/Permissions)
* 只提供基础的服务(EventBus/Share/GlobalDialog/Permissions)
* <p>
* 需要工具栏的页面请继承{@link ToolBarActivity}
*/
@ -82,12 +87,14 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
public final static String PLUGGABLE = "plugin";
public final static String SIGNATURE_CONFLICT = "signature_conflict";
public final static int ID_ROOT_INDICATOR = 999;
public final static int ID_NIGHT_INDICATOR = 998;
public final int MAX_BUNDLE_SIZE = 300;
@NonNull
protected String mEntrance;
private boolean mIsExistLogoutDialog;
protected boolean mNightMode;
public long startPageTime = 0;
protected final Handler mBaseHandler = new BaseHandler(this);
@ -127,6 +134,10 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
@Override
protected void onCreate(Bundle savedInstanceState) {
if (PackageFlavorHelper.IS_TEST_FLAVOR && isAutoResetViewBackgroundEnabled()) {
LayoutInflaterCompat.setFactory2(getLayoutInflater(), new CustomLayoutInflaterFactory(this));
}
super.onCreate(savedInstanceState);
if (useEventBus()) EventBus.getDefault().register(this);
@ -159,12 +170,20 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
}
}
}
mNightMode = NightModeUtils.INSTANCE.isNightMode(this);
}
@Override
protected void onResume() {
super.onResume();
startPageTime = System.currentTimeMillis();
if (BuildConfig.IS_NIGHT_MODE_ON
&& !NightModeUtils.INSTANCE.getSystemMode()
&& mNightMode != NightModeUtils.INSTANCE.isNightMode(this)) {
onNightModeChange();
}
}
@SuppressWarnings("ConstantConditions")
@ -255,6 +274,9 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
screenRootView.addView(view);
screenRootView.addView(ll);
if (BuildConfig.IS_NIGHT_MODE_ON) {
screenRootView.addView(getNightModeIndicatorView());
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) ll.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
@ -262,6 +284,80 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
return screenRootView;
}
private View getNightModeIndicatorView() {
LinearLayout ll = new LinearLayout(this);
TextView tv = new TextView(this);
String envText = NightModeUtils.INSTANCE.isNightMode(this) ? "夜间模式" : "日间模式";
tv.setBackground(ContextCompat.getDrawable(this, R.color.theme));
tv.setText(envText);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.WHITE);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
tv.measure(0, 0);
tv.setAlpha(NightModeUtils.INSTANCE.isNightMode(this) ? 0.8F : 0.15F);
tv.setId(ID_NIGHT_INDICATOR);
int height = tv.getMeasuredHeight();
int width = tv.getMeasuredWidth();
tv.setPadding(DisplayUtils.dip2px(20), 0, DisplayUtils.dip2px(20), 0);
ll.setTranslationX(DisplayUtils.dip2px(-20));
ll.setRotation(-45);
ll.addView(tv);
ll.setPadding(0, (width - height) / 2, 0, (width - height) / 2);
if (PackageFlavorHelper.IS_TEST_FLAVOR) {
tv.setOnClickListener(v -> {
//切换深色模式
String mode;
String positive;
String negative;
if (NightModeUtils.INSTANCE.getSystemMode()) {
mode = "跟随系统模式";
positive = "普通模式";
negative = "深色模式";
} else if (NightModeUtils.INSTANCE.getNightMode()) {
mode = "深色模式";
positive = "跟随系统模式";
negative = "普通模式";
} else {
mode = "普通模式";
positive = "跟随系统模式";
negative = "深色模式";
}
DialogHelper.showCenterDialog(this, "选择模式", "当前为 " + mode, positive, negative, () -> {
if (NightModeUtils.INSTANCE.getSystemMode()) {
NightModeUtils.INSTANCE.setNightMode(false);
NightModeUtils.INSTANCE.setSystemMode(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
} else {
NightModeUtils.INSTANCE.setSystemMode(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
}
}
NightModeUtils.INSTANCE.initNightMode();
}, () -> {
if (NightModeUtils.INSTANCE.getSystemMode()) {
NightModeUtils.INSTANCE.setNightMode(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
} else {
boolean nightMode = NightModeUtils.INSTANCE.getNightMode();
NightModeUtils.INSTANCE.setNightMode(!NightModeUtils.INSTANCE.getNightMode());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getDelegate().setLocalNightMode(nightMode ? AppCompatDelegate.MODE_NIGHT_NO : AppCompatDelegate.MODE_NIGHT_YES);
}
}
NightModeUtils.INSTANCE.setSystemMode(false);
NightModeUtils.INSTANCE.initNightMode();
});
});
}
return ll;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(final EBShowDialog showDialog) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
@ -292,7 +388,8 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
DialogHelper.showCenterDialog(this, "你的账号已在另外一台设备登录"
, StringUtils.buildString("", model, "")
, "知道了", "重新登录"
, () -> {}
, () -> {
}
, () -> {
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(BaseActivity.this)) {
QuickLoginHelper.startLogin(BaseActivity.this, "你的账号已在另外一台设备登录多设备-重新登录");
@ -445,4 +542,88 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
public Pair<String, String> getBusinessId() {
return null;
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onNightModeChange();
}
protected void onNightModeChange() {
if (BuildConfig.IS_NIGHT_MODE_ON) {
mNightMode = NightModeUtils.INSTANCE.isNightMode(this);
TextView tv = findViewById(ID_NIGHT_INDICATOR);
if (tv != null) {
tv.setText(NightModeUtils.INSTANCE.isNightMode(this) ? "夜间模式" : "日间模式");
tv.setAlpha(NightModeUtils.INSTANCE.isNightMode(this) ? 0.8F : 0.15F);
}
if (isAutoResetViewBackgroundEnabled()) {
updateStaticViewBackground(getWindow().getDecorView());
}
}
}
protected boolean isAutoResetViewBackgroundEnabled() {
return false;
}
/**
* 自动重置部分 view 的背景颜色/资源
*
* @param view 父 view
*/
private void updateStaticViewBackground(View view) {
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View child = ((ViewGroup) view).getChildAt(i);
updateStaticViewBackground(child);
}
}
String backgroundString = (String) view.getTag(CustomLayoutInflaterFactory.TAG_BACKGROUND_ID);
String textColorString = (String) view.getTag(CustomLayoutInflaterFactory.TAG_TEXT_COLOR_ID);
if (backgroundString != null) {
if (backgroundString.startsWith("#")) return;
int backgroundId = Integer.parseInt(
backgroundString
.replace("@", "")
.replace("?", "")
);
if (backgroundId != 0) {
try {
TypedValue value = new TypedValue();
getResources().getValue(backgroundId, value, true);
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
view.setBackgroundColor(ExtensionsKt.toColor(backgroundId, this));
} else {
view.setBackground(ExtensionsKt.toDrawable(backgroundId, this));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (textColorString != null && view instanceof TextView) {
if (textColorString.startsWith("#")) return;
int textColorId = Integer.parseInt(
textColorString
.replace("@", "")
.replace("?", "")
);
if (textColorId != 0) {
try {
final ColorStateList colorStateList = ContextCompat.getColorStateList(this, textColorId);
((TextView) view).setTextColor(colorStateList);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
@ -98,7 +99,7 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
String tabTitle = tab.getText() != null ? tab.getText().toString() : "";
View tabView = provideTabView(i, tabTitle);
if (tabView == null)
tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle);
tabView = BaseFragment_TabLayout.createDefaultTabCustomView(this, tabTitle);
tab.setCustomView(tabView);
}
@ -133,4 +134,22 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
public void onPageScrollStateChanged(int state) {
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
View container = findViewById(R.id.activity_tab_container);
if (container != null) {
container.setBackgroundColor(ContextCompat.getColor(this, R.color.background_white));
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
if (tab != null) {
BaseFragment_TabLayout.updateTabStyle(tab, tab.isSelected());
}
}
}
if (mDividerLineView != null) {
mDividerLineView.setBackgroundColor(ContextCompat.getColor(this, R.color.divider));
}
}
}

View File

@ -0,0 +1,53 @@
package com.gh.base
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.R
class CustomLayoutInflaterFactory(
private val mAppCompatActivity: AppCompatActivity
) : LayoutInflater.Factory2 {
override fun onCreateView(
parent: View?,
name: String,
context: Context,
attrs: AttributeSet
): View? {
val view: View?
try {
view = mAppCompatActivity.delegate.createView(parent, name, context, attrs)
?: mAppCompatActivity.onCreateView(parent, name, context, attrs)
?: mAppCompatActivity.layoutInflater.createView(name, null, attrs)
} catch (e: Exception) {
return null
}
val n = attrs.attributeCount
for (i in 0 until n) {
val attributeName = attrs.getAttributeName(i).toString()
if (attributeName.contains("background")) {
view?.setTag(TAG_BACKGROUND_ID, attrs.getAttributeValue(i))
} else if (attributeName.contains("textColor")) {
view?.setTag(TAG_TEXT_COLOR_ID, attrs.getAttributeValue(i))
}
}
return view
}
override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
return mAppCompatActivity.onCreateView(name, context, attrs)
}
companion object {
const val TAG_BACKGROUND_ID = R.string.background_id
const val TAG_TEXT_COLOR_ID = R.string.text_color_id
}
}

View File

@ -91,7 +91,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityDestroyed(activity: Activity) {
// do nothing
AppManager.getInstance().finishActivity(activity)
}
}

View File

@ -13,6 +13,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -21,6 +22,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
@ -310,4 +312,25 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
mToolbarContainer.setVisibility(isHide ? View.GONE : View.VISIBLE);
}
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
if (mToolbar != null) {
mToolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.background_white));
}
if (mBackBtn != null) {
if (mBackBtn instanceof ImageView) {
((ImageView) mBackBtn).setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_bar_back));
} else if (mBackBtn instanceof TextView) {
((TextView) mBackBtn).setTextColor(ContextCompat.getColor(this, R.color.text_subtitle));
}
}
if (mTitleTv != null) {
mTitleTv.setTextColor(ContextCompat.getColor(this, R.color.text_black));
}
if (showDownloadMenu() && getMenuItem(R.id.menu_download) != null) {
((ImageView) getMenuItem(R.id.menu_download).getActionView().findViewById(R.id.menu_download_iv)).setImageDrawable(ContextCompat.getDrawable(this, R.drawable.toolbar_download));
}
}
}

View File

@ -1,10 +1,12 @@
package com.gh.base.fragment;
import android.app.Dialog;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import com.gh.common.util.ClickUtils;
import com.gh.common.util.NightModeUtils;
import com.gh.gamecenter.R;
import com.lightgame.utils.RuntimeUtils;
import com.lightgame.utils.Utils;
@ -28,6 +30,14 @@ import androidx.lifecycle.Lifecycle;
public class BaseDialogFragment extends DialogFragment {
protected boolean mNightMode;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNightMode = NightModeUtils.INSTANCE.isNightMode(requireContext());
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@ -95,6 +105,16 @@ public class BaseDialogFragment extends DialogFragment {
}
}
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onNightModeChange();
}
protected void onNightModeChange() {
mNightMode = NightModeUtils.INSTANCE.isNightMode(requireContext());
}
}

View File

@ -1,6 +1,7 @@
package com.gh.base.fragment;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@ -8,6 +9,7 @@ import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
@ -23,6 +25,7 @@ import com.gh.common.constant.Constants;
import com.gh.common.syncpage.ISyncAdapterHandler;
import com.gh.common.syncpage.SyncDataEntity;
import com.gh.common.syncpage.SyncPageRepository;
import com.gh.common.util.NightModeUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.R;
import com.gh.gamecenter.eventbus.EBMiPush;
@ -58,6 +61,8 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
protected boolean isEverPause;
protected boolean mNightMode;
@NonNull
protected String mEntrance = "";
@ -158,6 +163,12 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
if (addSyncPageObserver()) {
initSyncPageObserver();
}
if (BuildConfig.IS_NIGHT_MODE_ON) {
mNightMode = NightModeUtils.INSTANCE.isNightMode(requireContext());
} else {
mNightMode = false;
}
}
private void initSyncPageObserver() {
@ -230,6 +241,12 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
super.onResume();
isEverPause = false;
startPageTime = System.currentTimeMillis();
if (BuildConfig.IS_NIGHT_MODE_ON
&& !NightModeUtils.INSTANCE.getSystemMode()
&& mNightMode != NightModeUtils.INSTANCE.isNightMode(requireContext())) {
onNightModeChange();
}
}
@Override
@ -315,7 +332,9 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
// 为 fragment 附加 bundle (setArgument())
public BaseFragment with(Bundle bundle) {
this.setArguments(bundle);
if (!isStateSaved()) {
this.setArguments(bundle);
}
return this;
}
@ -331,4 +350,16 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
protected boolean addSyncPageObserver() {
return false;
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (BuildConfig.IS_NIGHT_MODE_ON) {
onNightModeChange();
}
}
protected void onNightModeChange() {
mNightMode = NightModeUtils.INSTANCE.isNightMode(requireContext());
}
}

View File

@ -1,5 +1,6 @@
package com.gh.base.fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
@ -8,6 +9,12 @@ import android.view.View;
import android.widget.CheckedTextView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import com.gh.base.adapter.FragmentAdapter;
import com.gh.common.view.TabIndicatorView;
import com.gh.gamecenter.R;
@ -20,11 +27,6 @@ import com.lightgame.view.NoScrollableViewPager;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
/**
* Created by khy on 15/03/18.
*/
@ -119,7 +121,7 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
if (tab == null) continue;
String tabTitle = tab.getText() != null ? tab.getText().toString() : "";
View tabView = provideTabView(i, tabTitle);
if (tabView == null) tabView = createDefaultTabCustomView(tabTitle);
if (tabView == null) tabView = createDefaultTabCustomView(requireContext(), tabTitle);
tab.setCustomView(tabView);
}
@ -152,7 +154,7 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
});
}
private static void updateTabStyle(TabLayout.Tab tab, boolean isChecked) {
public static void updateTabStyle(TabLayout.Tab tab, boolean isChecked) {
View tabView = tab.getCustomView();
if (tabView == null) {
Utils.log("TabLayout->Tab样式不是通用样式,请检查");
@ -171,12 +173,13 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
return;
}
tabTitle.setTypeface(isChecked ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
tabTitle.setTextColor(ContextCompat.getColorStateList(tabTitle.getContext(), R.color.text_tabbar_style));
}
// 如果不设置View的话无法动态设置字体样式
@NonNull
public static View createDefaultTabCustomView(String title) {
View view = LayoutInflater.from(HaloApp.getInstance().getApplication().getBaseContext()).inflate(R.layout.tab_item, null);
public static View createDefaultTabCustomView(Context context, String title) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
View tabTitle = view.findViewById(R.id.tab_title);
if (tabTitle instanceof CheckedTextView) {
((CheckedTextView) tabTitle).setText(title);
@ -198,4 +201,22 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
public void onPageScrollStateChanged(int state) {
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
View container = requireView().findViewById(R.id.fragment_tab_container);
if (container != null) {
container.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background_white));
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
if (tab != null) {
updateTabStyle(tab, tab.isSelected());
}
}
}
if (mDividerLineView != null) {
mDividerLineView.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.divider));
}
}
}

View File

@ -3,6 +3,7 @@ package com.gh.base.fragment
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
@ -93,7 +94,7 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
val tab = mTabLayout.getTabAt(i) ?: continue
val tabTitle = if (tab.text != null) tab.text.toString() else ""
var tabView = provideTabView(i, tabTitle)
if (tabView == null) tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle)
if (tabView == null) tabView = BaseFragment_TabLayout.createDefaultTabCustomView(requireContext(), tabTitle)
tab.customView = tabView
}
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex)
@ -121,6 +122,20 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
override fun onPageScrollStateChanged(state: Int) {}
override fun onNightModeChange() {
super.onNightModeChange()
val container = requireView().findViewById<View>(R.id.fragment_tab_container)
if (container != null) {
container.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background_white))
for (i in 0 until mTabLayout.tabCount) {
val tab = mTabLayout.getTabAt(i)
if (tab != null) {
BaseFragment_TabLayout.updateTabStyle(tab, tab.isSelected)
}
}
}
}
companion object {
const val PAGE_INDEX = "PAGE_INDEX"
}

View File

@ -3,6 +3,7 @@ package com.gh.common
import android.os.Handler
import android.os.Looper
import com.gh.base.GHThreadFactory
import com.gh.common.AppExecutor.heavyWeightIoExecutor
import com.gh.common.AppExecutor.ioExecutor
import com.gh.common.AppExecutor.lightWeightIoExecutor
import com.gh.common.AppExecutor.logExecutor
@ -16,31 +17,33 @@ import java.util.concurrent.*
* [ioExecutor] 是一个最大线程数固定的线程池,较为繁重的 IO 任务可以交给它
* [uiExecutor] 是主线程的包裹,需要切换至主线程执行可以用它
* [lightWeightIoExecutor] 是一个单线程的线程池,轻量级且需要保证同一线程的 IO 任务可以交给它
* [heavyWeightIoExecutor] 重量级的线程池,一些高频调用但不用保证结果的任务可以交给它
* [logExecutor] 只为上传 log 而使用的线程池
*/
object AppExecutor {
private val mCoreSize = Runtime.getRuntime().availableProcessors()
private val mMinimumPoolSize = 16.coerceAtLeast(mCoreSize * 4)
private val mMaximumPoolSize = 64.coerceAtLeast(mCoreSize * 16)
// TODO 因为 LinkedBlockingQueue 过大导致 MaximumPoolSize 的值几乎无效,下版本改造 [PackageRepository] 启动请求一堆游戏摘要信息的接口?
private val mMinimumPoolSize = 6.coerceAtLeast(mCoreSize)
private val mMaximumPoolSize = 24.coerceAtLeast(mCoreSize * 3)
@JvmStatic
val uiExecutor by lazy { MainThreadExecutor() }
@JvmStatic
val lightWeightIoExecutor by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LIGHT_WEIGHT_IO_THREAD")) }
val lightWeightIoExecutor: ExecutorService by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LIGHT_WEIGHT_IO_THREAD")) }
@JvmStatic
val logExecutor by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LOG_THREAD")) }
val heavyWeightIoExecutor: ExecutorService by lazy { Executors.newFixedThreadPool(2, GHThreadFactory("GH_HEAVY_WEIGHT_IO_THREAD")) }
@JvmStatic
val logExecutor: ExecutorService by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LOG_THREAD")) }
@JvmStatic
val ioExecutor = ThreadPoolExecutor(
mMinimumPoolSize,
mMaximumPoolSize,
20L, TimeUnit.SECONDS,
LinkedBlockingQueue<Runnable>(1000),
LinkedBlockingQueue(256),
GHThreadFactory("GH_IO_THREAD"))
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
@ -58,14 +61,14 @@ object AppExecutor {
}
}
fun runOnIoThread(isLightWeightTask: Boolean = false, f: () -> Unit) {
if (isLightWeightTask) {
AppExecutor.lightWeightIoExecutor.execute(f)
} else {
AppExecutor.ioExecutor.execute(f)
fun runOnIoThread(isLightWeightTask: Boolean = false, isHeavyWightTask: Boolean = false, f: () -> Unit) {
when {
isLightWeightTask -> lightWeightIoExecutor.execute(f)
isHeavyWightTask -> heavyWeightIoExecutor.execute(f)
else -> ioExecutor.execute(f)
}
}
fun runOnUiThread(f: () -> Unit) {
AppExecutor.uiExecutor.execute(f)
uiExecutor.execute(f)
}

View File

@ -17,9 +17,7 @@ import com.gh.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.*
import com.gh.gamecenter.energy.EnergyCenterActivity
import com.gh.gamecenter.energy.EnergyHouseActivity
import com.gh.gamecenter.entity.Badge
import com.gh.gamecenter.entity.MtaEvent
import com.gh.gamecenter.entity.NotificationUgc
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.help.QaFeedbackDialogFragment
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
@ -401,7 +399,25 @@ class DefaultJsApi(var context: Context) {
@JavascriptInterface
fun checkUpdateGhzs(msg: Any) {
context.startActivity(AboutActivity.getIntent(context, true));
context.startActivity(AboutActivity.getIntent(context, true))
}
@JavascriptInterface
public fun clickGameActivityDownloadBtn(event: Any) {
val gameActivityEvent = event.toString().toObject() ?: GameActivityEvent()
GameActivityDownloadHelper.start(context, gameActivityEvent)
}
@JavascriptInterface
fun isGameActivityTaskCompleted(event: Any, handler: CompletionHandler<Any>) {
val gameActivityEvent = event.toString().toObject() ?: GameActivityEvent()
GameActivityDownloadHelper.checkTaskComplete(context, gameActivityEvent, handler)
}
@JavascriptInterface
fun postGameActivityExposureEvent(event: Any) {
val gameActivityEvent = event.toString().toObject() ?: GameActivityEvent()
GameActivityDownloadHelper.postExposureEvent(gameActivityEvent)
}
@Keep
@ -423,4 +439,12 @@ class DefaultJsApi(var context: Context) {
@Keep
internal data class BrowseTaskEvent(var timeout: String = "", var isFinished: String = "")
@Keep
data class GameActivityEvent(
var gameId: String = "",
var activityTitle: String = "",
var activityId: String = "",
var platform: String = ""
)
}

View File

@ -32,7 +32,7 @@ import java.nio.charset.Charset
object DefaultUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String) : Boolean {
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
return interceptUrl(context, url, entrance, false)
}
@ -335,6 +335,7 @@ object DefaultUrlHandler {
EntranceUtils.HOST_UPLOAD_VIDEO_NEW -> {
val activityName = uri.getQueryParameter("activity_name") ?: ""
val activityId = uri.getQueryParameter("activity_id") ?: ""
val original = uri.getQueryParameter("original") ?: ""
val forumName = uri.getQueryParameter("forum_name") ?: ""
val forumId = uri.getQueryParameter("forum_id") ?: ""
val forumIcon = uri.getQueryParameter("forum_icon") ?: ""
@ -343,11 +344,16 @@ object DefaultUrlHandler {
val gameName = uri.getQueryParameter("game_name") ?: ""
val icon = uri.getQueryParameter("game_icon") ?: ""
val iconSubscript = uri.getQueryParameter("game_icon_subscript") ?: ""
val gameEntity = if (forumType == BbsType.OFFICIAL_BBS.value) {
GameEntity(id = gameId, mName = gameName, mIcon = icon, mIconSubscript = iconSubscript)
val gameEntity =
if (forumType == BbsType.OFFICIAL_BBS.value && gameId.isNotEmpty() && gameName.isNotEmpty() && icon.isNotEmpty()) {
GameEntity(id = gameId, mName = gameName, mIcon = icon, mIconSubscript = iconSubscript)
} else null
val activityLabelEntity = if (activityId.isNotEmpty() && activityName.isNotEmpty()) {
ActivityLabelEntity(id = activityId, name = activityName, original = original.ifEmpty { "false" }.toBoolean())
} else null
val communityEntity = if (forumId.isNotEmpty() && forumName.isNotEmpty() && forumIcon.isNotEmpty()) {
CommunityEntity(id = forumId, name = forumName, icon = forumIcon)
} else null
val activityLabelEntity = ActivityLabelEntity(id = activityId, name = activityName)
val communityEntity = CommunityEntity(id = forumId, name = forumName, icon = forumIcon)
context.startActivity(
VideoPublishActivity.getIntent(
@ -356,7 +362,8 @@ object DefaultUrlHandler {
gameEntity,
activityLabelEntity,
forumType,
false,
disableForumSelection = false,
isFromCommunityActivity = true,
entrance,
""
)

View File

@ -49,6 +49,8 @@ public class Constants {
// 最近显示的弹窗信息
public static final String SP_LAST_OPENING_ID = "last_opening_dialog_id";
public static final String SP_LAST_OPENING_TIME = "last_opening_dialog_time";
public static final String SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID = "last_accepted_privacy_dialog_id";
// 游戏图标和图标角标
public static final String RAW_GAME_ICON = "raw_game_icon";
@ -245,6 +247,8 @@ public class Constants {
public static final String SP_MY_GAME_GUIDE = "my_game_guide";
//微信绑定配置信息
public static final String SP_WECHAT_CONFIG = "wechat_config";
//游戏库导航栏小红点提示
public static final String SP_GAME_NAVIGATION = "game_navigation";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
@ -415,4 +419,9 @@ public class Constants {
public static final String DEFAULT_VIVO_BROWSER_HINT_URL = "https://static-web.ghzs.com/ghzs_help/help.html?content=618112ce04796e63e97643a4&from=ghzs";
public static final int FOLLOW_HINT_TRIGGER_HEIGHT = 10;
// 深色模式
public static final String SP_NIGHT_MODE = "night_mode";
// 跟随系统模式
public static final String SP_SYSTEM_MODE = "system_mode";
}

View File

@ -16,7 +16,6 @@ import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
@ -34,6 +33,7 @@ import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.DownloadDialogHelper;
import com.gh.common.util.ExtensionsKt;
import com.gh.common.util.GameUtils;
import com.gh.common.util.GameViewUtils;
import com.gh.common.util.ImageUtils;
@ -84,22 +84,18 @@ import java.util.List;
public class BindingAdapters {
@BindingAdapter("imageIcon")
public static void loadIcon(SimpleDraweeView view, String imageUrl) {
ImageUtils.displayIcon(view, imageUrl);
}
@BindingAdapter("imageUrl")
public static void loadImage(SimpleDraweeView view, String imageUrl) {
ImageUtils.display(view, imageUrl);
}
@BindingAdapter("setTextSize")
public static void setTextSize(TextView view, int number) {
view.setTextSize(number);
}
@BindingAdapter("setTypeface")
public static void setTypeface(TextView view, String type) {
if (type == null) return;
@ -119,7 +115,6 @@ public class BindingAdapters {
}
}
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
public static void addDetailKaiFuView(LinearLayout view, List<ServerCalendarEntity> list
, OnViewClickListener listener, Boolean isReadyPatch) {
if (list == null) return;
@ -127,13 +122,13 @@ public class BindingAdapters {
for (int i = 0; i < list.size() + 1; i++) { // 1 is Title
View inflate = LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_detail_item_row, null);
KaifuDetailItemRowBinding binding = KaifuDetailItemRowBinding.bind(inflate);
binding.setIsCloseBottom(i == list.size());
binding.setIsReadyPatch(isReadyPatch);
if (i == 0) {
binding.setIsTitle(true);
} else {
ServerCalendarEntity serverEntity = list.get(i - 1);
binding.setEntity(serverEntity);
binding.getRoot().setBackgroundColor(isReadyPatch != null && isReadyPatch ? ExtensionsKt.toColor(R.color.theme) : ExtensionsKt.toColor(R.color.white));
binding.getRoot().setPadding(DisplayUtils.dip2px(1), DisplayUtils.dip2px(1), DisplayUtils.dip2px(1), i == list.size() ? DisplayUtils.dip2px(1) : 0);
ServerCalendarEntity serverEntity = list.get(i - 1);
binding.timeTv.setText(i == 0 ? "时间" : serverEntity.getFormatTime("HH:mm"));
binding.remarkTv.setText(i == 0 ? "备注" : serverEntity.getRemark());
binding.nameTv.setText(i == 0 ? "名字" : (TextUtils.isEmpty(serverEntity.getNote()) ? "-" : serverEntity.getNote()));
if (i != 0) {
binding.getRoot().setOnClickListener(v -> {
listener.onClick(v, isReadyPatch != null && isReadyPatch ? serverEntity : null);
});
@ -155,12 +150,10 @@ public class BindingAdapters {
}
// 如果超过10000则转换为1.0W
@BindingAdapter("transSimpleCount")
public static void transSimpleCount(TextView view, int count) {
view.setText(NumberUtils.transSimpleCount(count));
}
@BindingAdapter("textColorFromString")
public static void textColorFromString(TextView tv, String hexString) {
if (TextUtils.isEmpty(hexString)) return;
@ -171,7 +164,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("visibleGone")
public static void showHide(View view, Boolean show) {
if (show != null && show) {
view.setVisibility(View.VISIBLE);
@ -180,7 +172,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("goneIf")
public static void goneIf(View view, Boolean gone) {
if (gone != null && gone) {
view.setVisibility(View.GONE);
@ -192,7 +183,6 @@ public class BindingAdapters {
/**
* lazy 的 paddingTop
*/
@BindingAdapter("lazyPaddingLeft")
public static void lazyPaddingLeft(View view, int paddingLeftInDp) {
view.setPadding(DisplayUtils.dip2px(paddingLeftInDp), view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom());
}
@ -200,7 +190,6 @@ public class BindingAdapters {
/**
* lazy 的 paddingTop
*/
@BindingAdapter("lazyPaddingTop")
public static void lazyPaddingTop(View view, int paddingTopInDp) {
view.setPadding(view.getPaddingLeft(), DisplayUtils.dip2px(paddingTopInDp), view.getPaddingRight(), view.getPaddingBottom());
}
@ -208,12 +197,10 @@ public class BindingAdapters {
/**
* lazy 的 paddingBottom
*/
@BindingAdapter("lazyPaddingBottom")
public static void lazyPaddingBottom(View view, int paddingBottomInDp) {
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), DisplayUtils.dip2px(paddingBottomInDp));
}
@BindingAdapter("visibleInvisible")
public static void visibleInvisible(View view, Boolean show) {
if (show != null && show) {
view.setVisibility(View.VISIBLE);
@ -222,7 +209,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("messageUnread")
public static void setMessageUnread(TextView view, int unreadCount) {
if (unreadCount < 100) {
view.setText(String.valueOf(unreadCount));
@ -231,7 +217,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("serverTypePadding")
public static void setServerTypePadding(TextView view, String serverType) {
int paddRight = 0;
if (TextUtils.isEmpty(serverType)) {
@ -249,7 +234,6 @@ public class BindingAdapters {
view.setPadding(0, 0, paddRight, 0);
}
@BindingAdapter("serverType")
public static void setServerType(TextView view, String serverType) {
view.setText(serverType);
if ("删档内测".equals(serverType) || "不删档内测".equals(serverType)) {
@ -259,26 +243,22 @@ public class BindingAdapters {
}
}
@BindingAdapter("game")
public static void setGame(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity);
}
}
@BindingAdapter("gameIcon")
public static void setGameIcon(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript());
}
}
@BindingAdapter("articleType")
public static void setArticleType(TextView view, String articleType) {
NewsUtils.setNewsType(view, articleType, 0, 0);
}
@BindingAdapter("detailDownloadText")
public static void setDetailDownloadText(TextView view, GameEntity gameEntity) {
if (gameEntity == null || gameEntity.getApk().isEmpty()) {
view.setBackgroundResource(R.drawable.game_item_btn_pause_style);
@ -287,7 +267,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("liBaoBtn")
public static void setLiBaoBtn(TextView view, String status) {
if (TextUtils.isEmpty(status)) return;
switch (status) {
@ -352,7 +331,6 @@ public class BindingAdapters {
}
// 大图下的进度条
@BindingAdapter({"downloadButton", "traceEvent", "clickCallBack", "entrance", "location"})
public static void setDownloadButton(DownloadProgressBar progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@ -602,6 +580,7 @@ public class BindingAdapters {
case notfound:
case uncertificated:
case unqualified:
case unavailable:
break;
default:
break;
@ -692,13 +671,11 @@ public class BindingAdapters {
}
}
@BindingAdapter("gameLabelList")
public static void setGameLabelList(LinearLayout layout, List<TagStyleEntity> tagStyle) {
GameViewUtils.setLabelList(layout.getContext(), layout, tagStyle);
}
// 包含测试开服标签
@BindingAdapter("setGameTags")
public static void setGameTags(LinearLayout layout, GameEntity gameEntity) {
try {
if (layout.getVisibility() == View.GONE) return;
@ -739,7 +716,6 @@ public class BindingAdapters {
}
}
@BindingAdapter("setVideoDetailGameTags")
public static void setVideoDetailGameTags(LinearLayout layout, GameEntity gameEntity) {
try {
ArrayList<TagStyleEntity> tagStyle = new ArrayList<>();
@ -767,14 +743,12 @@ public class BindingAdapters {
}
}
@BindingAdapter("isRefreshing")
public static void isRefreshing(SwipeRefreshLayout layout, LoadStatus status) {
if (status != LoadStatus.INIT_LOADING && status != LoadStatus.LIST_LOADING) {
layout.setRefreshing(false);
}
}
@BindingAdapter({"setGameName", "isShowPlatform", "isShowSuffix"})
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
if (isShowPlatform && game.getApk().size() > 0) {
@ -787,7 +761,6 @@ public class BindingAdapters {
}
@BindingAdapter({"setCommunityImage", "setCommunityVideoImage"})
public static void setCommunityImage(SimpleDraweeView imageView, List<String> images, List<CommunityVideoEntity> videos) {
if (videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
@ -801,7 +774,6 @@ public class BindingAdapters {
}
}
@BindingAdapter({"setCommunityVideoDuration"})
public static void setCommunityVideoDuration(TextView mVideoDuration, List<CommunityVideoEntity> videos) {
if (videos != null && videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
@ -813,7 +785,6 @@ public class BindingAdapters {
}
}
@BindingAdapter({"setGameTags", "setMaxGameTags"})
public static void setGameTags(TextView view, List<TagStyleEntity> tags, int maxTags) {
if (tags == null) {
view.setText("");
@ -842,7 +813,6 @@ public class BindingAdapters {
view.setText(span);
}
@BindingAdapter({"setVideoData"})
public static void setVideoData(TextView view, int count) {
if (count > 0) {
view.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(view.getContext(), R.drawable.ic_video_data_up), null, null, null);

View File

@ -87,7 +87,7 @@ class ApplyModeratorDialogFragment : BaseDialogFragment() {
}
}.show(
activity.supportFragmentManager,
PrivacyDialogFragment::class.java.simpleName
ApplyModeratorDialogFragment::class.java.simpleName
)
}
}

View File

@ -129,10 +129,17 @@ class CertificationDialog(context: Context, private val authDialogEntity: AuthDi
val currentActivity = AppManager.getInstance().currentActivity() ?: return
AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
.startForResult(ShellActivity.getIntent(context, ShellActivity.Type.REAL_NAME_INFO, null), object : Callback {
.startForResult(
ShellActivity.getIntent(
context,
ShellActivity.Type.REAL_NAME_INFO,
).apply {
putExtra(EntranceUtils.KEY_GAME_ID, gameId)
}, object : Callback {
override fun onActivityResult(resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) {
val isAuthSuccess = data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
val isAuthSuccess =
data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
if (isAuthSuccess) {
listener.onConfirm()
dismiss()

View File

@ -23,6 +23,7 @@ import com.gh.common.constant.Constants
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogDeviceRemindBinding
import com.gh.gamecenter.entity.DeviceDialogEntity
import com.gh.gamecenter.entity.GameEntity
import com.google.gson.reflect.TypeToken
@ -31,14 +32,13 @@ import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.dialog_device_remind.view.*
import java.lang.ref.WeakReference
/**
* 设备提醒弹窗
*/
class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val gameEntity: GameEntity) : Dialog(context, R.style.GhAlertDialog) {
private lateinit var view: View
private val mBinding: DialogDeviceRemindBinding by lazy { DialogDeviceRemindBinding.inflate(layoutInflater) }
private var currentPage = 0
private var mSlideLooperInterval = 3000L
private lateinit var mLooperHandle: LooperHandle
@ -96,13 +96,12 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
view = LayoutInflater.from(context).inflate(R.layout.dialog_device_remind, null)
setContentView(view)
setContentView(mBinding.root)
mDatas.addAll(entity.gallery)
view.titleTv.text = entity.title
view.contentTv.text = entity.content
mBinding.titleTv.text = entity.title
mBinding.contentTv.text = entity.content
view.bannerView.apply {
mBinding.bannerView.apply {
orientation = ViewPager2.ORIENTATION_HORIZONTAL
mAdapter = BannerAdapter()
val recyclerView = getChildAt(0) as RecyclerView
@ -133,36 +132,36 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
}
val isFirst = SPUtils.getBoolean(Constants.SP_FIRST_DEVICE_REMIND, false)
if (!isFirst) {
view.cancelTv.isEnabled = false
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_round_f5f5f5)
mBinding.cancelTv.isEnabled = false
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_round_f5f5f5)
disposable = countDownTimer(3) { finish, time ->
if (finish) {
view.cancelTv.isEnabled = true
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
view.cancelTv.text = "我知道了"
view.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
mBinding.cancelTv.isEnabled = true
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
mBinding.cancelTv.text = "我知道了"
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
} else {
view.cancelTv.text = "我知道了(${time}S)"
mBinding.cancelTv.text = "我知道了(${time}S)"
}
}
SPUtils.setBoolean(Constants.SP_FIRST_DEVICE_REMIND, true)
} else {
view.noRemindAgainCb.visibility = View.VISIBLE
view.cancelTv.text = "我知道了"
view.cancelTv.isEnabled = true
view.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
mBinding.noRemindAgainCb.visibility = View.VISIBLE
mBinding.cancelTv.text = "我知道了"
mBinding.cancelTv.isEnabled = true
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
}
view.cancelTv.setOnClickListener {
SPUtils.setBoolean(Constants.SP_NO_REMIND_AGAIN, view.noRemindAgainCb.isChecked)
mBinding.cancelTv.setOnClickListener {
SPUtils.setBoolean(Constants.SP_NO_REMIND_AGAIN, mBinding.noRemindAgainCb.isChecked)
dismiss()
}
DownloadManager.getInstance().addObserver(dataWatcher)
}
private fun addIndicator() {
view.indicatorLl.removeAllViews()
mBinding.indicatorLl.removeAllViews()
mDatas.forEach { _ ->
val indicatorView = ImageView(context).apply {
setImageResource(R.drawable.selector_device_remind_indicator)
@ -171,13 +170,13 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
params.rightMargin = DisplayUtils.dip2px(1F)
layoutParams = params
}
view.indicatorLl.addView(indicatorView)
mBinding.indicatorLl.addView(indicatorView)
}
}
private fun slideIndicator(position: Int) {
for (i in 0 until view.indicatorLl.childCount) {
val childAt = view.indicatorLl.getChildAt(i)
for (i in 0 until mBinding.indicatorLl.childCount) {
val childAt = mBinding.indicatorLl.getChildAt(i)
childAt.isSelected = i == position
}
}
@ -210,7 +209,7 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
fun scrollToNextPage() {
currentPage++
view.bannerView.setCurrentItem(currentPage, true)
mBinding.bannerView.setCurrentItem(currentPage, true)
}
fun startScroll() {

View File

@ -19,6 +19,7 @@ import com.gh.common.util.PermissionHelper.INSTALL_PERMISSION_CODE
import com.gh.common.xapk.XapkInstaller
import com.gh.gamecenter.R
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import kotlin.random.Random
class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
@ -26,7 +27,7 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
lateinit var mView: View
var isXapk = false
var url: String = ""
var mCallBack: (() -> Unit)? = null
var mCallBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.dialog_install_permission, null, false)
@ -56,7 +57,7 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
closeTv.setOnClickListener {
MtaHelper.onEvent(getEvent(), getKey(), "文案样式_点击以后再说")
if (isXapk) {
mCallBack?.invoke()
mCallBack?.invoke(false)
}
dismiss()
}
@ -77,9 +78,11 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
SPUtils.setString(Constants.SP_XAPK_URL, "")
mCallBack?.invoke()
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
SPUtils.setString(Constants.SP_XAPK_URL, "")
}
mCallBack?.invoke(true)
dismiss()
}
}
@ -90,27 +93,27 @@ class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
companion object {
@JvmStatic
fun show(activity: AppCompatActivity, downloadEntity: DownloadEntity, callBack: (() -> Unit)?) {
fun show(activity: AppCompatActivity, downloadEntity: DownloadEntity, callBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)?) {
val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == downloadEntity.path.getExtension()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
callBack?.invoke()
callBack?.invoke(false)
return
}
val haveInstallPermission = activity.packageManager.canRequestPackageInstalls()
if (haveInstallPermission) {
callBack?.invoke()
callBack?.invoke(false)
return
}
if (isXapk) {
val xapkUnzipVersions = Config.getSettings()?.permissionPopupAppliedVersions?.xapkUnzip
if (xapkUnzipVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) {
callBack?.invoke()
callBack?.invoke(false)
return
}
} else {
val installVersions = Config.getSettings()?.permissionPopupAppliedVersions?.install
if (installVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) {
callBack?.invoke()
callBack?.invoke(false)
return
}
}

View File

@ -16,10 +16,10 @@ import com.gh.common.util.PermissionHelper
import com.gh.common.util.fromHtml
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogNotificationHintBinding
import com.gh.gamecenter.entity.NotificationStyleEntity
import com.gh.gamecenter.entity.NotificationUgc
import com.lightgame.utils.Utils
import kotlinx.android.synthetic.main.dialog_notification_hint.*
import org.json.JSONArray
import java.io.BufferedReader
import java.io.IOException
@ -30,9 +30,10 @@ import kotlin.random.Random
class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
private var mNotificationUgc: NotificationUgc? = null
private val mBinding: DialogNotificationHintBinding by lazy { DialogNotificationHintBinding.inflate(layoutInflater) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_notification_hint, null)
return mBinding.root
}
@Suppress("DEPRECATION")
@ -55,39 +56,41 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
val styleEntityJson = jsonObj.getJSONObject(mNotificationUgc!!.value)
val styleEntity = GsonUtils.fromJson(styleEntityJson.toString(), NotificationStyleEntity::class.java)
val drawableId = resources.getIdentifier(styleEntity.image, "drawable", requireContext().packageName)
notificationIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), drawableId))
notificationTitle.text = styleEntity.title
notificationContent.text = styleEntity.content.fromHtml()
if (index == 0) {
closeIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_notification_close_1))
} else {
activateTv.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_notification_open_btn_style_1)
activateTv.text = "优雅的开启"
}
mBinding.run {
notificationIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), drawableId))
notificationTitle.text = styleEntity.title
notificationContent.text = styleEntity.content.fromHtml()
if (index == 0) {
closeIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_notification_close_1))
} else {
activateTv.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_notification_open_btn_style_1)
activateTv.text = "优雅的开启"
}
activateTv.setOnClickListener {
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击立即开启")
dismissAllowingStateLoss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//这种方案适用于 API 26, 即8.0含8.0)以上可以用
val intent = Intent()
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
activateTv.setOnClickListener {
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击立即开启")
dismissAllowingStateLoss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//这种方案适用于 API 26, 即8.0含8.0)以上可以用
val intent = Intent()
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
PermissionHelper.toPermissionSetting(requireActivity())
}
} else {
PermissionHelper.toPermissionSetting(requireActivity())
}
} else {
PermissionHelper.toPermissionSetting(requireActivity())
}
}
closeIv.setOnClickListener {
dismissAllowingStateLoss()
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击关闭")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击关闭")
closeIv.setOnClickListener {
dismissAllowingStateLoss()
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击关闭")
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击关闭")
}
}
dialog?.setCanceledOnTouchOutside(true)

View File

@ -62,9 +62,11 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
detectionObjects?.forEach { detectionObject ->
if (detectionObject.packages.contains(packageName)) {
val packageLink = gameEntity?.packageDialog?.links?.find { it.buttonLink }
LogUtils.uploadPackageCheck("pkg_check_pop_download", if (DownloadStatus.add == downloadEntity.status) "下载开始" else "下载完成",
gameEntity, packageLink?.text ?: "", packageLink?.title
?: "", downloadEntity.gameId, downloadEntity.getMetaExtra(Constants.GAME_NAME))
LogUtils.uploadPackageCheck(
"pkg_check_pop_download", if (DownloadStatus.add == downloadEntity.status) "下载开始" else "下载完成",
gameEntity, packageLink?.text ?: "", packageLink?.title
?: "", downloadEntity.gameId, downloadEntity.getMetaExtra(Constants.GAME_NAME)
)
}
}
}
@ -98,8 +100,10 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val spanBuilder = SpanBuilder(it.linkHintText).build()
it.links.forEachIndexed { index, link ->
val linkSpan = SpanBuilder(link.title ?: "").click(0, (link.title
?: "").length, R.color.theme_font, true) {
val linkSpan = SpanBuilder(link.title ?: "").click(
0, (link.title
?: "").length, R.color.theme_font, true
) {
LogUtils.uploadPackageCheck("pkg_check_pop_click", "点击链接", gameEntity, link.text, link.title, "", "")
DirectUtils.directToLinkPage(requireContext(), link, "包名检测弹窗", "")
}.build()
@ -205,6 +209,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (it >= mDuration) {
mDisposable?.dispose()
binding.downloadBtn.isEnabled = true
binding.downloadBtn.background = R.drawable.bg_notification_open_btn_style_2.toDrawable()
}
}
val animator = ValueAnimator.ofInt(0, 100)
@ -273,7 +278,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
}
inner class PackageCheckAdapter(val context: Context, val entities: ArrayList<DetectionObjectEntity>) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
inner class PackageCheckAdapter(val context: Context, val entities: ArrayList<DetectionObjectEntity>) :
BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
private var index = -1
fun notifyPackages() {
@ -282,7 +288,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return PackageCheckViewHolder(PackageCheckItemBinding.bind(LayoutInflater.from(context).inflate(R.layout.package_check_item, parent, false)))
return PackageCheckViewHolder(parent.toBinding())
}
override fun getItemCount(): Int = entities.size
@ -290,7 +296,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is PackageCheckViewHolder) {
val entity = entities[position]
holder.binding.entity = entity
holder.binding.gameNameTv.text = entity.text
if (position <= index) {
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
if (isAllInstalled) {
@ -339,7 +345,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (!activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) return
var dialogFragment = activity.supportFragmentManager.findFragmentByTag(PackageCheckDialogFragment::class.java.simpleName) as? PackageCheckDialogFragment
var dialogFragment =
activity.supportFragmentManager.findFragmentByTag(PackageCheckDialogFragment::class.java.simpleName) as? PackageCheckDialogFragment
if (dialogFragment == null) {
dialogFragment = PackageCheckDialogFragment()
dialogFragment.gameEntity = gameEntity

View File

@ -1,157 +0,0 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.method.ScrollingMovementMethod
import android.text.style.ClickableSpan
import android.view.*
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentTransaction
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.util.dip2px
import com.gh.common.view.CustomLinkMovementMethod
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
class PrivacyDialogFragment : BaseDialogFragment() {
// private val mLocalPrivacyHtml = "file:///android_asset/privacy_policies.html"
// private val mLocalRegulationHtml = "file:///android_asset/user_regulation.html"
var containerView: View? = null
var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
containerView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_privacy_protocol, null, false)
return containerView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
// val mWebViewRegulation = containerView?.findViewById<WebView>(R.id.webView2)
//
// mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
// mWebViewRegulation?.isHorizontalScrollBarEnabled = false
val contentTv = containerView?.findViewById<TextView>(R.id.contentTv)
val descTv = containerView?.findViewById<TextView>(R.id.descTv)
contentTv?.movementMethod = ScrollingMovementMethod()
val skipText = SpannableStringBuilder("查看完整版的隐私政策和用户协议")
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.privacy_policy_url), true)
context?.startActivity(intent)
}
}, skipText.length - 9, skipText.length - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.disclaimer_url), true)
context?.startActivity(intent)
}
}, skipText.length - 4, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
descTv?.movementMethod = CustomLinkMovementMethod()
descTv?.text = skipText
// val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
//
// mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
//
// val settingsArrayList = arrayListOf(mWebViewPrivacy?.settings, mWebViewRegulation?.settings)
//
// for (settings in settingsArrayList) {
// settings?.javaScriptEnabled = true
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
// }
// // 避免提示网页有害信息不能访问
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// settings?.safeBrowsingEnabled = false
// }
//
// // 适配大于屏幕宽度的页面
// settings?.useWideViewPort = true
// settings?.loadWithOverviewMode = true
// settings?.domStorageEnabled = true
//
// // 自适应屏幕
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// settings?.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
// }
// }
// mWebViewPrivacy?.webViewClient = client
// mWebViewRegulation?.webViewClient = client
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
mCallBack?.invoke(false)
dismissAllowingStateLoss()
}
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
mCallBack?.invoke(true)
dismissAllowingStateLoss()
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val createDialog = super.onCreateDialog(savedInstanceState)
createDialog.setCanceledOnTouchOutside(false)
createDialog.setOnKeyListener(object : DialogInterface.OnKeyListener {
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true
}
return false
}
})
val window = createDialog.window
window?.setGravity(Gravity.CENTER)
return createDialog
}
override fun onStart() {
super.onStart()
val width = requireContext().resources.displayMetrics.widthPixels - 60F.dip2px()
val height = ViewGroup.LayoutParams.WRAP_CONTENT
dialog?.window?.setLayout(width, height)
}
companion object {
@JvmStatic
fun show(activity: AppCompatActivity, callBack: ((isSuccess: Boolean) -> Unit)?) {
var privacyDialogFragment = activity.supportFragmentManager.findFragmentByTag(PrivacyDialogFragment::class.java.simpleName) as? PrivacyDialogFragment
if (privacyDialogFragment != null) {
privacyDialogFragment.mCallBack = callBack
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
transaction.show(privacyDialogFragment)
transaction.commit()
} else {
privacyDialogFragment = PrivacyDialogFragment().apply {
mCallBack = callBack
}
privacyDialogFragment.show(activity.supportFragmentManager, PrivacyDialogFragment::class.java.simpleName)
}
}
}
}

View File

@ -0,0 +1,190 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.method.ScrollingMovementMethod
import android.text.style.ClickableSpan
import android.view.*
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.constant.Constants
import com.gh.common.util.SPUtils
import com.gh.common.util.dip2px
import com.gh.common.util.fromHtml
import com.gh.common.view.CustomLinkMovementMethod
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.databinding.DialogPrivacyProtocolBinding
import com.gh.gamecenter.entity.DialogEntity
import com.lightgame.utils.AppManager
import splitties.bundle.put
class PrivacyPolicyDialogFragment : BaseDialogFragment() {
private var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
private val mBinding by lazy { DialogPrivacyProtocolBinding.inflate(layoutInflater) }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mBinding.contentTv.movementMethod = ScrollingMovementMethod()
val privacyPolicyEntity = arguments?.get(KEY_DATA) as? DialogEntity.PrivacyPolicyEntity
if (privacyPolicyEntity == null) {
showPreLaunchStyle()
} else {
showUpdatedStyle(privacyPolicyEntity)
}
}
private fun showUpdatedStyle(privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity) {
mBinding.titleIv.visibility = View.VISIBLE
mBinding.privacyTitleTv.text = "光环助手《隐私协议》更新"
mBinding.contentTv.text = privacyPolicyEntity.content.fromHtml()
val skipText = SpannableStringBuilder("查看隐私政策详情")
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.privacy_policy_url), true)
context?.startActivity(intent)
}
}, skipText.length - 6, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
mBinding.descTv.movementMethod = CustomLinkMovementMethod()
mBinding.descTv.text = skipText
if (privacyPolicyEntity.alertType == "INFORM") {
mBinding.refuseTv.visibility = View.GONE
mBinding.agreeTv.text = "我知道了"
mBinding.agreeTv.setOnClickListener {
SPUtils.setString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, privacyPolicyEntity.id)
mCallBack?.invoke(true)
dismissAllowingStateLoss()
}
} else {
mBinding.refuseTv.text = "不同意退出"
mBinding.agreeTv.text = "同意"
mBinding.refuseTv.setOnClickListener {
dismissAllowingStateLoss()
AppManager.getInstance().finishAllActivity()
}
mBinding.agreeTv.setOnClickListener {
SPUtils.setString(Constants.SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID, privacyPolicyEntity.id)
mCallBack?.invoke(true)
dismissAllowingStateLoss()
}
}
}
private fun showPreLaunchStyle() {
val skipText = SpannableStringBuilder("查看完整版的隐私政策和用户协议")
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.privacy_policy_url), true)
context?.startActivity(intent)
}
}, skipText.length - 9, skipText.length - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), R.color.theme_font)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.disclaimer_url), true)
context?.startActivity(intent)
}
}, skipText.length - 4, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
mBinding.descTv.movementMethod = CustomLinkMovementMethod()
mBinding.descTv.text = skipText
mBinding.refuseTv.setOnClickListener {
mCallBack?.invoke(false)
dismissAllowingStateLoss()
}
mBinding.agreeTv.setOnClickListener {
mCallBack?.invoke(true)
dismissAllowingStateLoss()
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val createDialog = super.onCreateDialog(savedInstanceState)
createDialog.setCanceledOnTouchOutside(false)
createDialog.setOnKeyListener(object : DialogInterface.OnKeyListener {
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true
}
return false
}
})
val window = createDialog.window
window?.setGravity(Gravity.CENTER)
return createDialog
}
override fun onStart() {
super.onStart()
val width = requireContext().resources.displayMetrics.widthPixels - 60F.dip2px()
val height = ViewGroup.LayoutParams.WRAP_CONTENT
dialog?.window?.setLayout(width, height)
}
companion object {
const val KEY_DATA = "data"
@JvmStatic
fun show(activity: FragmentActivity,
privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity? = null,
callBack: ((isSuccess: Boolean) -> Unit)?) {
var privacyDialogFragment = activity.supportFragmentManager.findFragmentByTag(PrivacyPolicyDialogFragment::class.java.simpleName) as? PrivacyPolicyDialogFragment
if (privacyDialogFragment != null) {
privacyDialogFragment.mCallBack = callBack
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
transaction.show(privacyDialogFragment)
transaction.commit()
} else {
privacyDialogFragment = PrivacyPolicyDialogFragment().apply {
mCallBack = callBack
}
}
privacyDialogFragment.arguments = Bundle().apply {
put(KEY_DATA, privacyPolicyEntity)
}
privacyDialogFragment.show(
activity.supportFragmentManager,
PrivacyPolicyDialogFragment::class.java.simpleName
)
}
}
}

View File

@ -3,7 +3,7 @@ package com.gh.common.exposure
import android.os.Parcelable
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@Keep
@Parcelize
@ -12,6 +12,8 @@ data class ExposureEntity(
val gameId: String? = "",
@SerializedName("subject_id")
val subjectId: String? = null, // 专题 id
@SerializedName("carousel_id")
val carouselId: String? = "", // 轮播图 id
val gameName: String? = "",
val gameVersion: String? = "",
val sequence: Int? = 0,
@ -43,6 +45,8 @@ data class ExposureEntity(
var categoryId: String? = null,
@SerializedName("category_v2_id")
var categoryV2Id: String? = null,
@SerializedName("navigation_id")
var navigationId: String? = null,
// 专题详情的来源页面和来源 id
@SerializedName("source_page")
@ -69,6 +73,7 @@ data class ExposureEntity(
BLOCK_ID -> blockId = id
CATEGORY_ID -> categoryId = id
CATEGORY_V2_ID -> categoryV2Id = id
NAVIGATION_ID -> navigationId = id
}
containerId = null
@ -80,5 +85,6 @@ data class ExposureEntity(
const val BLOCK_ID = "block_id"
const val CATEGORY_ID = "category_id"
const val CATEGORY_V2_ID = "category_v2_id"
const val NAVIGATION_ID = "navigation_id"
}
}

View File

@ -12,7 +12,7 @@ import com.gh.common.util.getFirstElementDividedByDivider
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.entity.GameEntity
import com.lightgame.download.DownloadEntity
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.util.*
import kotlin.collections.ArrayList

View File

@ -2,7 +2,7 @@ package com.gh.common.exposure
import android.os.Parcelable
import androidx.annotation.Keep
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@Keep
@Parcelize

View File

@ -2,7 +2,7 @@ package com.gh.common.exposure.meta
import android.os.Parcelable
import androidx.annotation.Keep
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@Keep
@Parcelize

View File

@ -15,7 +15,6 @@ import com.gh.common.util.tryWithDefaultCatch
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.manager.UserManager
import com.halo.assistant.HaloApp
import com.leon.channel.helper.ChannelReaderUtil
import com.walkud.rom.checker.RomIdentifier
object MetaUtil {

View File

@ -16,7 +16,7 @@ import com.gh.gamecenter.room.converter.*
import com.gh.gamecenter.room.dao.*
import com.halo.assistant.HaloApp
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class], version = 10, exportSchema = false)
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class], version = 11, exportSchema = false)
@TypeConverters(CountConverter::class,
CommunityConverter::class,
TimeConverter::class,
@ -32,7 +32,8 @@ import com.halo.assistant.HaloApp
QuestionsConverter::class,
MeConverter::class,
SimpleGameListConverter::class,
TagInfoListConverter::class)
TagInfoListConverter::class,
ActivityLabelListConverter::class)
abstract class HistoryDatabase : RoomDatabase() {
@ -113,6 +114,12 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_10_11: Migration = object : Migration(10, 11) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE GamesCollectionEntity add activityTags TEXT DEFAULT ''")
}
}
val instance by lazy {
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
.addMigrations(MIGRATION_2_3)
@ -123,6 +130,7 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_7_8)
.addMigrations(MIGRATION_8_9)
.addMigrations(MIGRATION_9_10)
.addMigrations(MIGRATION_10_11)
.build()
}
}

View File

@ -52,7 +52,6 @@ object HistoryHelper {
historyGame.iconSubscript = updateEntity.iconSubscript
historyGame.name = updateEntity.name
historyGame.tagStyle = updateEntity.tagStyle
historyGame.tag = updateEntity.tag
return historyGame
}
@ -161,6 +160,7 @@ object HistoryHelper {
gamesCollectionEntity.id = gamesCollectionDetailEntity.id
gamesCollectionEntity.tags = gamesCollectionDetailEntity.tags
gamesCollectionEntity.activityTags = gamesCollectionDetailEntity.activityTags
gamesCollectionDetailEntity.games?.take(3)?.map { it.toSimpleGame() }?.run {
gamesCollectionEntity.games = ArrayList(this)
}

View File

@ -4,7 +4,7 @@ import android.os.Parcelable
import androidx.annotation.Keep
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.util.*
@Keep

View File

@ -36,7 +36,14 @@ object LoghubHelper {
}
private fun createClient(logStore: String): LogProducerClient {
val config = LogProducerConfig(ENDPOINT, PROJECT, logStore, ACCESS_KEY_ID, ACCESS_KEY_SECRET).apply {
val config = LogProducerConfig(
HaloApp.getInstance().applicationContext,
ENDPOINT,
PROJECT,
logStore,
ACCESS_KEY_ID,
ACCESS_KEY_SECRET
).apply {
// 1 开启断点续传功能, 0 关闭
// 每次发送前会把日志保存到本地的binlog文件只有发送成功才会删除保证日志上传At Least Once
setPersistent(1)
@ -74,17 +81,25 @@ object LoghubHelper {
return if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
LogProducerClient(config)
} else {
return LogProducerClient(config,
LogProducerCallback { resultCode, reqId, errorMessage, logBytes, compressedBytes ->
// resultCode 返回结果代码
// reqId 请求id
// errorMessage 错误信息没有为null
// logBytes 日志大小
// compressedBytes 压缩后日志大小
Utils.log("LoghubHelper -> ${String.format("%s %s %s %s %s",
LogProducerResult.fromInt(resultCode), reqId, errorMessage, logBytes, compressedBytes)}")
})
LogProducerClient(config) { resultCode, reqId, errorMessage, logBytes, compressedBytes ->
// resultCode 返回结果代码
// reqId 请求id
// errorMessage 错误信息没有为null
// logBytes 日志大小
// compressedBytes 压缩后日志大小
Utils.log(
"LoghubHelper -> ${
String.format(
"%s %s %s %s %s",
LogProducerResult.fromInt(resultCode),
reqId,
errorMessage,
logBytes,
compressedBytes
)
}"
)
}
}
}
}

View File

@ -12,13 +12,15 @@ import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.view.ViewCompat
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.util.DisplayUtils
import com.gh.common.util.ImageUtils
import com.gh.common.util.doOnEnd
import com.gh.common.util.doOnStart
import com.gh.gamecenter.R
import kotlinx.android.synthetic.main.view_notifier.view.*
class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: FrameLayout(context, attrs, defStyle) {
@ -65,13 +67,21 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
var showVerticalTranslateAnimation: Boolean = true
private var mCardView: CardView
private var mContentTv: TextView
private var mIconIv: SimpleDraweeView
init {
inflate(context, R.layout.view_notifier, this)
ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat())
cardView.scaleX = SCALE_MINI
cardView.scaleY = SCALE_MINI
mCardView = findViewById(R.id.cardView)
mContentTv = findViewById(R.id.tvText)
mIconIv = findViewById(R.id.ivIcon)
mCardView.scaleX = SCALE_MINI
mCardView.scaleY = SCALE_MINI
verticalAnimationOffset = dp2px(100F)
@ -113,7 +123,7 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
expandAnimator.duration = DEFAULT_DURATION
expandAnimator.addUpdateListener { a ->
val progress = a?.animatedValue as Float
tvText.width = (textWidth * progress).toInt()
mContentTv.width = (textWidth * progress).toInt()
}
expandAnimator.doOnEnd {
enableSwipeToDismiss()
@ -124,46 +134,46 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
shrinkAnimator.duration = DEFAULT_DURATION
shrinkAnimator.addUpdateListener { a ->
val progress = a?.animatedValue as Float
tvText.width = (textWidth * progress).toInt()
mContentTv.width = (textWidth * progress).toInt()
}
shrinkAnimator.doOnEnd {
val lp = FrameLayout.LayoutParams(cardView.layoutParams)
val lp = FrameLayout.LayoutParams(mCardView.layoutParams)
lp.gravity = Gravity.NO_GRAVITY
cardView.layoutParams = lp
mCardView.layoutParams = lp
disableSwipeToDismiss()
}
translateToLeftAnimator = ObjectAnimator.ofFloat(cardView, "translationX", veryRight, centerX)
translateToLeftAnimator = ObjectAnimator.ofFloat(mCardView, "translationX", veryRight, centerX)
translateToLeftAnimator.duration = DEFAULT_DURATION
translateToLeftAnimator.doOnEnd {
onShowListener?.onShow()
val lp = FrameLayout.LayoutParams(cardView.layoutParams)
val lp = FrameLayout.LayoutParams(mCardView.layoutParams)
lp.gravity = Gravity.CENTER_HORIZONTAL
cardView.layoutParams = lp
cardView.translationX = 0f
mCardView.layoutParams = lp
mCardView.translationX = 0f
expandAnimator.start()
}
translateToRightAnimator = ObjectAnimator.ofFloat(cardView, "translationX", centerX, veryRight)
translateToRightAnimator = ObjectAnimator.ofFloat(mCardView, "translationX", centerX, veryRight)
translateToRightAnimator.duration = DEFAULT_DURATION
translateUpAnimator = ObjectAnimator.ofFloat(cardView, "translationY", veryBottom + verticalAnimationOffset, veryBottom)
translateUpAnimator = ObjectAnimator.ofFloat(mCardView, "translationY", veryBottom + verticalAnimationOffset, veryBottom)
translateUpAnimator.duration = DEFAULT_DURATION
translateUpAnimator.doOnStart { cardView.translationX = veryRight }
translateUpAnimator.doOnStart { mCardView.translationX = veryRight }
translateDownAnimator = ObjectAnimator.ofFloat(cardView, "translationY", veryBottom, veryBottom + verticalAnimationOffset)
translateDownAnimator = ObjectAnimator.ofFloat(mCardView, "translationY", veryBottom, veryBottom + verticalAnimationOffset)
translateDownAnimator.duration = DEFAULT_DURATION
zoomInAnimator = ObjectAnimator.ofPropertyValuesHolder(cardView, PropertyValuesHolder.ofFloat("scaleX", SCALE_DEFAULT),
zoomInAnimator = ObjectAnimator.ofPropertyValuesHolder(mCardView, PropertyValuesHolder.ofFloat("scaleX", SCALE_DEFAULT),
PropertyValuesHolder.ofFloat("scaleY", SCALE_DEFAULT))
zoomInAnimator.duration = DEFAULT_DURATION
zoomInAnimator.doOnStart { cardView.translationX = veryRight }
zoomInAnimator.doOnStart { cardView.translationY = veryBottom }
zoomInAnimator.doOnStart { mCardView.translationX = veryRight }
zoomInAnimator.doOnStart { mCardView.translationY = veryBottom }
zoomOutAnimator = ObjectAnimator.ofPropertyValuesHolder(cardView, PropertyValuesHolder.ofFloat("scaleX", SCALE_MINI),
zoomOutAnimator = ObjectAnimator.ofPropertyValuesHolder(mCardView, PropertyValuesHolder.ofFloat("scaleX", SCALE_MINI),
PropertyValuesHolder.ofFloat("scaleY", SCALE_MINI))
zoomOutAnimator.duration = DEFAULT_DURATION
zoomOutAnimator.doOnEnd { removeFromParent() }
@ -177,7 +187,7 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
}
private fun enableSwipeToDismiss() {
cardView?.setOnTouchListener(SwipeDismissTouchListener(cardView, object : SwipeDismissTouchListener.DismissCallbacks {
mCardView?.setOnTouchListener(SwipeDismissTouchListener(mCardView, object : SwipeDismissTouchListener.DismissCallbacks {
override fun canDismiss(): Boolean {
return true
}
@ -193,7 +203,7 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
}
private fun disableSwipeToDismiss() {
cardView?.setOnTouchListener(null)
mCardView?.setOnTouchListener(null)
}
override fun onDetachedFromWindow() {
@ -264,13 +274,13 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
fun setText(text: String?) {
if (!TextUtils.isEmpty(text)) {
tvText.text = text
tvText.measure(0, 0)
textWidth = tvText.measuredWidth
tvText.width = 0
mContentTv.text = text
mContentTv.measure(0, 0)
textWidth = mContentTv.measuredWidth
mContentTv.width = 0
cardView.measure(0, 0)
cardViewWidth = cardView.measuredWidth
mCardView.measure(0, 0)
cardViewWidth = mCardView.measuredWidth
}
}
@ -284,7 +294,7 @@ class NotifierView @JvmOverloads constructor(context: Context, attrs: AttributeS
}
fun setIcon(url: String) {
ImageUtils.display(ivIcon, url)
ImageUtils.display(mIconIv, url)
}
private fun dp2px(dp: Float): Int {

View File

@ -91,6 +91,9 @@ class SimulatorDownloadManager private constructor() {
DownloadStatus.unqualified == downloadEntity.status -> {
ToastUtils.showToast("未成年人暂不允许在此时间下载游戏")
}
DownloadStatus.unavailable == downloadEntity.status -> {
ToastUtils.showToast("该游戏未接入防沉迷系统,暂不支持下载")
}
DownloadStatus.hijack == downloadEntity.status -> {
ToastUtils.showToast("网络劫持,请稍后重试")
}

View File

@ -0,0 +1,125 @@
package com.gh.common.util
import androidx.annotation.Keep
import androidx.core.util.Pools
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.request.Postprocessor
class AsyncImageLoader private constructor() {
fun addAsyncImage(view: SimpleDraweeView?, url: String, isAutoPlayGif: Boolean, processor: Postprocessor?) {
try {
val loopThread = LoopThread.getInstance()
val params = loopThread.obtainImageParams()
params.view = view
params.url = url
params.isAutoPlayGif = isAutoPlayGif
params.processor = processor
loopThread.addAsyncImage(params)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
private class LoopThread private constructor() : Thread("GH_LOOP_IMAGE_LOADER") {
private var mIsLoop = false
private val mRetryCount = 3
private val mInterval = 10L
private val mImageList = ArrayList<ImageLoadParams>()
private val mImageListTemp = ArrayList<ImageLoadParams>()
private val mImagePool = Pools.SynchronizedPool<ImageLoadParams>(15)
init {
start()
}
@Synchronized
fun addAsyncImage(image: ImageLoadParams) {
if (mIsLoop) {
mImageListTemp.add(image)
} else {
mImageList.add(image)
}
}
override fun run() {
rxTimerWithIoThread(mInterval) {
try {
if (!mIsLoop) {
runInner()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
private fun runInner() {
if (mImageList.isEmpty()) return
mIsLoop = true
mImageList.forEach { image ->
val width = image.view?.width ?: 0
if (width == 0) {
if (image.retryCount >= mRetryCount) {
loadImage(image, true)
} else {
image.retryCount += 1
mImageListTemp.add(image)
}
} else {
if (image.view?.getTag(ImageUtils.TAG_TARGET_WIDTH) == null) {
image.view?.setTag(ImageUtils.TAG_TARGET_WIDTH, width)
}
loadImage(image)
}
}
mImageList.clear()
if (mImageListTemp.isNotEmpty()) {
mImageList.addAll(mImageListTemp)
mImageListTemp.clear()
}
mIsLoop = false
}
private fun loadImage(params: ImageLoadParams, isIgnoreWidth: Boolean = false) {
ImageUtils.display(params.view, params.url, params.isAutoPlayGif, params.processor, isIgnoreWidth)
releaseImageParams(params)
}
fun obtainImageParams(): ImageLoadParams {
var acquire = mImagePool.acquire()
if (acquire == null) {
acquire = ImageLoadParams()
}
return acquire
}
private fun releaseImageParams(params: ImageLoadParams) {
params.run {
view = null
url = ""
isAutoPlayGif = false
processor = null
retryCount = 0
mImagePool.release(this)
}
}
companion object : SingletonHolder<LoopThread>({ LoopThread() })
}
companion object : SingletonHolder<AsyncImageLoader>({ AsyncImageLoader() })
}
@Keep
data class ImageLoadParams(
var view: SimpleDraweeView? = null,
var url: String = "",
var isAutoPlayGif: Boolean = true,
var processor: Postprocessor? = null,
var retryCount: Int = 0
)

View File

@ -141,7 +141,7 @@ object CommentHelper {
val context = view.context
val dialogOptions = ArrayList<String>()
if (isShowTop && (articleId != null || questionId != null) && commentEntity.me?.isContentAuthor == true) {
if (isShowTop && (articleId != null || questionId != null || videoId != null) && commentEntity.me?.isContentAuthor == true) {
dialogOptions.add(if (commentEntity.isTop) "取消置顶" else "置顶")
}
if (questionId != null && commentEntity.me?.isContentAuthor == true) {
@ -158,9 +158,8 @@ object CommentHelper {
}
if (questionId != null &&
commentEntity.me?.isModerator == true &&
(commentEntity.me?.moderatorPermissions?.highlightAnswer
?: Permissions.GUEST) > Permissions.GUEST &&
!commentEntity.choiceness) {
(commentEntity.me?.moderatorPermissions?.highlightAnswer ?: Permissions.GUEST) > Permissions.GUEST && !commentEntity.choiceness
) {
dialogOptions.add("加精选")
}
if (questionId != null &&

View File

@ -3,16 +3,23 @@ package com.gh.common.util;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import androidx.annotation.RequiresApi;
import com.gh.common.AppExecutor;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.IdCardEntity;
import com.gh.gamecenter.entity.UserInfoEntity;
import com.gh.gamecenter.provider.GhContentProvider;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gid.GidCallback;
@ -24,7 +31,6 @@ import com.lightgame.utils.Utils;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid;
@ -42,11 +48,10 @@ public class DataUtils {
* @param channel
*/
public static void init(final Application context, String channel) {
if (CommonDebug.IS_DEBUG) {
return;
}
// 初始化 Sentry 约占用 90ms这里切换到子线程初始化
AppExecutor.getIoExecutor().execute(() -> initSentry(context, channel));
@ -118,23 +123,23 @@ public class DataUtils {
// }
}
private static void initSentry(Context context, String channel) {
SentryAndroid.init(context, options -> {
// Sentry 疯狂报 ANR (很大一部分还是莫名奇妙的 ANR)严重影响到其它闪退日志的收集
// 这里将它局限到只有官网渠道的包才统计 ANR
if ("GH_206".equals(channel)) {
if ("GH_206".equals(channel) || "GH_BETA".equals(channel)) {
options.setAnrEnabled(true);
options.setAnrTimeoutIntervalMillis(6000);
} else {
options.setAnrEnabled(false);
}
options.setDebug(BuildConfig.DEBUG);
options.setEnableSessionTracking(true);
options.setEnvironment(BuildConfig.FLAVOR);
options.setDsn("https://6b1caf0d17c1408e8680f3f73ff80bd0@sentry.shanqu.cc/22");
options.setBeforeSend((event, hint) -> {
if (BuildConfig.DEBUG) {
return null;
@ -143,7 +148,7 @@ public class DataUtils {
}
});
});
Sentry.configureScope(scope -> {
if (BuildConfig.BUILD_TIME != 0L) {
scope.setTag("alias", "内测版" + BuildConfig.VERSION_NAME);
@ -203,6 +208,22 @@ public class DataUtils {
@Override
public void onSuccess(UserInfoEntity data) {
SPUtils.setString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + gid, GsonUtils.toJson(data));
ContentValues values = new ContentValues();
IdCardEntity idCardEntity = data.getIdCard();
if (idCardEntity != null) {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, !TextUtils.isEmpty(data.getIdCard().getId())); // 是否认证
values.put(GhContentProvider.KEY_IS_ADULT,
data.getIdCard().getMinor() == null
|| !data.getIdCard().getMinor()
);
} else {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
values.put(GhContentProvider.KEY_IS_ADULT, false);
}
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/certification"), values);
}
});
}

View File

@ -200,6 +200,7 @@ public class DetailDownloadUtils {
case notfound:
case uncertificated:
case unqualified:
case unavailable:
detailInitDownload(viewHolder, false);
break;
default:

View File

@ -170,6 +170,8 @@ public class DeviceUtils {
}
public static String getNetwork(Context context) {
context = context.getApplicationContext();
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connManager == null) return null;
NetworkInfo info = connManager.getActiveNetworkInfo();

View File

@ -44,13 +44,9 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.AppExecutor;
@ -81,6 +77,7 @@ import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.Badge;
import com.gh.gamecenter.entity.BadgeEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.PermissionsEntity;
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SimpleGameEntity;
@ -101,6 +98,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
public class DialogUtils {
public static Dialog showWaitDialog(Context context, String msg) {
@ -846,7 +846,7 @@ public class DialogUtils {
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setBackgroundColor(Color.WHITE);
container.setBackgroundColor(ContextCompat.getColor(context, R.color.background_white));
container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f));
for (String option : options) {
@ -998,7 +998,10 @@ public class DialogUtils {
if (holder instanceof PrivacyPolicyItemViewHolder) {
PrivacyPolicyItemViewHolder viewHolder = (PrivacyPolicyItemViewHolder) holder;
PrivacyItemBinding binding = viewHolder.getBinding();
binding.setData(entity.getPermissions().get(position));
final PermissionsEntity permissionsEntity = entity.getPermissions().get(position);
ImageUtils.display(binding.icon, permissionsEntity.getIcon());
binding.name.setText(permissionsEntity.getName());
binding.intro.setText(permissionsEntity.getIntro());
GenericDraweeHierarchy hierarchy = binding.icon.getHierarchy();
if (hierarchy != null) {
if (position == 0) {
@ -1397,11 +1400,12 @@ public class DialogUtils {
} else {
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
DialogOverseaConfirmationBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.dialog_oversea_confirmation, null, false);
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
View contentView = binding.getRoot();
binding.setGame(gameEntity);
binding.gameIcon.displayGameIcon(gameEntity);
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
@ -1438,7 +1442,7 @@ public class DialogUtils {
params = window.getAttributes();
params.width = (int) (context.getResources().getDisplayMetrics().widthPixels * 0.9);
window.setAttributes(params);
window.setBackgroundDrawableResource(R.drawable.full_dialog_background);
window.setBackgroundDrawableResource(R.drawable.textview_white_up);
}
inflate.findViewById(R.id.imprint_close).setOnClickListener(v -> dialog.dismiss());
@ -1457,10 +1461,11 @@ public class DialogUtils {
continue;
}
View item = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
ImprintContentItemBinding bind = DataBindingUtil.bind(item);
bind.setApk(apk);
ImprintContentItemBinding bind = ImprintContentItemBinding.bind(item);
String platform = TextUtils.isEmpty(apk.getRemark()) ? apk.getPlatformName() : apk.getPlatformName() + "\n" + apk.getRemark();
bind.setPlatformName(platform);
bind.imprintPlatform.setText(platform);
bind.imprintVersion.setText(apk.getVersion());
bind.imprintTime.setText(NewsUtils.getFormattedTime(apk.getTime() != null ? apk.getTime() : 0));
content.addView(item, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(40));
}
@ -2213,7 +2218,7 @@ public class DialogUtils {
dialog.show();
}
public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener,CancelListener cancelListener) {
public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener, CancelListener cancelListener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);

View File

@ -19,6 +19,7 @@ import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureEvent.Companion.createEvent
import com.gh.common.exposure.ExposureManager.log
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
import com.gh.common.exposure.ExposureType
import com.gh.common.util.EntranceUtils.*
@ -51,6 +52,7 @@ import com.gh.gamecenter.personalhome.home.UserHistoryViewModel
import com.gh.gamecenter.qa.answer.detail.SimpleAnswerDetailActivity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
@ -157,7 +159,7 @@ object DirectUtils {
entrance: String,
path: String,
exposureEvent: ExposureEvent? = null,
unknownCallback: (() -> Unit)?
unknownCallback: (() -> Unit)?,
) {
when (linkEntity.type) {
"article", "news", "文章" -> {
@ -898,14 +900,14 @@ object DirectUtils {
*/
@JvmStatic
fun directToCommunityColumn(context: Context, community: CommunityEntity?, subjectId: String, entrance: String?, path: String?) {
// if (subjectId.isEmpty()) return
// val bundle = Bundle()
// bundle.putString(KEY_PATH, path)
// bundle.putString(KEY_TO, CommunitySubjectActivity::class.java.name)
// bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
// bundle.putString(KEY_COLUMN_ID, subjectId)
// bundle.putParcelable(KEY_COMMUNITY_DATA, community)
// jumpActivity(context, bundle)
if (subjectId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, CommunitySubjectActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
bundle.putString(KEY_COLUMN_ID, subjectId)
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
jumpActivity(context, bundle)
}
@JvmStatic
@ -1143,7 +1145,13 @@ object DirectUtils {
* 跳转新分类
*/
@JvmStatic
fun directCatalog(context: Context, catalogId: String, catalogTitle: String, entrance: String? = null, path: String? = "") {
fun directCatalog(
context: Context,
catalogId: String,
catalogTitle: String,
entrance: String? = null,
path: String? = "",
) {
if (catalogId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, CatalogActivity::class.java.name)
@ -1157,7 +1165,13 @@ object DirectUtils {
* 跳转新分类2.0
*/
@JvmStatic
fun directCategoryV2(context: Context, categoryId: String, categoryTitle: String, entrance: String? = null, path: String? = "") {
fun directCategoryV2(
context: Context,
categoryId: String,
categoryTitle: String,
entrance: String? = null,
path: String? = "",
) {
if (categoryId.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_TO, CategoryV2Activity::class.java.name)

View File

@ -18,13 +18,16 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import com.halo.assistant.HaloApp;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import androidx.core.content.ContextCompat;
public class DisplayUtils {
/**
@ -223,6 +226,27 @@ public class DisplayUtils {
}
}
public static void setStatusBarColor(Activity activity, @ColorRes int colorRes) {
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int colorInt = ContextCompat.getColor(activity, colorRes);
// 设置状态栏底色颜色
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(colorInt);
// 如果亮色,设置状态栏文字为黑色
if (isLightColor(colorInt)) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
}
private static boolean isLightColor(@ColorInt int color) {
return ColorUtils.calculateLuminance(color) >= 0.5;
}
private static boolean isMiuiOs() {
String property = getSystemProperty("ro.miui.ui.version.name", "");

View File

@ -166,6 +166,7 @@ object DownloadItemUtils {
hideDownloadBtnIfNoAvailableContent: Boolean = false,
pluginLocation: PluginLocation? = PluginLocation.only_game
) {
downloadBtn.background = R.drawable.download_button_normal_style.toDrawable(context)
// 控制是否显示下载按钮
downloadBtn.goneIf(!Config.isShowDownload(gameEntity.id) || context.getString(R.string.app_name) == gameEntity.name)
// 青少年模式显示查看
@ -208,7 +209,7 @@ object DownloadItemUtils {
} else {
text = context.getString(R.string.none)
setTextColor(R.color.button_gray.toColor())
setBackgroundResource(R.drawable.news_detail_comment)
setBackgroundResource(R.drawable.button_border_gray_oval)
if (hideDownloadBtnIfNoAvailableContent) {
visibility = View.GONE
}
@ -418,6 +419,7 @@ object DownloadItemUtils {
holder.recommendTv.text = recommendStyle.text
if (TextUtils.isEmpty(recommendStyle.icon)) {
holder.recommendIv.visibility = View.GONE
holder.recommendContainer?.setPadding(6F.dip2px(), 0, 8F.dip2px(), 0)
} else {
holder.recommendIv.visibility = View.VISIBLE
ImageUtils.display(holder.recommendIv, recommendStyle.icon)

View File

@ -112,6 +112,7 @@ object DownloadNotificationHelper {
|| entity.status == DownloadStatus.cancel
|| entity.status == DownloadStatus.hijack
|| entity.status == DownloadStatus.unqualified
|| entity.status == DownloadStatus.unavailable
|| entity.status == DownloadStatus.uncertificated
|| entity.status == DownloadStatus.notfound
|| entity.status == DownloadStatus.overflow
@ -186,6 +187,6 @@ object DownloadNotificationHelper {
}
private fun getNotificationIcon(): Int {
return if (mShouldUseAlternativeNotificationIcon) R.drawable.ic_notification else R.mipmap.logo
return if (mShouldUseAlternativeNotificationIcon) R.drawable.ic_download_notification else R.mipmap.logo
}
}

View File

@ -36,7 +36,6 @@ import okhttp3.MediaType
import okhttp3.RequestBody
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
import java.util.*
object DownloadObserver {
@ -109,6 +108,20 @@ object DownloadObserver {
// 未成年
RealNameHelper.showRealNameUnqualifiedDialog(downloadEntity)
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
} else if (DownloadStatus.unavailable == downloadEntity.status) {
// 未接入防沉迷系统
val currentActivity = AppManager.getInstance().currentActivity() ?: return
DialogHelper.showDialog(
context = currentActivity,
title = "温馨提示",
content = "该游戏未接入防沉迷系统,暂不支持下载",
confirmText = "知道了",
cancelText = "")
// 删除任务
downloadEntity.status = DownloadStatus.cancel
downloadManager.cancel(downloadEntity.url)
@ -175,6 +188,8 @@ object DownloadObserver {
} else {
statDoneEvent(downloadEntity)
GameActivityDownloadHelper.clear()
EnergyTaskHelper.postEnergyTask(
"download_game",
downloadEntity.gameId,

View File

@ -47,6 +47,7 @@ public class EntranceUtils {
public static final String KEY_GAMENAME = "gameName";
public static final String KEY_PACKAGE_MD5 = "package_md5";
public static final String HOST_ARTICLE = "article";
public static final String HOST_INVOKE_ONLY = "invoke_only";
public static final String HOST_UPLOAD_VIDEO = "upload_video";//上传视频
public static final String HOST_UPLOAD_VIDEO_NEW = "upload_video_new"; // 上传视频新(AKA 发视频)
public static final String HOST_VIDEO_SINGLE = "video_single";//指定视频-不能划动
@ -264,6 +265,8 @@ public class EntranceUtils {
public static final String KEY_GAME_COLLECTION_ID = "game_collection_id";//游戏单ID
public static final String KEY_ASSIST_RES = "assist_res";
public static final String KEY_LAST_SELECTED_POSITION = "last_selected_position";
public static final String KEY_RECOMMEND_ID = "recommend_id";
public static final String KEY_LAST_PAGE_DATA = "last_page_data";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);

View File

@ -1,6 +1,7 @@
package com.gh.common.util
import android.animation.Animator
import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
@ -20,11 +21,13 @@ import android.util.Log
import android.util.TypedValue
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.webkit.WebView
import android.widget.EditText
import android.widget.PopupWindow
import android.widget.SeekBar
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
@ -34,6 +37,8 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import androidx.viewpager.widget.ViewPager
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
import com.airbnb.lottie.LottieAnimationView
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.DefaultUrlHandler
@ -753,7 +758,7 @@ fun <T> Array<out T>.secondOrNull(): T? {
fun ExpandTextView.setTextWithInterceptingInternalUrl(
shrankText: CharSequence,
expandedText: CharSequence,
clickedCallback: (url: String)-> Unit
clickedCallback: (url: String) -> Unit
) {
var shrankSsb = shrankText.interceptUrlSpanAndRoundImageSpan(clickedCallback)
var expandedSsb = expandedText.interceptUrlSpanAndRoundImageSpan(clickedCallback)
@ -881,10 +886,24 @@ fun Int.toColor(): Int {
return ContextCompat.getColor(HaloApp.getInstance().application, this)
}
/**
* 只能传Activity的context如果是Application的context会导致切换夜间模式变不了色
*/
fun Int.toColor(context: Context): Int {
return ContextCompat.getColor(context, this)
}
fun Int.toDrawable(): Drawable? {
return ContextCompat.getDrawable(HaloApp.getInstance().application, this)
}
/**
* 只能传Activity的context如果是Application的context会导致切换夜间模式变不了色
*/
fun Int.toDrawable(context: Context): Drawable? {
return ContextCompat.getDrawable(context, this)
}
fun Int.toResString(): String {
return HaloApp.getInstance().application.resources.getString(this)
}
@ -1047,6 +1066,13 @@ inline fun rxTimer(interval: Long, crossinline block: (times: Long) -> Unit): Di
}
}
inline fun rxTimerWithIoThread(interval: Long, crossinline block: (times: Long) -> Unit): Disposable {
return Observable.interval(0, interval, TimeUnit.MILLISECONDS)
.subscribe {
block.invoke(it)
}
}
fun LottieAnimationView.doOnAnimationEnd(action: () -> Unit) {
this.addAnimatorListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
@ -1165,6 +1191,20 @@ fun View.getBitmapFromView(): Bitmap? {
return bitmap
}
fun View.setRootBackgroundColor(@ColorRes res: Int) {
if (this.id == View.NO_ID) {
this.id = R.id.root_container
}
this.setBackgroundColor(res.toColor(this.context))
}
fun View.setRootBackgroundDrawable(@DrawableRes res: Int) {
if (this.id == View.NO_ID) {
this.id = R.id.root_container
}
this.background = res.toDrawable(this.context)
}
fun String.hexStringToIntColor(): Int {
val colorStr = if (this.length == 9) {
"#${this.substring(3)}"
@ -1187,4 +1227,25 @@ fun String.lengthOfEmojiHalf(): Int {
fun String.emojiCount(): Int {
val onlyText = EmojiUtils.removeEmoji(this)
return (this.length - onlyText.length) / 2
}
/**
* WebView启用强制深色模式
*/
fun WebView.enableForceDark(nightMode: Boolean) {
if (BuildConfig.IS_NIGHT_MODE_ON && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(settings, if (nightMode) WebSettingsCompat.FORCE_DARK_ON else WebSettingsCompat.FORCE_DARK_OFF)
}
}
/**
* 日夜间模式切换更新状态栏底色
*/
fun Activity.updateStatusBarColor(@ColorRes nightColor: Int, @ColorRes dayColor: Int) {
if (BuildConfig.IS_NIGHT_MODE_ON) {
DisplayUtils.setStatusBarColor(
this,
if (NightModeUtils.isNightMode(this)) nightColor else dayColor
)
}
}

View File

@ -0,0 +1,413 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.DefaultJsApi
import com.gh.common.constant.Constants
import com.gh.common.dialog.CertificationDialog
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureManager
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureType
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
import com.gh.common.runOnUiThread
import com.gh.common.view.dsbridge.CompletionHandler
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.PluginLocation
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.EmptyResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.gamecenter.user.ApiResponse
import com.lightgame.download.FileUtils
/**
* 游戏活动下载辅助类
*/
object GameActivityDownloadHelper {
private var mTraceEvent: ExposureEvent? = null
private var mGameEntity: GameEntity? = null
fun start(context: Context, event: DefaultJsApi.GameActivityEvent) {
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
runOnUiThread {
handleGameEntity(context, event, mGameEntity!!)
}
} else {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
gameEntity?.let {
handleGameEntity(context, event, it)
}
}
})
}
}
private fun handleGameEntity(
context: Context,
event: DefaultJsApi.GameActivityEvent,
gameEntity: GameEntity
) {
// 青少年模式
if (isTeenageMode(context)) return
val entrance = "(游戏活动[${event.activityTitle}])"
val location = "游戏活动:${event.activityTitle}-${gameEntity.name}"
if (mTraceEvent == null) {
val exposureSources = arrayListOf(
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
)
mTraceEvent = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
}
mTraceEvent?.run {
when {
// 预约
gameEntity.isReservable -> reserve(context, gameEntity, entrance, this)
// 开始玩
gameEntity.getApk().size == 0 && gameEntity.h5Link != null -> play(context, gameEntity)
// 下载
else -> handleDownload(context, event, gameEntity, entrance, location, this)
}
}
}
// 青少年模式
private fun isTeenageMode(context: Context): Boolean {
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
DialogHelper.showDialog(
context,
"提示",
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{ context.startActivity(TeenagerModeActivity.getIntent(context)) },
{},
DialogHelper.Config(
centerTitle = true,
centerContent = true
)
)
return true
}
return false
}
// 预约
private fun reserve(
context: Context,
gameEntity: GameEntity,
entrance: String,
traceEvent: ExposureEvent
) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
CheckLoginUtils.checkLogin(context, entrance) {
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
clear()
}
})
}
} else {
ToastUtils.toast("游戏已成功预约")
}
}
// 开始玩(H5链接)
private fun play(context: Context, gameEntity: GameEntity) {
val linkEntity = gameEntity.h5Link
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
if (isPlay) {
HistoryHelper.insertGameEntity(gameEntity)
}
val i = WebActivity.getIntentForWebGame(
context,
gameEntity.h5Link!!.link,
gameEntity.name,
isPlay,
linkEntity.closeButton
)
context.startActivity(i)
}
// 下载
private fun handleDownload(
context: Context,
event: DefaultJsApi.GameActivityEvent,
gameEntity: GameEntity,
entrance: String,
location: String,
traceEvent: ExposureEvent
) {
val apk = getApk(gameEntity, event, true) ?: return
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apk.url)
if (downloadEntity != null) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game)
if (str == context.getString(R.string.download)) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
}
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.attempt)) {
RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback {
override fun onCallback() {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
}
}
})
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str.contains("")) {
if (gameEntity.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
}
} else if (str == context.getString(R.string.install) || str == context.getString(R.string.launch)) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else if (str == context.getString(R.string.update)) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
}
}
private fun getApk(
gameEntity: GameEntity,
event: DefaultJsApi.GameActivityEvent,
isRemoveOther: Boolean
): ApkEntity? {
return when {
gameEntity.getApk().isEmpty() -> null
gameEntity.getApk().size == 1 -> gameEntity.getApk()[0]
// 找出对应平台版本Apk且移除掉其他平台版本Apk
isRemoveOther -> {
// 当前游戏为多版本时,只保留活动指定的版本即可,方便之后判断
var apk: ApkEntity? = null
val iterator = gameEntity.getApk().iterator()
while (iterator.hasNext()) {
val tempApk = iterator.next()
if (tempApk.getPlatform() == event.platform) {
apk = tempApk
} else {
iterator.remove()
}
}
apk
}
// 找出对应平台版本Apk即可
else -> {
var apk: ApkEntity? = null
run outside@{
gameEntity.getApk().forEach {
if (it.getPlatform() == event.platform) {
apk = it
return@outside
}
}
}
apk
}
}
}
private fun download(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
isSubscribe: Boolean,
entrance: String,
location: String,
traceEvent: ExposureEvent
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DataUtils.onGameDownloadEvent(context, gameEntity.name, apk.getPlatform(), entrance, "下载开始", "下载")
DownloadManager.createDownload(context, apk, gameEntity, context.getString(
R.string.download), entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
ToastUtils.toast(msg)
}
}
// 插件化
private fun plugin(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
entrance: String,
location: String,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DataUtils.onGameDownloadEvent(context, gameEntity.name, apk.getPlatform(), entrance, "下载开始", "插件化")
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
ToastUtils.toast(msg)
}
}
// 更新
private fun update(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
entrance: String,
location: String,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
DataUtils.onGameUpdateEvent(context, gameEntity.name, apk.getPlatform(), "下载开始")
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
}
@SuppressLint("CheckResult")
fun postTaskComplete(gameId: String) {
val api = RetrofitManager.getInstance().newApi
val single = if (UserManager.getInstance().isLoggedIn) {
api.postGameActivityTask(gameId)
} else {
api.postGameActivityTaskForNoLogin(gameId)
}
single.compose(singleToMain()).subscribe(EmptyResponse())
}
// 判断是否完成任务(预约完成或者已安装且无更新)
@SuppressLint("CheckResult")
fun checkTaskComplete(
context: Context,
event: DefaultJsApi.GameActivityEvent,
handler: CompletionHandler<Any>
) {
// 预约完成
if (ReservationRepository.thisGameHasBeenReserved(event.gameId)) {
postTaskComplete(event.gameId)
handler.complete(true)
return
}
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
handleCheckTaskComplete(context, mGameEntity, event, handler)
} else {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
handleCheckTaskComplete(context, gameEntity, event, handler)
}
override fun onApiFailure(e: ApiResponse<GameEntity>?) {
super.onApiFailure(e)
handler.complete(false)
}
})
}
}
private fun handleCheckTaskComplete(
context: Context,
gameEntity: GameEntity?,
event: DefaultJsApi.GameActivityEvent,
handler: CompletionHandler<Any>
) {
if (gameEntity == null) {
handler.complete(false)
} else {
val apk = getApk(gameEntity, event, false)
if (apk == null) {
handler.complete(false)
} else {
// 已安装
if (PackageUtils.isInstalled(context, apk.packageName)) {
// 是否可更新
if (PackageUtils.isCanUpdate(apk, event.gameId)
|| PackageUtils.isNonPluginUpdatable(apk, gameEntity)) {
handler.complete(false)
} else {
// 已安装且无更新
postTaskComplete(event.gameId)
handler.complete(true)
}
} else {
handler.complete(false)
}
}
}
}
fun postExposureEvent(event: DefaultJsApi.GameActivityEvent) {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
gameEntity?.let {
val exposureSources = arrayListOf(
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
)
mTraceEvent = ExposureEvent.createEvent(
gameEntity,
exposureSources,
null,
ExposureType.EXPOSURE
)
mTraceEvent?.run { ExposureManager.log(this) }
}
}
})
}
fun clear() {
mTraceEvent = null
mGameEntity = null
}
}

View File

@ -118,10 +118,9 @@ public class GameUtils {
if (PackagesManager.INSTANCE.isCanUpdate(gameEntity.getId(), apkEntity.getPackageName())) {
updateCount++;
}
if (PackagesManager.INSTANCE.isInstalled(apkEntity.getPackageName())) {
if (PackagesManager.isInstalled(apkEntity.getPackageName())) {
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
if (gameEntity.getTag() != null && gameEntity.getTag().size() != 0
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
if (!TextUtils.isEmpty(apkEntity.getGhVersion())
&& !PackageUtils.isSignedByGh(context, apkEntity.getPackageName())
&& apkEntity.isShowPlugin(pluginLocation)) {
pluginCount++;
@ -231,7 +230,6 @@ public class GameUtils {
gameUpdateEntity.setPlatform(apkEntity.getPlatform());
gameUpdateEntity.setEtag(apkEntity.getEtag());
gameUpdateEntity.setPluggable(true);
gameUpdateEntity.setTag(gameEntity.getTag());
gameUpdateEntity.setTagStyle(gameEntity.getTagStyle());
gameUpdateEntity.setBrief(gameEntity.getBrief());
gameUpdateEntity.setPlugin(apkEntity.getPlugin());

View File

@ -32,6 +32,7 @@ import com.gh.common.structure.FixedSizeLinkedHashSet
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import com.squareup.picasso.LruCache
import com.squareup.picasso.Picasso
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
@ -60,6 +61,13 @@ object ImageUtils {
)
}
@JvmStatic
val picasso: Picasso by lazy {
// Picasso 的 Lru 缓存改为 5M默认设定是 1/7 的 heap 大小,太大了
// https://stackoverflow.com/a/20105828/4812571
Picasso.Builder(HaloApp.getInstance()).memoryCache(LruCache(5 * 1024 * 1024)).build()
}
/**
* 禁用动图,全局设置
*/
@ -393,9 +401,10 @@ object ImageUtils {
view: SimpleDraweeView?,
url: String?,
isAutoPlayGif: Boolean = true,
processor: Postprocessor? = null
processor: Postprocessor? = null,
isIgnoreWidth: Boolean = false
) {
displayInternal(view, url, isAutoPlayGif, processor)
displayInternal(view, url, isAutoPlayGif, processor, isIgnoreWidth)
}
@JvmStatic
@ -403,7 +412,8 @@ object ImageUtils {
view: SimpleDraweeView?,
url: String?,
isAutoPlayGif: Boolean = true,
processor: Postprocessor? = null
processor: Postprocessor? = null,
isIgnoreWidth: Boolean = false
) {
mImageDecorationThread.execute {
if (url.isNullOrEmpty()) return@execute
@ -414,6 +424,10 @@ object ImageUtils {
val height = view?.layoutParams?.height
val shouldNotSaveMemoryCache = view?.getTag(TAG_NO_MEMORY_CACHE) == true
if (view != null && width == 0 && !isIgnoreWidth) {
AsyncImageLoader.getInstance().addAsyncImage(view, url, isAutoPlayGif, processor)
return@execute
}
var lowResUrl = ""
var highResUrl = ""
@ -471,12 +485,12 @@ object ImageUtils {
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
} else {
if (width != null && width > 0) {
highResUrl = resizeGif(url, view!!.width, height ?: 0)
highResUrl = resizeGif(url, width, height ?: 0)
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
} else {
runOnUiThread {
view ?: return@runOnUiThread
highResUrl = resizeGif(url, view.width, height ?: 0)
highResUrl = resizeGif(url, width ?: view.width, height ?: 0)
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
}
}

View File

@ -58,7 +58,7 @@ public class IntentUtils {
"\n" +
"光环助手官网地址:\n" +
"\n" +
"http://www.ghzs.com/link?source=appshare333");
"https://www.ghzs.com/link?source=appshare333");
return data;
}

View File

@ -20,6 +20,7 @@ public class NetworkUtils {
*/
public static boolean isNetworkConnected(Context context) {
if (context != null) {
context = context.getApplicationContext();
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager
@ -39,6 +40,7 @@ public class NetworkUtils {
*/
public static boolean isWifiConnected(Context context) {
if (context != null) {
context = context.getApplicationContext();
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
@ -108,6 +110,7 @@ public class NetworkUtils {
*/
public static String getConnectedType(Context context) {
if (context != null) {
context = context.getApplicationContext();
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager

View File

@ -5,6 +5,7 @@ import com.gh.common.json.JsonObjectBuilder
import com.gh.common.json.json
import com.gh.common.loghub.LoghubUtils
import com.gh.common.tracker.Tracker
import com.gh.gamecenter.entity.AdditionalParamsEntity
import com.gh.gamecenter.entity.LinkEntity
import com.gh.gamecenter.entity.QuoteCountEntity
import com.gh.gamecenter.entity.WechatConfigEntity
@ -50,15 +51,17 @@ object NewLogUtils {
}
@SuppressLint("CheckResult")
fun logForumContentBrowser(contentId: String, contentType: String) {
val requestBody = hashMapOf(
Pair("content_id", contentId),
Pair("content_type", contentType)
).createRequestBody()
fun logForumContentBrowser(contentId: String, contentType: String, recommendId: String) {
val requestMap = hashMapOf<String, Any>()
requestMap["content_id"] = contentId
requestMap["content_type"] = contentType
if (recommendId.isNotBlank()) {
requestMap["recommend_id"] = recommendId
}
RetrofitManager.getInstance()
.api
.postBrowses(requestBody)
.postBrowses(requestMap.toRequestBody())
.subscribeOn(Schedulers.io())
.subscribe(EmptyResponse<ResponseBody>())
}
@ -569,12 +572,21 @@ object NewLogUtils {
//分享结果
@JvmStatic
fun logShareResult(shareResult: Boolean) {
fun logShareResult(additionalParams: AdditionalParamsEntity? = null, shareResult: Boolean) {
val json = json {
"location" to "分享面板"
"event" to "share_result"
"meta" to LogUtils.getMetaObject()
"share_success" to shareResult
additionalParams?.let {
"content_type" to it.contentType
"content_id" to it.contentId
"bbs_id" to it.bbsId
"bbs_type" to it.bbsType
"ref_user_id" to it.refUserId
}
"launch_id" to Tracker.launchId
"session_id" to Tracker.sessionId
"timestamp" to System.currentTimeMillis() / 1000
@ -1897,7 +1909,7 @@ object NewLogUtils {
//默认封面点击事件
@JvmStatic
fun logClickGameCollectionDefaultCoverDialog(action: String){
fun logClickGameCollectionDefaultCoverDialog(action: String) {
val json = json {
"event" to "click_dialog_game_collect_chose_default_picture"
"action" to action

View File

@ -0,0 +1,61 @@
package com.gh.common.util
import android.content.Context
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatDelegate
import com.gh.common.constant.Constants
import com.gh.gamecenter.BuildConfig
object NightModeUtils {
/**
* 当前系统是否是深色模式
*/
fun isNightMode(context: Context): Boolean {
// 仅配置开启的包才提供夜间模式功能
return if (BuildConfig.IS_NIGHT_MODE_ON) {
val uiMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
uiMode == Configuration.UI_MODE_NIGHT_YES
} else {
false
}
}
/**
* 获取是否跟随系统默认true
*/
fun getSystemMode() = SPUtils.getBoolean(Constants.SP_SYSTEM_MODE, true)
fun setSystemMode(nightMode: Boolean) = SPUtils.setBoolean(Constants.SP_SYSTEM_MODE, nightMode)
/**
* 获取是否设置深色模式默认false
*/
fun getNightMode() = SPUtils.getBoolean(Constants.SP_NIGHT_MODE, false)
fun setNightMode(nightMode: Boolean) = SPUtils.setBoolean(Constants.SP_NIGHT_MODE, nightMode)
fun initNightMode() {
initNightMode(getSystemMode(), getNightMode())
}
/**
* 初始化App深色模式
*
* @param systemMode 是否是跟随系统
* @param nightMode 是否是深色模式
*/
fun initNightMode(systemMode: Boolean, nightMode: Boolean) {
// 仅配置开启的包才提供夜间模式功能
if (BuildConfig.IS_NIGHT_MODE_ON) {
if (systemMode) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
} else {
if (nightMode) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
}
}
}
}

View File

@ -1,6 +1,7 @@
package com.gh.common.util
import java.text.DecimalFormat
import kotlin.math.roundToInt
object NumberUtils {
@ -45,8 +46,8 @@ object NumberUtils {
fun transSimpleUsageTime(second: Long): String {
val totalMinute = second / 60
if (totalMinute < 60) return ((if (totalMinute == 0L) 1 else totalMinute).toString() + "分钟")
val hour = Math.round((totalMinute / 60).toFloat())
val minute = Math.round((totalMinute - hour * 60).toFloat())
val hour = (totalMinute / 60).toFloat().roundToInt()
val minute = (totalMinute - hour * 60).toFloat().roundToInt()
return hour.toString() + "小时" + if (minute == 0) "" else minute.toString() + "分钟"
}

View File

@ -15,7 +15,7 @@ object OptionDialogHelper {
val dialog = Dialog(context)
val container = LinearLayout(context)
container.orientation = LinearLayout.VERTICAL
container.setBackgroundColor(Color.WHITE)
container.setBackgroundColor(R.color.background_white.toColor(context))
container.setPadding(0, DisplayUtils.dip2px(context, 12f), 0, DisplayUtils.dip2px(context, 12f))
for (type in typeList) {

View File

@ -53,15 +53,23 @@ object PackageInstaller {
// TODO 此处可能遇到 activity 是 WXEntryActivity
// TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装!
if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) {
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) {
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { isFromPermissionGrantedCallback ->
// 取消状态栏下载完成的通知,若存在
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
if (isXapk) {
XapkInstaller.install(context, downloadEntity, showUnzipToast)
if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= 31) {
val pm = context.packageManager
val intent = pm.getLaunchIntentForPackage(context.packageName)
val mainIntent = Intent.makeRestartActivityTask(intent!!.component)
context.startActivity(mainIntent)
Runtime.getRuntime().exit(0)
} else {
install(context, downloadEntity.isPlugin, downloadEntity.path)
if (isXapk) {
XapkInstaller.install(context, downloadEntity, showUnzipToast)
} else {
install(context, downloadEntity.isPlugin, downloadEntity.path)
}
}
}
}

View File

@ -82,7 +82,6 @@ public class PackageUtils {
updateEntity.setPlatform(apkEntity.getPlatform());
updateEntity.setEtag(apkEntity.getEtag());
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateEntity.setTagStyle(gameEntity.getTagStyle());
updateEntity.setDownload(gameEntity.getDownload());
updateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
@ -131,7 +130,6 @@ public class PackageUtils {
updateEntity.setPlatform(apkEntity.getPlatform());
updateEntity.setEtag(apkEntity.getEtag());
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateEntity.setTagStyle(gameEntity.getTagStyle());
updateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
updateEntity.setPluginDesc(gameEntity.getPluginDesc());
@ -741,7 +739,6 @@ public class PackageUtils {
updateEntity.setPlatform(apkEntity.getPlatform());
updateEntity.setEtag(apkEntity.getEtag());
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateEntity.setTagStyle(gameEntity.getTagStyle());
updateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
updateEntity.setPluginDesc(gameEntity.getPluginDesc());

View File

@ -34,7 +34,7 @@ public class PicassoImageGetter implements Html.ImageGetter {
BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();
Context context = HaloApp.getInstance().getApplication();
Picasso.with(context)
ImageUtils.getPicasso()
.load(source)
.transform(new CircleTransformation())
.placeholder(ResourcesCompat.getDrawable(context.getResources(), R.drawable.personal_user_default_icon, context

View File

@ -151,6 +151,43 @@ public class PostCommentUtils {
});
}
public static void unLikeComment(
String articleId,
String articleCommunityId,
String videoId,
String questionId,
final String commentId,
final PostCommentListener listener) {
Observable<ResponseBody> observable;
if (!TextUtils.isEmpty(questionId)) {
observable = RetrofitManager.getInstance().getApi().postUnVoteQuestionComment(questionId, commentId);
} else if (!TextUtils.isEmpty(articleCommunityId) && !TextUtils.isEmpty(articleId)) {
observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(articleCommunityId, articleId, commentId);
} else {
observable = RetrofitManager.getInstance().getApi().postUnVoteVideoComment(videoId, commentId);
}
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
if (listener != null) {
listener.postSuccess(null);
}
}
@Override
public void onFailure(HttpException e) {
if (listener != null) {
listener.postFailed(e);
}
}
});
}
public static void addCommentVote(final String commentId,
final PostCommentListener listener) {
RetrofitManager.getInstance().getApi()
@ -260,10 +297,11 @@ public class PostCommentUtils {
}
});
}
public static void reportQuestionComment(final String questionId,
final String commentId,
final String reportData,
final PostCommentListener listener) {
final String commentId,
final String reportData,
final PostCommentListener listener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData);
RetrofitManager.getInstance().getApi()
.postQuestionCommentReport(questionId, commentId, body)

View File

@ -28,6 +28,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WeiBoShareActivity;
import com.gh.gamecenter.entity.AdditionalParamsEntity;
import com.gh.gamecenter.entity.ShareEntity;
import com.gh.gamecenter.eventbus.EBShare;
import com.lightgame.utils.Utils;
@ -129,6 +130,7 @@ public class ShareUtils {
public static String resourceId = "";//分享内容的id(事件上报用)
public static ShareEntity shareEntity;//分享信息(事件上报用)
private static ShareType mShareType;//分享类型(事件上报用)
public static AdditionalParamsEntity additionalParams;//附加参数(事件上报用)
private WeakReference<Activity> mActivity;
@ -148,7 +150,7 @@ public class ShareUtils {
if (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal ||
ShareUtils.shareEntrance == ShareEntrance.communityArticle ||
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video) {
NewLogUtils.logShareResult(true);
NewLogUtils.logShareResult(ShareUtils.additionalParams, true);
} else if (ShareUtils.shareEntrance == ShareEntrance.gameCollection) {
String shareType;
if (mShareType == ShareType.qq) {
@ -176,7 +178,7 @@ public class ShareUtils {
if (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal ||
ShareUtils.shareEntrance == ShareEntrance.communityArticle ||
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video) {
NewLogUtils.logShareResult(false);
NewLogUtils.logShareResult(ShareUtils.additionalParams, false);
}
}
@ -191,7 +193,7 @@ public class ShareUtils {
if (ShareUtils.shareEntrance == ShareUtils.ShareEntrance.askNormal ||
ShareUtils.shareEntrance == ShareEntrance.communityArticle ||
ShareUtils.shareEntrance == ShareUtils.ShareEntrance.video) {
NewLogUtils.logShareResult(false);
NewLogUtils.logShareResult(ShareUtils.additionalParams, false);
}
}
@ -232,7 +234,7 @@ public class ShareUtils {
public void shareInviteFriends(Activity activity, String url, String way) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = activity.getString(R.string.gh_icon_url);
this.shareIcon = getHttpsUrl(activity.getString(R.string.gh_icon_url));
this.shareUrl = url;
this.mSummary = "卡牌神器,海量游戏下载,积分大礼,等你尝鲜";
this.mTitle = "推荐一款好玩的游戏下载APP【光环助手】";
@ -270,7 +272,7 @@ public class ShareUtils {
public void showShareUserHomeWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
this.shareIcon = getHttpsUrl(icon);
this.shareUrl = url;
this.mSummary = shareSummary;
this.mTitle = shareTitle;
@ -331,7 +333,7 @@ public class ShareUtils {
public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
this.shareIcon = getHttpsUrl(icon);
this.shareUrl = url;
this.mSummary = shareSummary;
this.mTitle = shareTitle;
@ -416,14 +418,19 @@ public class ShareUtils {
});
}
public void shareParamsDetail(Activity activity, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
public void shareParamsDetail(Activity activity, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id) {
shareParamsDetail(activity, url, icon, shareTitle, shareSummary, shareEntrance, id, null);
}
public void shareParamsDetail(Activity activity, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, AdditionalParamsEntity params) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
this.shareIcon = getHttpsUrl(icon);
this.shareUrl = url;
this.mSummary = shareSummary;
this.mTitle = shareTitle;
this.mShareEntrance = shareEntrance;
ShareUtils.additionalParams = params;
ShareUtils.shareEntrance = mShareEntrance;
ShareUtils.resourceId = id;
ShareUtils.shareEntity = new ShareEntity(shareUrl, mTitle, mSummary);
@ -888,6 +895,13 @@ public class ShareUtils {
}
}
private String getHttpsUrl(String url) {
if (url.startsWith("http://")) {
return url.replace("http://", "https://");
}
return url;
}
interface OnItemClickListener {
void onItemClick(int position);
}

View File

@ -38,23 +38,23 @@ public class UserIconUtils {
public static String getUserIconUrl(int i) {
switch (i) {
case 1:
return "http://image.ghzs666.com/pic/default_icon_1.png";
return "https://image.ghzs666.com/pic/default_icon_1.png";
case 2:
return "http://image.ghzs666.com/pic/default_icon_2.png";
return "https://image.ghzs666.com/pic/default_icon_2.png";
case 3:
return "http://image.ghzs666.com/pic/default_icon_3.png";
return "https://image.ghzs666.com/pic/default_icon_3.png";
case 4:
return "http://image.ghzs666.com/pic/default_icon_4.png";
return "https://image.ghzs666.com/pic/default_icon_4.png";
case 5:
return "http://image.ghzs666.com/pic/default_icon_5.png";
return "https://image.ghzs666.com/pic/default_icon_5.png";
case 6:
return "http://image.ghzs666.com/pic/default_icon_6.png";
return "https://image.ghzs666.com/pic/default_icon_6.png";
case 7:
return "http://image.ghzs666.com/pic/default_icon_7.png";
return "https://image.ghzs666.com/pic/default_icon_7.png";
case 8:
return "http://image.ghzs666.com/pic/default_icon_8.png";
return "https://image.ghzs666.com/pic/default_icon_8.png";
default:
return "http://image.ghzs666.com/pic/default_icon_1.png";
return "https://image.ghzs666.com/pic/default_icon_1.png";
}
}
}

View File

@ -4,7 +4,7 @@ import android.os.Parcelable
import androidx.annotation.Keep
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.util.*
@Keep

View File

@ -10,6 +10,7 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import com.gh.common.util.toColor
import com.gh.common.util.visibleIf
@ -74,13 +75,23 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
mOnCatalogFilterSetupListener = onCatalogFilterSetupListener
}
fun setRootBackgroundColor(@ColorInt color: Int) {
findViewById<View>(R.id.config_controller).setBackgroundColor(color)
}
fun setItemTextColor(@ColorInt color: Int) {
mTypeTv.setTextColor(color)
mCatalogTv.setTextColor(color)
mSizeTv.setTextColor(color)
}
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
if (highlightIt) {
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
targetTextView.setTextColor(Color.WHITE)
} else {
targetTextView.background = null
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
targetTextView.setTextColor(R.color.text_757575.toColor(context))
}
}
@ -90,7 +101,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
typeTv.setTextColor(R.color.theme_font.toColor())
typeTv.setTextColor(R.color.theme_font.toColor(context))
typeTv.setCompoundDrawables(null, null, drawableUp, null)
val inflater = LayoutInflater.from(typeTv.context)
@ -134,7 +145,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
}
popupWindow.setOnDismissListener {
typeTv.setTextColor(R.color.text_757575.toColor())
typeTv.setTextColor(R.color.text_757575.toColor(context))
typeTv.setCompoundDrawables(null, null, drawableDown, null)
}
@ -150,7 +161,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
catalogTv.setTextColor(R.color.theme_font.toColor())
catalogTv.setTextColor(R.color.theme_font.toColor(context))
catalogTv.setCompoundDrawables(null, null, drawableUp, null)
val inflater = LayoutInflater.from(catalogTv.context)
@ -196,7 +207,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
}
popupWindow.setOnDismissListener {
catalogTv.setTextColor(R.color.text_757575.toColor())
catalogTv.setTextColor(R.color.text_757575.toColor(context))
catalogTv.setCompoundDrawables(null, null, drawableDown, null)
}
@ -212,7 +223,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
sizeTv.setTextColor(R.color.theme_font.toColor())
sizeTv.setTextColor(R.color.theme_font.toColor(context))
sizeTv.setCompoundDrawables(null, null, drawableUp, null)
val inflater = LayoutInflater.from(sizeTv.context)
@ -266,7 +277,7 @@ class CatalogFilterView @JvmOverloads constructor(context: Context, attrs: Attri
}
popupWindow.setOnDismissListener {
sizeTv.setTextColor(R.color.text_757575.toColor())
sizeTv.setTextColor(R.color.text_757575.toColor(context))
sizeTv.setCompoundDrawables(null, null, drawableDown, null)
}

View File

@ -2,7 +2,6 @@ package com.gh.common.view
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
@ -17,18 +16,25 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.google.android.flexbox.FlexboxLayout
class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ConstraintLayout(context, attrs, defStyleAttr) {
class ConfigFilterView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private var mSizeTv: TextView
private var mPopupWindow: PopupWindow? = null
var newestTv: TextView
var ratingTv: TextView //目前只在专题页面显示
var recommendedTv: TextView
var updateTv: TextView //更新
var container: View
var sizeFilterArray: ArrayList<SubjectSettingEntity.Size>? = null
private var mOnConfigFilterSetupListener: OnConfigFilterSetupListener? = null
private var mSelectionTvList: ArrayList<TextView>
init {
View.inflate(context, R.layout.layout_config_filter, this)
@ -36,7 +42,11 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
mSizeTv = findViewById(R.id.size_tv)
newestTv = findViewById(R.id.newest_tv)
ratingTv = findViewById(R.id.rating_tv)
updateTv = findViewById(R.id.updateTv)
recommendedTv = findViewById(R.id.recommended_tv)
container = findViewById(R.id.config_controller)
mSelectionTvList = arrayListOf(newestTv, ratingTv, updateTv, recommendedTv)
mSizeTv.setOnClickListener {
mOnConfigFilterSetupListener?.onShowSortSize()
@ -45,55 +55,85 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
ratingTv.setOnClickListener {
mOnConfigFilterSetupListener?.onSetupSortType(SortType.RATING)
toggleHighlightedTextView(ratingTv, true)
toggleHighlightedTextView(newestTv, false)
toggleHighlightedTextView(recommendedTv, false)
updateHighlightedTextView(ratingTv)
}
updateTv.setOnClickListener {
mOnConfigFilterSetupListener?.onSetupSortType(SortType.UPDATE)
updateHighlightedTextView(updateTv)
}
newestTv.setOnClickListener {
mOnConfigFilterSetupListener?.onSetupSortType(SortType.NEWEST)
toggleHighlightedTextView(ratingTv, false)
toggleHighlightedTextView(newestTv, true)
toggleHighlightedTextView(recommendedTv, false)
updateHighlightedTextView(newestTv)
}
recommendedTv.setOnClickListener {
mOnConfigFilterSetupListener?.onSetupSortType(SortType.RECOMMENDED)
toggleHighlightedTextView(ratingTv, false)
toggleHighlightedTextView(newestTv, false)
toggleHighlightedTextView(recommendedTv, true)
updateHighlightedTextView(recommendedTv)
}
}
private fun updateHighlightedTextView(highlightedTv: TextView) {
for (tv in mSelectionTvList) {
toggleHighlightedTextView(tv, tv == highlightedTv)
}
}
fun updateAllTextView(sortType: SortType) {
when (sortType) {
SortType.RECOMMENDED -> updateHighlightedTextView(recommendedTv)
SortType.NEWEST -> updateHighlightedTextView(newestTv)
SortType.RATING -> updateHighlightedTextView(ratingTv)
SortType.UPDATE -> updateHighlightedTextView(updateTv)
}
mSizeTv.setTextColor(R.color.text_757575.toColor(context))
}
fun setOnConfigSetupListener(onConfigFilterSetupListener: OnConfigFilterSetupListener) {
mOnConfigFilterSetupListener = onConfigFilterSetupListener
}
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
if (highlightIt) {
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
targetTextView.background =
ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
targetTextView.setTextColor(Color.WHITE)
} else {
targetTextView.background = null
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
targetTextView.setTextColor(
ContextCompat.getColor(
targetTextView.context,
R.color.text_757575
)
)
}
}
fun updatePopupWindow() {
if (mPopupWindow != null) {
mPopupWindow?.dismiss()
showSelectionPopupWindow(this, mSizeTv, mSizeTv.text.toString())
}
}
private fun showSelectionPopupWindow(containerView: View, sizeTv: TextView, sizeText: String) {
val drawableUp = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_up)
val drawableDown = ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_down)
val drawableDown =
ContextCompat.getDrawable(sizeTv.context, R.drawable.ic_filter_arrow_down)
drawableUp?.setBounds(0, 0, drawableUp.minimumWidth, drawableUp.minimumHeight)
drawableDown?.setBounds(0, 0, drawableDown.minimumWidth, drawableDown.minimumHeight)
sizeTv.setTextColor(R.color.theme_font.toColor())
sizeTv.setTextColor(R.color.theme_font.toColor(sizeTv.context))
sizeTv.setCompoundDrawables(null, null, drawableUp, null)
val inflater = LayoutInflater.from(sizeTv.context)
val layout = inflater.inflate(R.layout.layout_filter_size, null)
val popupWindow = PopupWindow(
layout,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
layout,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply { mPopupWindow = this }
val flexboxLayout = layout.findViewById<FlexboxLayout>(R.id.flexbox)
val backgroundView = layout.findViewById<View>(R.id.background)
@ -143,8 +183,9 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
}
popupWindow.setOnDismissListener {
sizeTv.setTextColor(R.color.text_757575.toColor())
sizeTv.setTextColor(R.color.text_757575.toColor(sizeTv.context))
sizeTv.setCompoundDrawables(null, null, drawableDown, null)
mPopupWindow = null
}
popupWindow.isTouchable = true
@ -173,7 +214,8 @@ class ConfigFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
enum class SortType {
RECOMMENDED,
NEWEST,
RATING
RATING,
UPDATE
}
}

View File

@ -170,7 +170,7 @@ public class DownloadProgressBar extends ProgressBar {
case INSTALL_NORMAL:
case H5_GAME:
if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) {
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_normal_image_style));
setProgressDrawable(getResources().getDrawable(R.drawable.text_white_background));
mDefaultColor = Color.BLACK;
} else {
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style));
@ -185,7 +185,7 @@ public class DownloadProgressBar extends ProgressBar {
setProgress(0);
break;
case NONE:
setProgressDrawable(getResources().getDrawable(R.drawable.news_detail_comment));
setProgressDrawable(getResources().getDrawable(R.drawable.button_border_gray_oval));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.hint);
setProgress(0);
break;

View File

@ -13,7 +13,6 @@ import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.gh.common.databind.DrawablesBindingAdapter
import com.gh.common.util.DisplayUtils
import com.gh.common.util.dip2px
import com.halo.assistant.HaloApp

View File

@ -183,7 +183,7 @@ class FilterView @JvmOverloads constructor(context: Context, attrs: AttributeSet
holder.binding.titleTv.setBackgroundResource(R.drawable.bg_tag_text)
holder.binding.titleTv.setTextColor(R.color.white.toColor())
} else {
holder.binding.titleTv.setBackgroundColor(Color.WHITE)
holder.binding.titleTv.setBackgroundColor(R.color.background_white.toColor(holder.binding.root.context))
holder.binding.titleTv.setTextColor(R.color.text_777777.toColor())
}

View File

@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat
import com.gh.common.util.DisplayUtils
import com.gh.common.util.dip2px
import com.gh.common.util.sp2px
import com.gh.common.util.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.TagStyleEntity
import kotlin.math.ceil
@ -43,7 +44,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4f.dip2px())
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10f.sp2px().toFloat())
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18f.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 1f.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5f.dip2px())
ta.recycle()
}
@ -107,7 +108,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
includeFontPadding = false
textSize = DisplayUtils.px2sp(context, mTextSize).toFloat()
gravity = Gravity.CENTER
setTextColor(Color.parseColor("#333333"))
setTextColor(R.color.text_title.toColor(context))
val params = LayoutParams(LayoutParams.WRAP_CONTENT, mItemHeight)
params.setMargins(0, 0, mMargin, 0)
@ -125,7 +126,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
private fun createBackgroundDrawable(): GradientDrawable {
val gradientDrawable = GradientDrawable()
gradientDrawable.setColor(Color.TRANSPARENT)
gradientDrawable.setStroke(mStrokeWidth, Color.parseColor("#C2C6CC"))
gradientDrawable.setStroke(mStrokeWidth, Color.parseColor("#CCCCCC"))
gradientDrawable.cornerRadius = DisplayUtils.dip2px(2f).toFloat()
return gradientDrawable
}

View File

@ -83,6 +83,10 @@ class GameIconView : CardView {
}
fun displayGameIcon(icon: String?, iconSubscript: String?, goneIfEmpty: Boolean = false) {
if (getTag(ImageUtils.TAG_TARGET_WIDTH) == null) {
setTag(ImageUtils.TAG_TARGET_WIDTH, layoutParams.width)
}
mGameIconIv?.display(icon)
mGameIconDecorationIv?.display(iconSubscript)
mGameIconDecorationIv?.goneIf(TextUtils.isEmpty(iconSubscript))

View File

@ -12,6 +12,7 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.gh.common.util.DisplayUtils
import com.gh.common.util.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.TagStyleEntity
import kotlin.math.ceil
@ -80,7 +81,7 @@ class GameTagFlexLinearLayout @JvmOverloads constructor(context: Context, attrs:
includeFontPadding = false
textSize = mTextSize
gravity = Gravity.CENTER
setTextColor(Color.parseColor("#666666"))
setTextColor(R.color.text_subtitle.toColor(context))
val params = LayoutParams(LayoutParams.WRAP_CONTENT, mItemHeight)
params.setMargins(0, 0, mMargin, 0)

View File

@ -237,6 +237,10 @@ class ImageContainerView : LinearLayout {
} else {
params.width = mDefaultWidth.toInt()
params.height = mDefaultWidth.toInt()
if (width > height) {
val loadImageWidth = width * (mDefaultWidth.toInt() / height)
binding.image.setTag(ImageUtils.TAG_TARGET_WIDTH, loadImageWidth.toInt())
}
ImageUtils.display(binding.image, url, false)
}
//长图

View File

@ -4,11 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.util.ImageUtils
import com.gh.common.util.fromHtml
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
@ -23,8 +23,8 @@ class ReserveDialog : BaseDialogFragment() {
private lateinit var mReserveList: List<SimpleGameEntity>
private var mDismissListener: (() -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: DialogReserveBinding = DataBindingUtil.inflate(inflater, R.layout.dialog_reserve, container, false)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogReserveBinding = DialogReserveBinding.inflate(layoutInflater, null, false)
mReserveList = arguments?.getParcelableArrayList(RESERVE_LIST) ?: arrayListOf()
@ -54,7 +54,8 @@ class ReserveDialog : BaseDialogFragment() {
override fun onBindViewHolder(holder: ReserveDialogItemViewHolder, position: Int) {
val entity = mReserveList[position]
holder.binding.game = entity
ImageUtils.display(holder.binding.icon, entity.icon)
holder.binding.gameNameTv.text = entity.name
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(预约弹窗)")
dismissAllowingStateLoss()

View File

@ -24,7 +24,6 @@ import com.gh.common.util.GsonUtils;
import com.gh.common.util.HtmlUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NetworkUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.RichEditorUtils;
import com.gh.common.util.SPUtils;
@ -62,8 +61,8 @@ import java.util.Locale;
public class RichEditor extends WebView {
// 和 rich_editor.js 同步
public static String IMAGE_FLAG_DEFAULT = ",default";
public static String IMAGE_FLAG_THUMBNAIL = ",thumbnail";
// public static String IMAGE_FLAG_DEFAULT = ",default";
// public static String IMAGE_FLAG_THUMBNAIL = ",thumbnail";
private boolean mContentOwner;
private boolean mInputEnabled;
@ -132,7 +131,7 @@ public class RichEditor extends WebView {
int widthPixels = getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
mThumbnailImageWidth = widthPixels / 3;
mDefaultImageWidth = widthPixels * 2;
mDefaultImageWidth = widthPixels;
}
@SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
@ -251,13 +250,7 @@ public class RichEditor extends WebView {
exec("javascript:RE.setHtmlByVideoStatus('" + URLEncoder.encode(contents, "UTF-8") + "');");
if (isLoadTbImage) {
if (!NetworkUtils.isWifiOr4GConnected(getContext())) {
exec("javascript:RE.replaceTbImage('" +
ImageUtils.getLimitWidthRule(mThumbnailImageWidth) + IMAGE_FLAG_THUMBNAIL + "','" +
ImageUtils.getWatermarkWidthGifRule(mThumbnailImageWidth) + IMAGE_FLAG_THUMBNAIL + "');");
} else {
replaceAllDfImageExcludeGif();
}
replaceAllDfImage();
exec("javascript:RE.ImageClickListener()");
}
@ -370,21 +363,21 @@ public class RichEditor extends WebView {
public void replaceAllDfImageExcludeGif() {
exec("javascript:RE.replaceAllDfImage('" +
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + IMAGE_FLAG_DEFAULT + "','" +
ImageUtils.getWatermarkWidthGifRule(mThumbnailImageWidth) + IMAGE_FLAG_THUMBNAIL + "')");
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + "','" +
ImageUtils.getWatermarkWidthGifRule(mThumbnailImageWidth) + "')");
}
public void replaceAllDfImage() {
exec("javascript:RE.replaceAllDfImage('" +
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + IMAGE_FLAG_DEFAULT + "','" +
ImageUtils.getDefaultGifRule() + IMAGE_FLAG_DEFAULT + "')");
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + "','" +
ImageUtils.getDefaultGifRule() + "')");
}
public void replaceDfImageByUrl(String imgUrl) {
exec("javascript:RE.replaceDfImageByUrl('" + imgUrl + "','" +
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + IMAGE_FLAG_DEFAULT + "','" +
ImageUtils.getDefaultGifRule() + IMAGE_FLAG_DEFAULT + "');");
ImageUtils.getLimitWidthRule(mDefaultImageWidth) + "','" +
ImageUtils.getDefaultGifRule() + "');");
}
public void loadCSS(String cssFile) {

View File

@ -0,0 +1,215 @@
package com.gh.common.view
import android.animation.ArgbEvaluator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.annotation.ColorInt
import com.gh.common.util.dip2px
import com.gh.gamecenter.R
class ScaleIndicatorView : View {
private var argbEvaluator: ArgbEvaluator? = null
private var mCurrentPosition = 0
private var mSlideProgress = 0F
var mPageSize = 0
var mNormalSliderWidth = 0F
var mCheckedSliderWidth = 0F
var mSliderHeight = 0F
var mSliderGap = 0F
@ColorInt
var mNormalColor = 0
@ColorInt
var mCheckedColor = 0
private var mRectF = RectF()
private var mPaint = Paint()
private var maxWidth = 0F
private var minWidth = 0F
private val isWidthEquals
get() = mNormalSliderWidth == mCheckedSliderWidth
constructor(context: Context) : super(context, null) {
initView(null)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs, 0) {
initView(attrs)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
initView(attrs)
}
private fun initView(attrs: AttributeSet?) {
if (attrs != null) {
val ta = context.obtainStyledAttributes(attrs, R.styleable.ScaleIndicatorView)
mNormalSliderWidth = ta.getDimensionPixelSize(R.styleable.ScaleIndicatorView_normalSliderWidth, 10F.dip2px()).toFloat()
mCheckedSliderWidth = ta.getDimensionPixelSize(R.styleable.ScaleIndicatorView_checkedSliderWidth, 10F.dip2px()).toFloat()
mSliderHeight = ta.getDimensionPixelSize(R.styleable.ScaleIndicatorView_normalSliderWidth, 10F.dip2px()).toFloat()
mSliderGap = ta.getDimensionPixelSize(R.styleable.ScaleIndicatorView_normalSliderWidth, 10F.dip2px()).toFloat()
mNormalColor = ta.getColor(R.styleable.ScaleIndicatorView_normalColor, Color.WHITE)
mCheckedColor = ta.getColor(R.styleable.ScaleIndicatorView_checkedColor, Color.WHITE)
}
mPaint.isAntiAlias = true
argbEvaluator = ArgbEvaluator()
}
fun onPageScrolled(position: Int, positionOffset: Float) {
if (mPageSize > 1) {
scrollSlider(position, positionOffset)
invalidate()
}
}
fun notifyDataChanged() {
requestLayout()
invalidate()
}
private fun scrollSlider(
position: Int,
positionOffset: Float
) {
mCurrentPosition = position
mSlideProgress = positionOffset
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
maxWidth = mNormalSliderWidth.coerceAtLeast(mCheckedSliderWidth)
minWidth = mNormalSliderWidth.coerceAtMost(mCheckedSliderWidth)
setMeasuredDimension(measureWidth(), measureHeight())
}
private fun measureHeight() = mSliderHeight.toInt() + INDICATOR_PADDING
private fun measureWidth() =
((mPageSize - 1) * mSliderGap + maxWidth + (mPageSize - 1) * minWidth).toInt() + INDICATOR_PADDING_ADDITION
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (mPageSize > 1) {
if (isWidthEquals) {
drawUncheckedSlider(canvas, mPageSize)
} else {
for (i in 0 until mPageSize) {
drawScaleSlider(canvas, i)
}
}
}
}
private fun drawScaleSlider(
canvas: Canvas?,
i: Int
) {
when {
i < mCurrentPosition -> {
mPaint.color = mNormalColor
val left: Float = if (mCurrentPosition == mPageSize - 1) {
(i * mNormalSliderWidth + i * mSliderGap) + (mCheckedSliderWidth - mNormalSliderWidth) * mSlideProgress
} else {
(i * mNormalSliderWidth + i * mSliderGap)
}
mRectF.set(left, 0f, left + mNormalSliderWidth, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
i == mCurrentPosition -> {
mPaint.color = mCheckedColor
val slideProgress = mSlideProgress
if (mCurrentPosition == mPageSize - 1) {
val evaluate = argbEvaluator?.evaluate(
slideProgress, mCheckedColor, mNormalColor
)
mPaint.color = (evaluate as Int)
val right =
(mPageSize - 1) * (mNormalSliderWidth + mSliderGap) + mCheckedSliderWidth
val left =
right - mCheckedSliderWidth + (mCheckedSliderWidth - mNormalSliderWidth) * (slideProgress)
mRectF.set(left, 0f, right, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
} else {
if (slideProgress < 1) {
val evaluate = argbEvaluator?.evaluate(
slideProgress, mCheckedColor, mNormalColor
)
mPaint.color = (evaluate as Int)
val left = i * mNormalSliderWidth + i * mSliderGap
val right =
left + mNormalSliderWidth + (mCheckedSliderWidth - mNormalSliderWidth) * (1 - slideProgress)
mRectF.set(left, 0f, right, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
}
if (mCurrentPosition == mPageSize - 1) {
if (slideProgress > 0) {
val evaluate = argbEvaluator?.evaluate(
1 - slideProgress, mCheckedColor, mNormalColor
)
mPaint.color = evaluate as Int
val left = 0f
val right =
left + mNormalSliderWidth + (mCheckedSliderWidth - mNormalSliderWidth) * slideProgress
mRectF.set(left, 0f, right, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
} else {
if (slideProgress > 0) {
val evaluate = argbEvaluator?.evaluate(
1 - slideProgress, mCheckedColor, mNormalColor
)
mPaint.color = evaluate as Int
val right =
i * mNormalSliderWidth + i * mSliderGap + mNormalSliderWidth + (mSliderGap + mCheckedSliderWidth)
val left =
right - (mNormalSliderWidth) - (mCheckedSliderWidth - mNormalSliderWidth) * (slideProgress)
mRectF.set(left, 0f, right, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
}
}
else -> {
if ((mCurrentPosition + 1 != i || mSlideProgress == 0f)) { // 避免多余绘制
mPaint.color = mNormalColor
val left = i * minWidth + i * mSliderGap + (mCheckedSliderWidth - minWidth)
mRectF.set(left, 0f, left + minWidth, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
}
}
}
private fun drawUncheckedSlider(
canvas: Canvas?,
pageSize: Int
) {
for (i in 0 until pageSize) {
mPaint.color = mNormalColor
val left = i * maxWidth + i * +mSliderGap + (maxWidth - minWidth)
mRectF.set(left, 0f, left + minWidth, mSliderHeight)
canvas?.drawRoundRect(mRectF, mSliderHeight, mSliderHeight, mPaint)
}
}
companion object {
const val INDICATOR_PADDING_ADDITION = 6
const val INDICATOR_PADDING = 3
}
}

View File

@ -0,0 +1,197 @@
package com.gh.common.view
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.core.content.ContextCompat
import com.gh.common.util.dip2px
import com.gh.gamecenter.R
import splitties.views.dsl.core.add
class SegmentedFilterView : FrameLayout {
private var mItemWidth = 0
private var mItemHeight = 0
private var mTextColor: ColorStateList? =
ContextCompat.getColorStateList(context, R.color.game_collection_rg_button_selector)
private var mTextSize = 10F
private var mContainerBackground: Drawable? = null
private var mIndicatorBackground: Drawable? = null
private var mAnimationDuration = 200
private var mContainerPadding = 1F.dip2px()
private lateinit var mContainer: FrameLayout
private lateinit var mRadioGroup: RadioGroup
private lateinit var mIndicator: View
private var mCallback: OnCheckedCallback? = null
private var mItemList = listOf<String>()
constructor(context: Context) : super(context, null) {
initView(null)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs, 0) {
initView(attrs)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
initView(attrs)
}
fun setTextColor(colorStateList: ColorStateList?) {
if (::mRadioGroup.isInitialized) {
for (i in 0 until mRadioGroup.childCount) {
val radioBtn = mRadioGroup.getChildAt(i) as RadioButton
radioBtn.setTextColor(colorStateList)
}
}
}
fun setContainerBackground(drawable: Drawable?) {
background = drawable
}
fun setIndicatorBackground(drawable: Drawable?) {
if (::mIndicator.isInitialized) {
mIndicator.background = drawable
}
}
private fun initView(attrs: AttributeSet?) {
if (attrs != null) {
val ta = context.obtainStyledAttributes(attrs, R.styleable.SegmentedFilterView)
mContainerBackground =
ta.getDrawable(R.styleable.SegmentedFilterView_containerBackground)
mIndicatorBackground =
ta.getDrawable(R.styleable.SegmentedFilterView_indicatorBackground)
mContainerPadding = ta.getDimensionPixelSize(
R.styleable.SegmentedFilterView_containerPadding,
1F.dip2px()
)
mItemWidth = ta.getDimensionPixelSize(
R.styleable.SegmentedFilterView_sfv_itemWidth,
36F.dip2px()
)
mItemHeight = ta.getDimensionPixelSize(
R.styleable.SegmentedFilterView_sfv_itemHeight,
24F.dip2px()
)
mAnimationDuration = ta.getInt(R.styleable.SegmentedFilterView_animationDuration, 200)
mTextColor = ta.getColorStateList(R.styleable.SegmentedFilterView_sfv_textColor)
mTextSize = ta.getFloat(R.styleable.SegmentedFilterView_sfv_textSize, 10F)
ta.recycle()
}
setPadding(mContainerPadding, mContainerPadding, mContainerPadding, mContainerPadding)
if (mContainerBackground != null) background = mContainerBackground
mContainer = FrameLayout(context)
mIndicator = View(context).apply {
background = mIndicatorBackground
}
mRadioGroup = RadioGroup(context).apply {
gravity = Gravity.CENTER
orientation = LinearLayout.HORIZONTAL
}
add(mContainer, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT))
mContainer.add(mIndicator, LayoutParams(mItemWidth, mItemHeight))
mContainer.add(
mRadioGroup,
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
)
}
fun setItemList(itemList: List<String>, defaultCheckPosition: Int) {
mItemList = itemList
mRadioGroup.removeAllViews()
addRadioButton()
if (defaultCheckPosition in 0 until mRadioGroup.childCount) (mRadioGroup.getChildAt(defaultCheckPosition) as RadioButton).isChecked = true
}
fun getItemList(): List<String> {
return mItemList
}
fun performClick(position: Int) {
if (position in 0 until mRadioGroup.childCount) {
val radioButton = mRadioGroup.getChildAt(position) as RadioButton
radioButton.isChecked = true
startIndicatorAnimation(radioButton.x)
mCallback?.onItemCheck(position)
}
}
fun setChecked(position: Int) {
if (position in 0 until mRadioGroup.childCount) {
val radioButton = mRadioGroup.getChildAt(position) as RadioButton
mIndicator.x = radioButton.x
radioButton.isChecked = true
}
}
fun getCurrentPosition(): Int {
var position = 0
for (i in 0 until mRadioGroup.childCount) {
val radioButton = mRadioGroup.getChildAt(i) as RadioButton
if (radioButton.isChecked) {
position = i
break
}
}
return position
}
fun setOnCheckedCallback(callback: OnCheckedCallback) {
mCallback = callback
mRadioGroup.setOnCheckedChangeListener { _, checkId ->
for (i in 0 until mRadioGroup.childCount) {
val radioBtn = mRadioGroup.getChildAt(i)
if (checkId == radioBtn.id && radioBtn.x != mIndicator.x) {
startIndicatorAnimation(radioBtn.x)
mCallback?.onItemCheck(i)
}
}
}
}
private fun addRadioButton() {
for (item in mItemList) {
val radioButton = RadioButton(context).apply {
background = null
buttonDrawable = null
text = item
gravity = Gravity.CENTER
textSize = mTextSize
setTextColor(mTextColor)
isChecked = false
}
mRadioGroup.add(radioButton, LinearLayout.LayoutParams(mItemWidth, mItemHeight))
}
}
private fun startIndicatorAnimation(x: Float) {
ValueAnimator.ofFloat(mIndicator.x, x).apply {
interpolator = AccelerateDecelerateInterpolator()
duration = mAnimationDuration.toLong()
addUpdateListener {
mIndicator.x = it.animatedValue as Float
}
}.start()
}
interface OnCheckedCallback {
fun onItemCheck(position: Int)
}
}

View File

@ -0,0 +1,25 @@
package com.gh.common.view;
import android.content.Context;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatTextView;
public class TrimmedPaddingTextView extends AppCompatTextView {
public TrimmedPaddingTextView(Context context) {
super(context);
}
public TrimmedPaddingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setIncludeFontPadding(getLineCount() > 1);
}
}

View File

@ -2,6 +2,7 @@ package com.gh.common.view
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.*
import android.text.InputFilter.LengthFilter
@ -14,6 +15,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import com.gh.gamecenter.R
import java.util.*
@ -33,6 +35,7 @@ class VerifyEditText @JvmOverloads constructor(
private var mEditText: EditText? = null
private var drawableNormal: Drawable? = null
private var drawableSelected: Drawable? = null
private var textColor: Int
private var mContext: Context? = null
@ -58,6 +61,23 @@ class VerifyEditText @JvmOverloads constructor(
if (drawable != null) textView.background = drawable
}
fun setTextViewStyle(normal: Drawable?, selected: Drawable?, @ColorInt color: Int) {
drawableNormal = normal
drawableSelected = selected
textColor = color
var isFirst = true
for (i in mTextViewList.indices) {
val textView = mTextViewList[i]
if (textView.text.isNullOrEmpty() && isFirst) {
isFirst = false
setTextViewBackground(textView, drawableSelected)
} else {
setTextViewBackground(textView, drawableNormal)
}
textView.setTextColor(textColor)
}
}
/**
* 获取当前输入的内容
*
@ -179,7 +199,7 @@ class VerifyEditText @JvmOverloads constructor(
obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_normal)
drawableSelected =
obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_selected)
val textColor = obtainStyledAttributes.getColor(
textColor = obtainStyledAttributes.getColor(
R.styleable.verify_EditText_verify_textColor,
ContextCompat.getColor(context, R.color.black)
)

View File

@ -82,6 +82,8 @@ object DownloadDataHelper {
"未实名"
} else if (status == DownloadStatus.unqualified) {
"未成年"
} else if (status == DownloadStatus.unavailable) {
"未接入防沉迷系统,暂不支持下载"
} else if (status == DownloadStatus.redirected) {
"重定向至最终地址"
} else {

View File

@ -73,7 +73,6 @@ import java.util.concurrent.LinkedBlockingQueue;
public class DownloadManager implements DownloadStatusListener {
private static final Gson gson = new Gson();
private static final String UPDATE_IS_READ_MARK = "update_is_read";
private static final String DOWNLOADING_IS_READ_MARK = "downloading_is_read";
private static final String DOWNLOADED_IS_READ_MARK = "downloaded_is_read";
@ -349,7 +348,7 @@ public class DownloadManager implements DownloadStatusListener {
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, apkEntity.getPlatform(), traceEvent, downloadType);
// 将下载事件放入 downloadEntity 中供下载完成时取出使用
downloadEntity.setExposureTrace(gson.toJson(downloadExposureEvent));
downloadEntity.setExposureTrace(GsonUtils.toJson(downloadExposureEvent));
if (isSubscribe) {
DownloadManager.getInstance().subscribe(downloadEntity);
@ -690,11 +689,13 @@ public class DownloadManager implements DownloadStatusListener {
public void cancel(String url, boolean isDeleteFile, boolean automatic) {
DownloadEntity entry = mDownloadDao.get(url);
if (entry != null) {
if (isDeleteFile) {
FileUtils.deleteFile(entry.getPath());
}
mDownloadDao.delete(url);
Utils.log(DownloadManager.class.getSimpleName(), "cancel==>record were deleted!");
AppExecutor.getIoExecutor().execute(() -> {
if (isDeleteFile) {
FileUtils.deleteFile(entry.getPath());
}
mDownloadDao.delete(url);
Utils.log(DownloadManager.class.getSimpleName(), "cancel==>record were deleted!");
});
}
if (entry != null) {
if (automatic) {

View File

@ -3,10 +3,11 @@ package com.gh.download.dialog
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
@ -32,7 +33,6 @@ import com.lightgame.utils.AppManager
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*
class DownloadDialog : BaseDraggableDialogFragment() {
@ -62,17 +62,20 @@ class DownloadDialog : BaseDraggableDialogFragment() {
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.gameId == mGameEntity?.id &&
DownloadStatus.delete != DownloadManager.getInstance().getStatus(downloadEntity.url)) {
DownloadStatus.delete != DownloadManager.getInstance().getStatus(downloadEntity.url)
) {
mAdapter?.listData?.forEachIndexed { index, entity ->
if (entity.normal?.packageName == downloadEntity.packageName
|| entity.installed?.packageName == downloadEntity.packageName) {
|| entity.installed?.packageName == downloadEntity.packageName
) {
mAdapter?.notifyItemChanged(index)
}
}
mCollectionAdapter?.listData?.forEachIndexed { index, entity ->
if (entity.normal?.packageName == downloadEntity.packageName
|| entity.installed?.packageName == downloadEntity.packageName) {
|| entity.installed?.packageName == downloadEntity.packageName
) {
mCollectionAdapter?.notifyItemChanged(index)
}
}
@ -146,8 +149,8 @@ class DownloadDialog : BaseDraggableDialogFragment() {
}
@SuppressLint("ClickableViewAccessibility")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = DataBindingUtil.inflate(inflater, R.layout.dialog_download, container, false)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
mBinding = DialogDownloadBinding.bind(layoutInflater.inflate(R.layout.dialog_download, container, false))
mBinding.title.text = ("选择下载" + mGameEntity.pluginDesc + "版本")
val downloadNotice = mGameEntity.downloadAd
@ -159,9 +162,10 @@ class DownloadDialog : BaseDraggableDialogFragment() {
DialogUtils.showImprintDialog(requireContext(), mGameEntity, downloadNotice.title)
} else {
DirectUtils.directToLinkPage(
requireContext(),
downloadNotice,
mEntrance, "下载多平台弹窗")
requireContext(),
downloadNotice,
mEntrance, "下载多平台弹窗"
)
}
// MtaHelper.onEvent(MTA_KEY, "点击", mViewModel.gameEntity.name + "_" + downloadNotice.title)
}

View File

@ -1,15 +1,13 @@
package com.gh.download.dialog
import android.content.Context
import android.graphics.drawable.GradientDrawable
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.OnViewClickListener
import com.gh.common.exposure.ExposureEvent
import com.gh.common.util.DirectUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.dip2px
import com.gh.common.util.throwExceptionInDebug
import com.gh.common.util.*
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.QaActivity
import com.gh.gamecenter.R
@ -18,13 +16,15 @@ import com.gh.gamecenter.entity.GameEntity
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.utils.Utils
class DownloadDialogAdapter(context: Context,
val viewModel: DownloadViewModel,
val listData: List<DownloadDialogItemData>,
val isCollectionPage: Boolean,
private val mTraceEvent: ExposureEvent?,
private val mEntrance: String,
private val mLocation: String) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
class DownloadDialogAdapter(
context: Context,
val viewModel: DownloadViewModel,
val listData: List<DownloadDialogItemData>,
val isCollectionPage: Boolean,
private val mTraceEvent: ExposureEvent?,
private val mEntrance: String,
private val mLocation: String
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
private val mPath = if (isCollectionPage) {
"下载弹窗-二级页"
@ -83,11 +83,13 @@ class DownloadDialogAdapter(context: Context,
} else 0
holder.binding.root.layoutParams = this
}
holder.binding.type = listData[position].section
val section = listData[position].section
holder.binding.title.text = if (section == DownloadDialogSectionType.OTHER) "其它版本" else "我的版本"
holder.binding.otherVersionHint.goneIf(section != DownloadDialogSectionType.OTHER)
}
is DownloadDialogLinkItemViewHolder -> {
holder.binding.links = listData[position].links
holder.binding.clickListener = OnViewClickListener<GameEntity.PluginLink> { _, data ->
val links = listData[position].links
val clickListener = OnViewClickListener<GameEntity.PluginLink> { _, data ->
when (data.linkType) {
"dialog" -> {
DownloadLinkDialog.showDownloadDialog(mContext, data)
@ -109,6 +111,28 @@ class DownloadDialogAdapter(context: Context,
// MtaHelper.onEvent(DownloadDialog.MTA_KEY, "点击", viewModel.gameEntity.name + "_" + data.title)
}
holder.binding.run {
links?.let {
leftLink.setOnClickListener { view ->
clickListener.onClick(view, links[0])
}
rightLink.setOnClickListener { view ->
clickListener.onClick(view, links[1])
}
}
leftLink.visibleIf(!links.isNullOrEmpty())
rightLink.visibleIf(links?.size ?:0 > 1)
leftLink.text = if (links.isNullOrEmpty()) "" else links[0].title
rightLink.text = if (links?.size ?: 0 > 1) links?.get(1)?.title else ""
leftLink.background = GradientDrawable().apply {
cornerRadius = 8F.dip2px().toFloat()
setStroke(0.5F.dip2px(), R.color.divider.toColor())
}
rightLink.background = GradientDrawable().apply {
cornerRadius = 8F.dip2px().toFloat()
setStroke(0.5F.dip2px(), R.color.divider.toColor())
}
}
}
is DownloadDialogInstructionItemViewHolder -> {
holder.bindItem(listData, position, mEntrance)

View File

@ -4,10 +4,7 @@ import android.view.View
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureEvent
import com.gh.common.util.PackageUtils
import com.gh.common.util.goneIf
import com.gh.common.util.throwExceptionInDebug
import com.gh.common.util.toColor
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DownloadDialogInstalledItemBinding
@ -16,15 +13,28 @@ import com.lightgame.download.DownloadStatus
class DownloadDialogInstalledItemViewHolder(val binding: DownloadDialogInstalledItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
fun bindInstalledItem(apkEntity: ApkEntity, viewModel: DownloadViewModel, traceEvent: ExposureEvent?, entrance: String, path: String, location: String) {
fun bindInstalledItem(
apkEntity: ApkEntity,
viewModel: DownloadViewModel,
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String
) {
val gameEntity = viewModel.gameEntity
val apkCollection = apkEntity.apkCollection
binding.pluginDesc = gameEntity.pluginDesc
binding.apk = if (apkCollection != null) {
val pluginDesc = gameEntity.pluginDesc
val apk = if (apkCollection != null) {
ApkEntity(platformIcon = apkCollection.newIcon, platformName = apkCollection.name, remark = apkCollection.remark)
} else apkEntity
ImageUtils.display(binding.icon, apk.getPlatformIcon())
binding.name.text = apk.getPlatformName()
binding.remark.text = apk.remark
binding.root.setBackgroundResource(R.drawable.download_dialog_item_background)
binding.launch.text = "启动${pluginDesc}"
binding.pluggable.text = "${pluginDesc}此版本"
binding.update.text = "更新${pluginDesc}"
if (apkEntity.apkLink != null) {
throwExceptionInDebug("apkLink 不应该出现在这里")
@ -132,6 +142,5 @@ class DownloadDialogInstalledItemViewHolder(val binding: DownloadDialogInstalled
}
DownloadDialogItemViewHolder.setDownloadClickListener(itemView, apkEntity, viewModel, traceEvent, entrance, path, location)
binding.executePendingBindings()
}
}

View File

@ -32,37 +32,51 @@ import com.lightgame.utils.Utils
class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
fun bindItem(listData: List<DownloadDialogItemData>,
position: Int,
viewModel: DownloadViewModel,
isCollectionPage: Boolean,
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String) {
fun bindItem(
listData: List<DownloadDialogItemData>,
position: Int,
viewModel: DownloadViewModel,
isCollectionPage: Boolean,
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String
) {
val apkEntity = listData[position].normal!!
val gameEntity = viewModel.gameEntity
val apkLink = apkEntity.apkLink
val apkCollection = apkEntity.apkCollection
binding.apk = when {
val apk = when {
apkLink != null -> ApkEntity(
platformIcon = apkLink.icon,
platformName = apkLink.name,
remark = apkLink.remark)
platformIcon = apkLink.icon,
platformName = apkLink.name,
remark = apkLink.remark
)
apkCollection != null -> ApkEntity(
platformIcon = apkCollection.newIcon,
platformName = apkCollection.name,
recommend = apkCollection.recommend,
remark = apkCollection.remark)
platformIcon = apkCollection.newIcon,
platformName = apkCollection.name,
recommend = apkCollection.recommend,
remark = apkCollection.remark
)
else -> apkEntity
}
ImageUtils.display(binding.icon, apk.getPlatformIcon())
binding.name.text = apk.getPlatformName()
binding.remark.text = apk.remark
binding.recommendDesTv.goneIf(apk.recommend == null)
binding.recommendDesTv.text = apk.recommend?.description
binding.recommendLabel.goneIf(apk.recommend == null)
binding.recommendLabelTv.text = apk.recommend?.subscript
binding.containerView.setBackgroundResource(R.drawable.download_dialog_item_background)
binding.status.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
changeRecommendUI(apkEntity, listData, position)
if (apkLink != null) {
binding.root.visibility = View.VISIBLE
binding.downloadStatusIcon.visibility = View.GONE
binding.status.visibility = View.VISIBLE
binding.progressbar.visibility = View.GONE
@ -70,7 +84,12 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
binding.remark.goneIf(apkLink.remark.isEmpty())
binding.status.text = "点击查看"
binding.status.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_link), null)
binding.status.setCompoundDrawablesWithIntrinsicBounds(
null,
null,
ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_link),
null
)
binding.containerView.setBackgroundResource(R.drawable.download_dialog_installed_background)
itemView.setTag(DownloadDialogAdapter.ITEM_TAG_KEY, DownloadDialogItemStatus.LINK)
} else if (apkCollection != null || (!isCollectionPage && apkEntity.downloadInstruction.isNotEmpty())) {
@ -119,11 +138,17 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
binding.status.visibility = View.VISIBLE
binding.status.text = "可更新"
binding.status.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_update), null)
binding.status.setCompoundDrawablesWithIntrinsicBounds(
null,
null,
ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_update),
null
)
binding.downloadStatusIcon.visibility = View.GONE
itemView.setTag(DownloadDialogAdapter.ITEM_TAG_KEY, DownloadDialogItemStatus.UPDATE)
} else if (PackageUtils.getGhId(apkEntity.packageName) == gameEntity.id ||
PackagesManager.isInstalled(apkEntity.packageName) && Config.getSettings()?.gameDownloadBlackList?.contains(apkEntity.packageName) == true) {
PackagesManager.isInstalled(apkEntity.packageName) && Config.getSettings()?.gameDownloadBlackList?.contains(apkEntity.packageName) == true
) {
binding.downloadStatusIcon.visibility = View.GONE
binding.status.visibility = View.VISIBLE
binding.containerView.setBackgroundResource(R.drawable.download_dialog_installed_background)
@ -143,7 +168,12 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
// 点击启动
binding.status.text = "点击启动"
itemView.setTag(DownloadDialogAdapter.ITEM_TAG_KEY, DownloadDialogItemStatus.LAUNCH)
binding.status.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_launch), null)
binding.status.setCompoundDrawablesWithIntrinsicBounds(
null,
null,
ContextCompat.getDrawable(binding.status.context, R.drawable.download_dialog_collection_status_launch),
null
)
}
} else {
binding.downloadStatusIcon.visibility = View.VISIBLE
@ -160,7 +190,6 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
setDownloadClickListener(itemView, apkEntity, viewModel, traceEvent, entrance, path, location)
binding.executePendingBindings()
}
private fun changeRecommendUI(apkEntity: ApkEntity, listData: List<DownloadDialogItemData>, position: Int) {
@ -171,7 +200,8 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
(binding.root.layoutParams as RecyclerView.LayoutParams).apply {
bottomMargin = if (apkEntity.recommend != null) {
if ((position + 1 < listData.size && listData[position + 1].normal?.recommend == null) ||
(position + 2 < listData.size && listData[position + 2].normal?.recommend == null)) {
(position + 2 < listData.size && listData[position + 2].normal?.recommend == null)
) {
20f.dip2px()
} else 16f.dip2px()
} else 8f.dip2px()
@ -192,13 +222,15 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
}
fun setDownloadClickListener(itemView: View,
apkEntity: ApkEntity,
viewModel: DownloadViewModel,
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String) {
fun setDownloadClickListener(
itemView: View,
apkEntity: ApkEntity,
viewModel: DownloadViewModel,
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String
) {
val gameEntity = viewModel.gameEntity
itemView.setOnClickListener {
@ -215,10 +247,13 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
DownloadDialogItemStatus.DOWNLOADING -> {
// 打开下载管理界面
it.context.startActivity(DownloadManagerActivity.getDownloadMangerIntent(
it.context.startActivity(
DownloadManagerActivity.getDownloadMangerIntent(
it.context,
apkEntity.url,
BaseActivity.mergeEntranceAndPath(entrance, path)))
BaseActivity.mergeEntranceAndPath(entrance, path)
)
)
if (AppManager.getInstance().currentActivity() is DownloadManagerActivity) {
viewModel.dismissLiveData.postValue(Any())
}
@ -237,7 +272,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
DownloadDialogItemStatus.INSTALL -> {
val downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(apkEntity.url)
?: return@setOnClickListener
?: return@setOnClickListener
if (FileUtils.isEmptyFile(downloadEntity.path)) {
Utils.toast(it.context, R.string.install_failure_hint)
@ -300,13 +335,15 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
}
private fun createDownloadTask(context: Context,
apkEntity: ApkEntity,
gameEntity: GameEntity,
downloadMethod: String,
traceEvent: ExposureEvent?,
entrance: String,
location: String) {
private fun createDownloadTask(
context: Context,
apkEntity: ApkEntity,
gameEntity: GameEntity,
downloadMethod: String,
traceEvent: ExposureEvent?,
entrance: String,
location: String
) {
// todo 有时间存储判断统一处理
val msg = FileUtils.isCanDownload(context, apkEntity.size)
if (msg.isNullOrEmpty()) {
@ -318,13 +355,14 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
CertificationDialog.showCertificationDialog(context, gameEntity, DialogUtils.ConfirmListener {
DialogUtils.checkDownload(context, apkEntity.size) { isSubscribe ->
DownloadManager.createDownload(
context,
apkEntity,
gameEntity,
downloadMethod,
entrance,
location,
isSubscribe, traceEvent)
context,
apkEntity,
gameEntity,
downloadMethod,
entrance,
location,
isSubscribe, traceEvent
)
DeviceRemindDialog.showDeviceRemindDialog(context, gameEntity)
}

View File

@ -5,12 +5,10 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.FragmentActivity
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.util.dip2px
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogDownloadLinkBinding
import com.gh.gamecenter.entity.GameEntity
import com.halo.assistant.HaloApp
@ -25,11 +23,14 @@ class DownloadLinkDialog : BaseDialogFragment() {
super.onCreate(savedInstanceState)
mLinkEntity = requireArguments().getParcelable(KEY_LINK_ENTITY)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: DialogDownloadLinkBinding = DataBindingUtil.inflate(inflater, R.layout.dialog_download_link, container, false)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogDownloadLinkBinding = DialogDownloadLinkBinding.inflate(layoutInflater, container, false)
binding.title.text = mLinkEntity?.title
binding.webView.loadDataWithBaseURL(null,
mLinkEntity?.content ?: "", "text/html", "utf-8", null)
binding.webView.loadDataWithBaseURL(
null,
mLinkEntity?.content ?: "", "text/html", "utf-8", null
)
binding.confirm.setOnClickListener {
dismissAllowingStateLoss()

View File

@ -5,7 +5,9 @@ import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ExtensionsKt;
import com.halo.assistant.fragment.AboutFragment;
/**
@ -13,6 +15,12 @@ import com.halo.assistant.fragment.AboutFragment;
*/
public class AboutActivity extends NormalActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
@NonNull
public static Intent getIntent(Context context, boolean isUpdate) {
Bundle bundle = new Bundle();
@ -20,4 +28,14 @@ public class AboutActivity extends NormalActivity {
return getTargetIntent(context, AboutActivity.class, AboutFragment.class, bundle);
}
@Override
protected boolean isAutoResetViewBackgroundEnabled() {
return true;
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
}

View File

@ -2,7 +2,10 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.ExtensionsKt;
import com.gh.gamecenter.info.ConcernFragment;
/**
@ -11,7 +14,19 @@ import com.gh.gamecenter.info.ConcernFragment;
public class ConcernInfoActivity extends NormalActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
public static Intent getIntent(Context context) {
return getTargetIntent(context, ConcernInfoActivity.class, ConcernFragment.class);
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
}

View File

@ -5,7 +5,9 @@ import android.content.Intent;
import android.os.Bundle;
import com.gh.base.fragment.BaseFragment_TabLayout;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ExtensionsKt;
import com.gh.gamecenter.download.DownloadFragment;
/**
@ -20,6 +22,12 @@ public class DownloadManagerActivity extends NormalActivity {
public static final String TAG = "DownloadManagerActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
@Override
protected Intent provideNormalIntent() {
return getTargetIntent(this, DownloadManagerActivity.class, DownloadFragment.class);
@ -48,4 +56,10 @@ public class DownloadManagerActivity extends NormalActivity {
bundle.putString(EntranceUtils.KEY_PACKAGENAME, packageName);
return getTargetIntent(context, DownloadManagerActivity.class, DownloadFragment.class, bundle);
}
@Override
protected void onNightModeChange() {
super.onNightModeChange();
ExtensionsKt.updateStatusBarColor(this, R.color.black, R.color.white);
}
}

View File

@ -75,6 +75,8 @@ class GameDetailActivity : NormalActivity() {
})
}
override fun isAutoResetViewBackgroundEnabled(): Boolean = true
companion object {
@JvmStatic

Some files were not shown because too many files have changed in this diff Show More