Compare commits

...

256 Commits

Author SHA1 Message Date
1facde123e 3.7.1_tinker-base 2019-12-05 18:31:21 +08:00
8f9d6ed2ce 完成20191202测试汇总的20191205补充 https://gitlab.ghzs.com/pm/halo-app-issues/issues/714 2019-12-05 17:52:25 +08:00
e43902be79 首页下载统计 下载位置补充 2019-12-04 19:27:17 +08:00
0f5f8861a7 修复问答推荐默认排序规则混乱问题 2019-12-04 15:10:17 +08:00
cb08886d27 修复启动图显示问题(与系统底部控制栏重叠) 2019-12-04 14:51:10 +08:00
322ec56787 修复光环助手1202测试问题汇总(20191204的3,4,6) https://gitlab.ghzs.com/pm/halo-app-issues/issues/714 2019-12-04 11:56:14 +08:00
60b12a3bdf Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-12-04 11:30:09 +08:00
26a66e3a2b 更换启动图 2019-12-04 11:29:35 +08:00
e86e78a665 添加默认打包渠道号 2019-12-03 16:07:13 +08:00
3ba68abbee 优化首页刷新问题 补充 2019-12-03 15:45:58 +08:00
a46ba32f06 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-03 15:21:25 +08:00
82348b519a 优化首页刷新问题 2019-12-03 15:20:53 +08:00
8315a50d49 绕过广点通SDK初始化限制避免启动耗时过长 2019-12-03 11:50:21 +08:00
dca07831db 新增 徽章中心 MTA事件 2019-12-03 09:51:34 +08:00
d568dd0791 修复邀请回答页面用户名显示越界问题 2019-12-03 09:31:13 +08:00
9dbfc68488 Merge branch '3.7.0_servers_reverse' into dev 2019-12-02 19:34:24 +08:00
0b46e0ef8e 邀请回答徽章位置修改 2019-12-02 18:27:58 +08:00
472604bc15 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-02 17:49:07 +08:00
58a2d38518 修复DownloadItemUtils下载按钮点击回调混乱顺序问题 2019-12-02 17:48:54 +08:00
c91186be8a 修复启动页的虚拟按键显示问题 2019-12-02 17:37:49 +08:00
03235438bc Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2019-12-02 17:18:49 +08:00
d015285f1a 更换启动图 2019-12-02 17:17:42 +08:00
45323a6817 MTA数据补充 2019-12-02 16:59:18 +08:00
bcc8d35654 进入评论MTA数据修改 2019-12-02 16:07:16 +08:00
9137b65f4a 粉丝/关注页面MTA数据 2019-12-02 16:01:29 +08:00
fbc9dac99e 修复安利墙分页问题 2019-12-02 15:41:09 +08:00
c27a6e06ad 更换启动图 2019-12-02 15:03:07 +08:00
07970fcbae Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2019-12-02 00:13:19 +08:00
0b3e250386 优化启动图 2019-12-02 00:11:48 +08:00
13b1ba613d 完成(20191129-1730)测试问题汇总的20191201测试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/712 2019-12-01 23:54:15 +08:00
5a1feb4500 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 23:21:22 +08:00
cc7accbc95 首页轮播图增加预约功能 2019-12-01 23:14:10 +08:00
42a83ea0c5 Merge remote-tracking branch 'origin/dev' into dev 2019-12-01 23:04:13 +08:00
39f84442cd 调整 chucker 编译脚本 2019-12-01 23:04:04 +08:00
047c25b0b7 完成1201-1500测试问题汇总的16,18 https://gitlab.ghzs.com/pm/halo-app-issues/issues/713 2019-12-01 23:02:24 +08:00
045f21beac Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 22:49:31 +08:00
8a64460097 更换启动图 2019-12-01 22:49:20 +08:00
195d039904 完成3.7.1测试问题汇总的9 https://gitlab.ghzs.com/pm/halo-app-issues/issues/713 2019-12-01 21:54:28 +08:00
bcf77433b9 公告评论徽章入口 2019-12-01 21:47:02 +08:00
3a122a7137 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 21:41:18 +08:00
354d286a98 光环助手V3.7.1 RELEASE(20191201-1500)测试问题汇总(1.2.7) https://gitlab.ghzs.com/pm/halo-app-issues/issues/713 2019-12-01 21:41:06 +08:00
bfccc1c9b8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 21:14:26 +08:00
80767c17b2 光环助手V3.7.1 RELEASE(20191201-1500)测试问题汇总(5,8,10) https://gitlab.ghzs.com/pm/halo-app-issues/issues/713 2019-12-01 21:14:17 +08:00
0a9185462e 完成3.7.1测试问题汇总的3 https://gitlab.ghzs.com/pm/halo-app-issues/issues/713 2019-12-01 21:13:58 +08:00
c058d3f8c1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 20:57:05 +08:00
70655da2e7 限制网页标题变化 2019-12-01 20:57:00 +08:00
51f8c15af6 修复微信分享问题 2019-12-01 19:37:43 +08:00
20d6984057 首页轮播图加上占位符,图片加载完成再显示渐变阴影 2019-12-01 17:56:56 +08:00
f26813c137 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 17:26:38 +08:00
e2a265c3c7 光环助手V3.7.1 RELEASE(20191129-1730)测试问题汇总(1.2.3.4.5) https://gitlab.ghzs.com/pm/halo-app-issues/issues/712 2019-12-01 17:26:23 +08:00
e840daa340 禁用 webview 安全浏览 2019-12-01 17:23:37 +08:00
c54df5336d 光环助手V3.7.1 RELEASE(20191129-1730) 测试问题汇总https://gitlab.ghzs.com/pm/halo-app-issues/issues/712 2019-12-01 17:17:47 +08:00
4ec97409a8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 16:04:52 +08:00
31b5568dfa 轮播图初始化时定位到第一张
修复首页评分无法显示问题
2019-12-01 16:04:42 +08:00
10cfc6521d 修改个人主页MTA 2019-12-01 15:01:52 +08:00
bfdbc7fc92 修复单图跳转排行榜与多图跳转不一致的问题 2019-12-01 14:44:44 +08:00
ead332d863 修复安利墙闪退问题 2019-12-01 14:27:44 +08:00
b8fd666e84 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2019-12-01 14:20:10 +08:00
fb6e3637de 修复引导图显示异常问题 2019-12-01 14:19:03 +08:00
2db519f9e0 去掉多余的时间戳后缀 2019-12-01 14:10:11 +08:00
f55aeaf3d4 20191201测试https://gitlab.ghzs.com/pm/halo-app-issues/issues/682 2019-12-01 11:59:49 +08:00
2340d4957b 视频上传存草稿/提交防抖 补充 2019-12-01 11:05:25 +08:00
7bed914a92 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2019-12-01 11:04:05 +08:00
4b9f86a4bb 修复首页MTA统计异常事件 2019-12-01 11:01:22 +08:00
a1844e15e1 Merge remote-tracking branch 'origin/dev' into dev 2019-12-01 10:39:40 +08:00
148589a6c5 完成光环助手v3.7.1测试汇总的第5点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/711 2019-12-01 10:39:31 +08:00
2902a8b441 视频上传存草稿/提交防抖 2019-12-01 10:39:15 +08:00
b410016fae Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-12-01 10:23:05 +08:00
0d56448bfd 光环助手V3.7.1 DEV(20191129-1730)测试问题汇总(1.2.3) https://gitlab.ghzs.com/pm/halo-app-issues/issues/711 2019-12-01 10:22:55 +08:00
326c292572 评论详情徽章入口 2019-12-01 09:44:04 +08:00
afdaef1a64 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-29 18:27:35 +08:00
9bcd4b8e95 首页安利墙徽章入口 2019-11-29 18:27:30 +08:00
4d455f13b6 Merge remote-tracking branch 'origin/dev' into dev 2019-11-29 18:00:11 +08:00
94eea3aa90 完成光环助手v3.7.1测试汇总的第4点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/711 2019-11-29 18:00:02 +08:00
b00f47dd99 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-29 17:07:49 +08:00
20a4427e08 修改徽章入口问题 2019-11-29 17:07:43 +08:00
3287f31e2c 修复安利墙异常 MTA 异常事件 2019-11-29 17:02:24 +08:00
fbb6b01585 完成对已安装游戏标记为玩过游戏弹窗的排重处理 https://gitlab.ghzs.com/pm/halo-app-issues/issues/696 2019-11-29 16:33:06 +08:00
f07d1b7257 去掉旧引导遮罩 https://gitlab.ghzs.com/pm/halo-app-issues/issues/708 2019-11-29 16:20:22 +08:00
45d2d958a2 客服消息支持跳转至游戏详情评论tab https://gitlab.ghzs.com/pm/halo-app-issues/issues/683 2019-11-29 15:49:13 +08:00
2ba2498f6b Merge remote-tracking branch 'origin/dev' into dev 2019-11-29 15:40:08 +08:00
d76dada9f8 调整安利墙列表标签样式 2019-11-29 15:39:59 +08:00
28b63ee21b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-29 15:30:07 +08:00
90ea78eb39 首页相关标签颜色修改 2019-11-29 15:29:57 +08:00
0cda0e93f0 完成排行榜1129测试补充的第2点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/699 2019-11-29 15:00:20 +08:00
2e0469f915 完成安利墙1128测试补充的 2~5 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-29 14:43:15 +08:00
fdfbd23963 修改首页 bottom bar 图标 2019-11-29 10:13:36 +08:00
5f8b11f8e0 首页安利墙snap定位向右偏移4dp 2019-11-28 21:00:58 +08:00
a1df2f6ca6 首页UI调整 2019-11-28 20:34:58 +08:00
1d0d0e40de Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/layout/fragment_main.xml
#	app/src/main/res/values/dimens.xml
2019-11-28 19:55:08 +08:00
b3e5144cea 修改首页底部控制台UI
板块推荐入口接入安利墙/开服表
2019-11-28 19:49:32 +08:00
aed74449b0 更换引导图 2019-11-28 18:24:54 +08:00
45dc231024 完成10月第四周优化(8~12, 14) https://gitlab.ghzs.com/pm/halo-app-issues/issues/685 2019-11-28 18:17:13 +08:00
c1a223f120 完成"排行榜"功能1128测试补充 https://gitlab.ghzs.com/pm/halo-app-issues/issues/699 2019-11-28 17:26:51 +08:00
4a926997aa Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-28 16:48:36 +08:00
ae764b95fb DefaultJsApi添加跳转登录页面方法 2019-11-28 16:48:29 +08:00
7bba3f8b4d 游戏评分徽章入口图标优化 2019-11-28 16:47:38 +08:00
b2ad804d3c 微调微信登录结构 2019-11-28 15:29:08 +08:00
c49fa5cd3d 修复游戏预约微信提醒服务1128测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/675 2019-11-28 15:11:06 +08:00
92b5e28675 1128测试问题10 11(1)https://gitlab.ghzs.com/pm/halo-app-issues/issues/695 2019-11-28 11:55:03 +08:00
4afa5f6bc6 调整我的光环-微信预约位置 2019-11-28 11:42:10 +08:00
fbdc31aa97 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2019-11-28 11:22:36 +08:00
4eedfadc22 启动速度优化 2019-11-28 11:21:33 +08:00
3432a6c39f 1128测试问题(10)https://gitlab.ghzs.com/pm/halo-app-issues/issues/695 2019-11-28 10:42:55 +08:00
7e7c2180ce 更换广点通帐号 https://gitlab.ghzs.com/pm/yunying/issues/893 2019-11-28 10:22:33 +08:00
0386446a00 游戏评论编辑去除空行 2019-11-28 10:03:51 +08:00
09853e4187 标记已玩过的数据后页面刷新 2019-11-28 10:02:57 +08:00
40020fa617 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-28 09:39:14 +08:00
cc68c15824 处理空指针闪退 2019-11-28 09:38:48 +08:00
7aa874a0e3 修改问题草稿显示规则(草稿存储以社区ID为唯一标识,同设备可跨账号使用) 2019-11-28 09:38:46 +08:00
8203e5b568 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-27 20:31:44 +08:00
4f54bca286 首页安利墙交互修改
首页轮播图UI修改
首页去除“xxx想玩”
2019-11-27 20:31:31 +08:00
087479325d 完成 20191126测试(4)https://gitlab.ghzs.com/pm/halo-app-issues/issues/682 2019-11-27 18:31:40 +08:00
357b2c2a60 完成 1127测试问题(1-7)https://gitlab.ghzs.com/pm/halo-app-issues/issues/696 2019-11-27 18:16:09 +08:00
e1918b56e2 DownloadProgressBar add slide style 2019-11-27 16:11:49 +08:00
1f31d1e614 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-27 15:43:15 +08:00
f5468c5f11 首页UI间距调整 2019-11-27 15:43:08 +08:00
672cf331ea 评论徽章入口修改 2019-11-27 15:21:37 +08:00
348ad0faed 徽章系统入口及MTA数据统计 2019-11-27 15:02:33 +08:00
ae742547d8 调整安利墙随机逻辑 2019-11-26 17:24:52 +08:00
ff1c01c836 游戏评分增加来源 2019-11-26 16:45:48 +08:00
a645a3c929 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-26 16:15:31 +08:00
37c590400e 修复首页推荐入口有可能出现的闪退问题
修复首页刷新时轮播图动画异常问题
2019-11-26 16:15:21 +08:00
785e2d8cf5 适配启动页在挖孔屏上的状态栏显示 2019-11-26 15:38:39 +08:00
03d25cb102 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-26 15:21:44 +08:00
869dd9ac11 启动页添加启动图标 2019-11-26 15:21:38 +08:00
f647e172bd 调整安利墙下拉刷新进度指示的位置 2019-11-26 15:18:49 +08:00
7069200c6e 更换设置微信提醒图标 2019-11-26 14:26:00 +08:00
c61cfcbed9 优化首页刷新问题
修复轮播图游戏名显示异常问题
2019-11-26 11:38:53 +08:00
67eddc99ef 修复 data 后台数据上报异常 2019-11-26 09:57:15 +08:00
03fd5aaf09 修复部分安利墙页面专题点击闪退问题 2019-11-25 21:04:34 +08:00
31a8f5e5c7 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-25 18:26:12 +08:00
b7c6460c0e 修改评论光标问题 2019-11-25 18:26:07 +08:00
538c096b8f 修复部分安利墙页面的页面显示问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-25 18:13:59 +08:00
d05c738696 标记已安装游戏弹窗 2019-11-25 15:55:45 +08:00
976035da22 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-25 14:58:30 +08:00
d47fd51c7c 20191121测试(1,2)https://gitlab.ghzs.com/pm/halo-app-issues/issues/682 2019-11-25 14:58:20 +08:00
a047c65efd 适配后台游戏类型新增福利游戏 https://gitlab.ghzs.com/pm/halo-app-issues/issues/706 2019-11-25 09:12:53 +08:00
5bbb6b1c89 整理专题详情代码(删除用rows页面实现的排行榜代码) 2019-11-22 18:02:03 +08:00
95432cb591 修改首页下载按钮文案
修复首页刷新时可能会出现的闪退问题
2019-11-22 17:36:37 +08:00
04862e7f22 重新实现首页轮播图自动轮播逻辑 2019-11-22 17:16:29 +08:00
abafd0bb24 首页安利墙优化 2019-11-22 11:45:34 +08:00
aa83617796 专题排行榜 MTA数据统计 2019-11-21 18:14:02 +08:00
a5b8806997 重新实现专题排行榜 https://gitlab.ghzs.com/pm/halo-app-issues/issues/699 2019-11-21 17:53:55 +08:00
7a70c0158e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-20 15:27:31 +08:00
74f5972874 修复首页断网刷新问题 2019-11-20 15:27:16 +08:00
b01a29d2e9 修改冲突 2019-11-20 12:17:15 +08:00
88bd0dc9f5 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/layout/fragment_home.xml
2019-11-20 11:51:58 +08:00
c7b6d44874 对接个人主页徽章接口 2019-11-20 11:51:36 +08:00
8b6e01929b 完成 3.7.1 数据后台数据统计需求 https://gitlab.ghzs.com/pm/halo-app-issues/issues/706 2019-11-20 10:59:02 +08:00
2ecba00d2a 完成3.7.1 MTA数据统计需求 https://gitlab.ghzs.com/pm/halo-app-issues/issues/705 2019-11-20 10:18:02 +08:00
851fcaab13 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-19 17:37:49 +08:00
e1b9504421 修改安利墙游戏标签个数限制 2019-11-19 17:37:41 +08:00
247e8ed6cc 修复安利墙点赞数据刷新不及时的问题 2019-11-19 16:47:57 +08:00
996d1be136 拆分首页横向专题(补充) 2019-11-19 16:25:49 +08:00
a249d4d572 拆分首页横向专题 2019-11-19 16:16:39 +08:00
c91d52d753 优化自动轮播问题 2019-11-19 15:26:39 +08:00
0c37db444a 光环前端优化汇总(2019年10月第4周)(13.15)https://gitlab.ghzs.com/pm/halo-app-issues/issues/685 2019-11-19 10:02:58 +08:00
eb93f1d915 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-18 21:17:53 +08:00
74e6c9b145 轮播图,触控到轮播区域暂停自动轮播
双击底部导航栏时相关列表自动回到顶部
2019-11-18 21:17:47 +08:00
f15e630fd1 网络错误统计过滤初始化请求 2019-11-18 17:23:58 +08:00
01ee84caa8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-18 16:22:57 +08:00
311a1916d1 搜索工具栏修改 2019-11-18 16:22:50 +08:00
ae43ae1b97 修复安利墙嵌套专题导致顶部图片不跟随滑动的问题 2019-11-18 15:45:18 +08:00
d9814bbb1f 正式环境接口切换至 3.7.1 2019-11-18 11:17:26 +08:00
dba8abacf2 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-15 18:44:57 +08:00
3ee1474535 删除游戏模块原首页相关代码
光环助手V3.7.1-新增游戏库入口管理 https://gitlab.ghzs.com/pm/halo-app-issues/issues/697
2019-11-15 18:44:46 +08:00
8481e923ee 修改 EllipsizeTextView 2019-11-15 18:27:42 +08:00
53cfb0f078 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-15 18:22:23 +08:00
233277f6e8 TextView using Spannable,ellipsize doesn't work 2019-11-15 18:21:55 +08:00
dbd75cb513 光环前端优化汇总(2019年11月第3周)(21) https://gitlab.ghzs.com/pm/halo-app-issues/issues/703 2019-11-15 18:21:02 +08:00
bae14a54a1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-15 17:26:56 +08:00
9c48afca77 提问草稿规则优化 2019-11-15 17:26:46 +08:00
54ebc460fa 修复微博登录失效的问题 2019-11-15 17:24:50 +08:00
901e9a39f9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-15 17:16:13 +08:00
2ebd12c6db 主题颜色撤回更改 2019-11-15 17:16:05 +08:00
c762529b8b 更换主题颜色 2019-11-15 16:59:36 +08:00
3c371038cf 完成安利墙的旧首页功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-15 16:49:46 +08:00
0350c19c81 分离新首页的旧首页部分 2019-11-15 16:49:15 +08:00
ebace67201 提问问题增加草稿功能 2019-11-15 16:31:20 +08:00
cbe6e2e3bd 光环助手V3.7.1-隐藏评分支持修改(完成) https://gitlab.ghzs.com/pm/halo-app-issues/issues/687 2019-11-15 11:16:48 +08:00
4adefc885b 首页大图游戏设置随机占位符 2019-11-15 09:58:05 +08:00
cade2882e4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-14 16:52:01 +08:00
8c0f2fd527 补全首页相关的MTA统计 2019-11-14 16:51:53 +08:00
56809d8d66 光环前端优化汇总(2019年11月第3周)(20)https://gitlab.ghzs.com/pm/halo-app-issues/issues/703 2019-11-14 15:54:55 +08:00
14772494be 完成11月第三周测试汇总的 3,4,6,7,8,9 https://gitlab.ghzs.com/pm/halo-app-issues/issues/703 2019-11-14 11:22:49 +08:00
4bbec7344f 首页轮播图增加轮播定时器以及修改相关间距 2019-11-14 10:04:48 +08:00
9907863ef5 首页专题的一些回调由接口改为闭包 2019-11-13 17:33:17 +08:00
adfbe36fdf 调整首页专题合集回调结构 2019-11-13 17:09:28 +08:00
3cfb9ac1c3 完成首页相关的跳转以及部分MTA统计 2019-11-13 17:05:45 +08:00
2004b85a12 完成首页相关的跳转以及部分MTA统计 2019-11-13 17:00:59 +08:00
7dd3b5f122 完成新增"排行榜"功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/699 2019-11-13 16:31:49 +08:00
c849746a6f 光环助手V3.7.1-个人主页改版(第二期)MTA数据统计 2019-11-13 15:52:50 +08:00
a9582bc295 光环前端优化汇总(2019年11月第3周)(19)https://gitlab.ghzs.com/pm/halo-app-issues/issues/703 2019-11-13 15:06:07 +08:00
fd49defe00 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-13 11:43:12 +08:00
650a24775a 首页新增样式添加下载监听 2019-11-13 11:43:00 +08:00
b62a864a7d 添加安利墙评价内容标签 2019-11-13 09:53:26 +08:00
b76e10bdfc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-12 18:41:17 +08:00
4311205e62 光环前端优化汇总(2019年11月第3周)(11-18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/703 2019-11-12 18:41:12 +08:00
69bc1c971d 首页游戏部分Item的实现抽离到相应的ViewHolder 2019-11-12 17:39:38 +08:00
f13c720bcc 3.7.0-splash tinker base 2019-11-12 16:21:00 +08:00
63f66e9714 更换引导图 2019-11-12 16:14:54 +08:00
25d8ed079c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-12 16:05:03 +08:00
b923714b42 首页接入专题相关的下载监听 2019-11-12 16:04:54 +08:00
178295596a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-12 14:06:20 +08:00
2e1dae86e0 MTA数据统计 2019-11-12 14:05:08 +08:00
4bb0206d2d 完成安利墙假置顶 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-12 11:07:38 +08:00
23cda9c121 调整个人主页命名避免撞车 2019-11-12 11:06:17 +08:00
a1d0b59e28 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-11 19:40:31 +08:00
9de8e61b1b 新版首页兼容专题/插件化以及相关部分数据补全 2019-11-11 19:40:18 +08:00
be1188e8e4 安利墙列表更换数据结构 2019-11-11 18:41:43 +08:00
fdaefa52ab 补充安利墙搜索内容为空时的样式 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-11 18:25:11 +08:00
d667e70b90 完成部分安利墙搜索功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-11 17:45:27 +08:00
6184acc144 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-08 18:21:28 +08:00
6f012dc459 标记已玩过弹窗 2019-11-08 18:21:23 +08:00
94774c674a 首页游戏部分Item的实现抽离到相应的ViewHolder 2019-11-08 17:46:30 +08:00
3bda3354f0 3.7.0-servers_reverse-https tinker base 2019-11-08 15:52:45 +08:00
8a56459375 data host 由http改为https 2019-11-08 15:47:35 +08:00
aeb689648f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/values/colors.xml
2019-11-08 15:34:45 +08:00
761d4c3354 完成部分新版首页 https://gitlab.ghzs.com/pm/halo-app-issues/issues/678 2019-11-08 15:33:15 +08:00
90899e7d1f 整理 SearchActivity 代码 2019-11-08 11:10:52 +08:00
9e9d8b7149 引入 core-ktx 依赖 2019-11-08 11:09:31 +08:00
f774df532c 调整游戏详情页部分样式(细节待微调) https://gitlab.ghzs.com/pm/halo-app-issues/issues/685 2019-11-07 16:58:19 +08:00
d85c4533b7 完成简单的安利墙列表(暂缺首页专题) https://gitlab.ghzs.com/pm/halo-app-issues/issues/680 2019-11-07 16:56:46 +08:00
79aeca832a 更新版本至 3.7.1 2019-11-07 11:00:48 +08:00
50931b1fb6 修改删除评论崩溃 2019-11-07 09:42:46 +08:00
63bd0cdebb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-06 18:01:19 +08:00
8880d381db 完成光环助手V3.7.1-游戏详情评分优化(前端)https://gitlab.ghzs.com/pm/halo-app-issues/issues/682 2019-11-06 18:00:52 +08:00
4eccd3b2ac Merge remote-tracking branch 'origin/dev' into dev 2019-11-05 17:22:16 +08:00
716ba77d3e 完善微信绑定 2019-11-05 17:22:00 +08:00
4053eec64c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-05 16:57:36 +08:00
b11463b0f7 首页游戏,用recyclerView重新实现纵向滑动样式 2019-11-05 16:57:28 +08:00
109ada8e8b data 数据接口切换至 https 2019-11-05 16:49:03 +08:00
ab32670b40 3.7.0-servers_reverse tinker base 2019-11-05 10:50:58 +08:00
92f82099b5 总开服表开服/开测页面置换 2019-11-05 10:29:57 +08:00
e41b7434c9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-11-05 09:39:51 +08:00
9c79df6d6e 增加方法让内嵌网页知道是否处于测试环境 2019-11-04 18:18:39 +08:00
fe1f491104 Merge branch 'dev_3.7.1' into 'dev'
Dev 3.7.1

See merge request !8
2019-11-04 18:09:53 +08:00
652bdf9f1d 对接修改评论接口、取消游戏评论点赞 2019-11-04 17:30:49 +08:00
36b13d6d28 游戏评分取消点赞 2019-11-01 15:08:24 +08:00
53b58b63a2 主题修改 2019-11-01 10:51:40 +08:00
6b0f298a2d 移除由引导页进去主页的延迟操作 2019-10-31 18:18:04 +08:00
08bc8bc49e 补充提交遗漏文件 2019-10-31 12:12:23 +08:00
c8b436de94 Merge remote-tracking branch 'origin/dev_3.7.1' into dev_3.7.1 2019-10-31 11:51:00 +08:00
82b6323f72 补充提交遗漏代码 2019-10-31 11:50:49 +08:00
6664bc9e62 fix build error 2019-10-31 11:47:08 +08:00
544dc67d0d Merge branch 'dev_3.7.1' of gitlab.ghzs.com:halo/assistant-android into dev_3.7.1 2019-10-31 11:41:04 +08:00
d55c4d12bc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev_3.7.1
# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/gh/base/ToolBarActivity.java
2019-10-31 11:40:54 +08:00
707bc9bb1a ToolBarActivity和BaseActivity层级更换
设置启动默认闪屏图片(却缺失启动图片,待完成),防止启动时长时间处于无响应状态
2019-10-31 11:34:35 +08:00
41806eab54 基本完成游戏预约微信提醒服务的 APP 部分 https://gitlab.ghzs.com/pm/halo-app-issues/issues/675 2019-10-31 11:12:05 +08:00
443c3bf26a 测试环境接口切换至 3.7.1 2019-10-31 11:09:11 +08:00
7ac6e82624 内嵌网页新增绑定微信类型 2019-10-31 09:54:18 +08:00
87106de6d6 提供更多的 API 供内嵌网页调用 2019-10-30 18:17:18 +08:00
c52d94b003 Merge branch 'dev_3.7.1' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-30 16:55:37 +08:00
5ac13f2107 调整QQ,微博和微信等第三方登录相关的代码结构 2019-10-30 16:50:48 +08:00
9269548d64 V3.7.1游戏详情评分优化UI 2019-10-30 11:59:06 +08:00
370 changed files with 13393 additions and 4636 deletions

View File

@ -197,6 +197,7 @@ dependencies {
kapt "androidx.lifecycle:lifecycle-compiler:${lifeCycle}"
implementation "androidx.room:room-runtime:${room}"
implementation "androidx.room:room-rxjava2:${room}"
implementation "androidx.core:core-ktx:${ktx}"
kapt "androidx.room:room-compiler:${room}"
kapt "androidx.databinding:databinding-compiler:${databinding}"
@ -280,6 +281,8 @@ dependencies {
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.2'
implementation "com.airbnb.android:lottie:$lottie"
implementation project(':libraries:LGLibrary')
implementation project(':libraries:MTA')
implementation project(':libraries:QQShare')

Binary file not shown.

View File

@ -1,516 +1,559 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
package = "com.gh.gamecenter" >
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.gh.gamecenter">
<!-- 允许应用程序访问网络连接 -->
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许应用程序写入外部存储如SD卡上写文件 -->
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许应用程序读取扩展存储器 -->
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 允许挂载和反挂载文件系统可移动存储 -->
<uses-permission android:name = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 允许应用程序访问Wi-Fi网络状态信息 -->
<uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许应用程序获取网络信息状态 -->
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许应用程序读取电话状态 -->
<uses-permission android:name = "android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 允许应用程序获取当前或最近运行的应用 -->
<uses-permission android:name = "android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<!-- 允许访问振动设备 -->
<uses-permission android:name = "android.permission.VIBRATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 允许应用程序改变Wi-Fi连接状态 -->
<uses-permission android:name = "android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 允许应用程序打开系统窗口,显示其他应用程序 -->
<uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- 修改系统设置的权限 -->
<uses-permission android:name = "android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- bugly with tinker -->
<uses-permission android:name = "android.permission.READ_LOGS" />
<uses-permission android:name = "android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-sdk
tools:overrideLibrary="com.shuyu.gsyvideoplayer,
<uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,
com.shuyu.gsyvideoplayer.lib,
com.shuyu.gsyvideoplayer.armv7a,
com.shuyu.gsyvideoplayer.x86,
com.shuyu.gsy.base,
shuyu.com.androidvideocache"/>
shuyu.com.androidvideocache" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission android:name = "android.permission.READ_CONTACTS" tools:node = "remove"/>
<uses-permission
android:name="android.permission.READ_CONTACTS"
tools:node="remove" />
<supports-screens
android:anyDensity = "true"
android:largeScreens = "true"
android:normalScreens = "true"
android:resizeable = "true"
android:smallScreens = "true" />
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
<!--android:largeHeap = "true"-->
<application
android:name = "com.halo.assistant.TinkerApp"
android:allowBackup = "true"
android:icon = "@mipmap/logo"
android:label = "@string/app_name"
android:resizeableActivity = "true"
android:theme = "@style/AppCompatTheme.APP"
android:name="com.halo.assistant.TinkerApp"
android:allowBackup="true"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:largeHeap="true"
tools:targetApi = "n" >
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:targetApi="n">
<!--android:launchMode = "singleTask"-->
<activity
android:name = "com.gh.gamecenter.SplashScreenActivity"
android:configChanges = "keyboardHidden|orientation|screenSize"
android:screenOrientation = "portrait"
android:theme = "@style/AppGuideTheme" >
<intent-filter >
<action android:name = "android.intent.action.MAIN" />
android:name="com.gh.gamecenter.SplashScreenActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter >
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity >
</activity>
<activity
android:name = "com.gh.gamecenter.MainActivity"
android:launchMode = "singleTask"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateAlwaysHidden|adjustResize" />
android:name="com.gh.gamecenter.MainActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
<activity
android:name = "com.gh.gamecenter.DownloadManagerActivity"
android:launchMode = "singleTask"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.DownloadManagerActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<!--android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" 退出时屏幕抖动 -->
<activity android:name = "com.gh.gamecenter.ViewImageActivity" />
<activity
android:name = "com.gh.gamecenter.SearchActivity"
android:configChanges = "keyboardHidden"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.NewsDetailActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.SettingActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.ConcernActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.subject.SubjectActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.NewsSearchActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
<activity
android:name = "com.gh.gamecenter.GameNewsActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.CropImageActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.WebActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.ShareCardPicActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.ShareCardActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.MessageDetailActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.LibaoActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
<activity
android:name = "com.gh.gamecenter.LibaoDetailActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.ShareGhActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.CleanApkActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.SelectUserIconActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.AboutActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.CommentDetailActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.mygame.MyGameActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.GameDetailActivity"
android:configChanges = "orientation|screenSize|keyboardHidden"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.SuggestSelectActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.SuggestionActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.VoteActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateAlwaysHidden|adjustResize" />
<activity
android:name = "com.gh.gamecenter.ToolBoxActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
<activity android:name="com.gh.gamecenter.ViewImageActivity" />
<activity
android:name = "com.gh.gamecenter.WeiBoShareActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
android:name="com.gh.gamecenter.SearchActivity"
android:configChanges="keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<activity
android:name = ".category.CategoryDirectoryActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.amway.search.AmwaySearchActivity"
android:configChanges="keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<activity
android:name = ".category.CategoryListActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ShellActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.LoginActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
android:name="com.gh.gamecenter.NewsDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.UserInfoActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.SettingActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.UserRegionActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ConcernActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.CollectionActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.subject.SubjectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.MessageActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.NewsSearchActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.UserInfoEditActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
android:name="com.gh.gamecenter.GameNewsActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.search.AskSearchActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.CropImageActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.WebActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ShareCardPicActivity"
android:screenOrientation="portrait" />
<activity
android:name = ".qa.answer.fold.AnswerFoldActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ShareCardActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.ConcernInfoActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.LibaoActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.InfoActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.LibaoDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.MessageKeFuActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ShareGhActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.select.CommunitiesSelectActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.CleanApkActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.subject.CommunitySubjectActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.SelectUserIconActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.MessageInviteActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.AboutActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.MessageVoteActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.CommentDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = ".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.mygame.MyGameActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.myqa.MyAskActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.GameDetailActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.column.order.AskTabOrderActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.SuggestSelectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.QuestionEditActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.SuggestionActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.VoteActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
<activity
android:name = "com.gh.gamecenter.servers.add.AddKaiFuActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
android:name="com.gh.gamecenter.ToolBoxActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.servers.patch.PatchKaifuActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.WeiBoShareActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.BlockActivity"
android:screenOrientation = "portrait" />
android:name=".category.CategoryDirectoryActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity"
android:screenOrientation = "portrait" />
android:name=".category.CategoryListActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.NetworkDiagnosisActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.LoginActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.personalhome.fans.FansActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.UserInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.followers.FollowersActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.UserRegionActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.HomeActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.CollectionActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.edit.ArticleEditActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.MyArticleActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.UserInfoEditActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.qa.article.draft.ArticleDraftActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.search.AskSearchActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.detail.ArticleDetailActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateVisible" />
android:name=".qa.answer.fold.AnswerFoldActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryDetailActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.ConcernInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.InfoActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.GameActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageKeFuActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.select.CommunitiesSelectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.subject.CommunitySubjectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageVoteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity"
android:screenOrientation = "portrait" />
android:name=".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.tag.TagsActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.myqa.MyAskActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.SimpleArticleListActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.column.order.AskTabOrderActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.questions.edit.QuestionEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.servers.add.AddKaiFuActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.gh.gamecenter.servers.patch.PatchKaifuActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.BlockActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.amway.AmwayActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.NetworkDiagnosisActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.fans.FansActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.followers.FollowersActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.UserHomeActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.edit.ArticleEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.MyArticleActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.draft.ArticleDraftActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.detail.ArticleDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity"
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" />
<activity
android:name="com.gh.gamecenter.qa.editor.GameActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.tag.TagsActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.SimpleArticleListActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.video.videomanager.VideoManagerActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.video.upload.view.UploadVideoActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.editor.VideoActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.mygame.PlayedGameActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.servers.GameServersActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.game.upload.GameSubmissionActivity"
android:screenOrientation = "portrait"/>
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.comment.CommentActivity"
android:screenOrientation = "portrait"
android:theme = "@style/Theme.Transparent"
android:windowSoftInputMode = "adjustNothing" />
android:name="com.gh.gamecenter.qa.comment.CommentActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.Transparent"
android:windowSoftInputMode="adjustNothing" />
<activity android:name="com.gh.gamecenter.video.detail.VideoDetailActivity"
android:screenOrientation = "portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar"/>
<activity
android:name="com.gh.gamecenter.video.detail.VideoDetailActivity"
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
<activity
android:name = "com.gh.gamecenter.PushProxyActivity"
android:exported = "true"
android:theme = "@android:style/Theme.Translucent" />
android:name="com.gh.gamecenter.PushProxyActivity"
android:exported="true"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name = "com.gh.gamecenter.SkipActivity"
android:theme = "@style/Theme.AppCompat.Light.Fullscreen.Transparent" >
<intent-filter >
<data android:scheme = "ghzhushou" />
android:name="com.gh.gamecenter.SkipActivity"
android:theme="@style/Theme.AppCompat.Light.Fullscreen.Transparent">
<intent-filter>
<data android:scheme="ghzhushou" />
<category android:name = "android.intent.category.DEFAULT" />
<action android:name = "android.intent.action.VIEW" />
<category android:name = "android.intent.category.BROWSABLE" />
</intent-filter >
</activity >
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name = "${applicationId}.wxapi.WXEntryActivity"
android:exported = "true"
android:label = "@string/app_name"
android:launchMode = "singleTop"
android:screenOrientation = "portrait"
android:theme = "@android:style/Theme.Translucent.NoTitleBar" ></activity >
android:name="${applicationId}.wxapi.WXEntryActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
<provider
android:name = "androidx.core.content.FileProvider"
android:authorities = "${applicationId}"
android:exported = "false"
android:grantUriPermissions = "true" >
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name = "android.support.FILE_PROVIDER_PATHS"
android:resource = "@xml/provider_paths" />
</provider >
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<receiver
android:name = "com.gh.gamecenter.receiver.DownloadReceiver"
android:exported = "false" >
<intent-filter >
<action android:name = "com.gh.gamecenter.DOWNLOAD" />
</intent-filter >
</receiver >
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.gh.gamecenter.DOWNLOAD" />
</intent-filter>
</receiver>
<receiver
android:name = "com.gh.gamecenter.receiver.InstallReceiver"
android:exported = "false" >
<intent-filter >
<action android:name = "com.gh.gamecenter.INSTALL" />
</intent-filter >
</receiver >
android:name="com.gh.gamecenter.receiver.InstallReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.gh.gamecenter.INSTALL" />
</intent-filter>
</receiver>
<receiver
android:name = "com.gh.gamecenter.receiver.ActivitySkipReceiver"
android:exported = "true" >
<intent-filter >
<action android:name = "com.gh.gamecenter.ACTIVITYSKIP" />
</intent-filter >
</receiver >
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.gh.gamecenter.ACTIVITYSKIP" />
</intent-filter>
</receiver>
<receiver android:name = "com.gh.gamecenter.receiver.UmengMessageReceiver" >
<intent-filter >
<action android:name = "com.gh.gamecenter.UMENG" />
</intent-filter >
</receiver >
<receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">
<intent-filter>
<action android:name="com.gh.gamecenter.UMENG" />
</intent-filter>
</receiver>
<!--魅族push应用定义消息receiver声明 -->
<receiver android:name = "com.gh.gamecenter.receiver.MeizuPushReceiver" >
<intent-filter >
<receiver android:name="com.gh.gamecenter.receiver.MeizuPushReceiver">
<intent-filter>
<!-- 接收push消息 -->
<action android:name = "com.meizu.flyme.push.intent.MESSAGE" />
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<!-- 接收register消息 -->
<action android:name = "com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<!-- 接收unregister消息-->
<action android:name = "com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
<!-- 兼容低版本Flyme3推送服务配置 -->
<action android:name = "com.meizu.c2dm.intent.REGISTRATION" />
<action android:name = "com.meizu.c2dm.intent.RECEIVE" />
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name = "${applicationId}" />
</intent-filter >
</receiver >
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<receiver
android:name = "com.gh.common.im.ImReceiver"
android:enabled = "true" >
<intent-filter android:priority = "2147483647" >
<action android:name = "com.gh.im" />
<action android:name = "action_finish" />
</intent-filter >
</receiver >
android:name="com.gh.common.im.ImReceiver"
android:enabled="true">
<intent-filter android:priority="2147483647">
<action android:name="com.gh.im" />
<action android:name="action_finish" />
</intent-filter>
</receiver>
<service android:name = "com.gh.base.GHUmengNotificationService" />
<service android:name="com.gh.base.GHUmengNotificationService" />
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->
</application >
</application>
</manifest >
</manifest>

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,16 @@
package com.gh.base;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import com.gh.common.constant.Constants;
import com.gh.common.util.DataUtils;
@ -22,6 +26,7 @@ import com.gh.gamecenter.R;
import com.gh.gamecenter.SuggestionActivity;
import com.gh.gamecenter.eventbus.EBShowDialog;
import com.gh.gamecenter.suggest.SuggestType;
import com.lightgame.BaseAppCompatActivity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import com.tencent.tauth.Tencent;
@ -29,31 +34,39 @@ import com.tencent.tauth.Tencent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import androidx.annotation.NonNull;
import butterknife.ButterKnife;
import pub.devrel.easypermissions.EasyPermissions;
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
public abstract class BaseActivity extends BaseToolBarActivity implements EasyPermissions.PermissionCallbacks {
/**
* 只提供基础的服务(EventBus/ButterKnife/Share/GlobalDialog/Permissions)
* <p>
* 需要通道工具栏的页面请继承{@link ToolBarActivity}
*/
public abstract class BaseActivity extends BaseAppCompatActivity implements EasyPermissions.PermissionCallbacks {
// global dialog key
public final static String DOWNLOAD_HIJACK = "hijack";
public final static String DOWNLOAD_NOT_FOUND = "notfound";
public final static String LOGIN_EXCEPTION = "loginException";
public final static String PLUGGABLE = "plugin";
@NonNull
protected String mEntrance;
private boolean mIsPause;
private boolean mIsExistLogoutDialog;
protected final Handler mBaseHandler = new BaseHandler(this);
protected static class BaseHandler extends Handler {
private final WeakReference<BaseActivity> mActivityWeakReference;
BaseHandler(BaseActivity activity) {
@ -82,25 +95,9 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
}
}
// 小米沉浸式黑色字体
public void setStatusBarDarkMode(boolean darkmode, Activity activity) {
Class<? extends Window> clazz = activity.getWindow().getClass();
try {
int darkModeFlag = 0;
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
} catch (Exception ignore) {
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarDarkMode(true, this);
EventBus.getDefault().register(this);
ButterKnife.bind(this);
mEntrance = getIntent().getStringExtra(KEY_ENTRANCE);
@ -120,12 +117,6 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
super.onDestroy();
}
@Override
protected boolean onNavigationIconClicked() {
onBackPressed();
return true;
}
public void toast(String msg) {
Utils.toast(this, msg);
}
@ -134,10 +125,18 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
toast(getString(msg));
}
public void showShare(String url, String icon, String shareTitle, String shareSummary, ShareUtils.ShareType shareType) {
ShareUtils.getInstance(this).showShareWindows(this, getWindow().getDecorView(), url, icon, shareTitle, shareSummary, shareType);
public void showShare(String url,
String icon,
String shareTitle,
String shareSummary,
ShareUtils.ShareType shareType) {
ShareUtils.getInstance(this).showShareWindows(this,
getWindow().getDecorView(),
url,
icon,
shareTitle,
shareSummary,
shareType);
if (shareType == ShareUtils.ShareType.game || shareType == ShareUtils.ShareType.plugin) {
DataUtils.onEvent(this, "内容分享", shareTitle + shareSummary);
} else {
@ -147,21 +146,19 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(final EBShowDialog showDialog) {
if (!mIsPause && this.getClass().getName().equals(RunningUtils.getTopActivity(this))) {
if ("hijack".equals(showDialog.getType())) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
&& this.getClass().getName().equals(RunningUtils.getTopActivity(this))) {
if (DOWNLOAD_HIJACK.equals(showDialog.getType())) {
DialogUtils.showQqSessionDialog(this, "2586716223");// 建议用户联系客服
} else if ("plugin".equals(showDialog.getType())) {
DialogUtils.showPluginDialog(this, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
if (FileUtils.isEmptyFile(showDialog.getPath())) {
toast(R.string.install_failure_hint);
} else {
startActivity(PackageUtils.getUninstallIntent(BaseActivity.this, showDialog.getPath()));
}
} else if (PLUGGABLE.equals(showDialog.getType())) {
DialogUtils.showPluginDialog(this, () -> {
if (FileUtils.isEmptyFile(showDialog.getPath())) {
toast(R.string.install_failure_hint);
} else {
startActivity(PackageUtils.getUninstallIntent(BaseActivity.this, showDialog.getPath()));
}
});
} else if ("loginException".equals(showDialog.getType())) {
} else if (LOGIN_EXCEPTION.equals(showDialog.getType())) {
if (mIsExistLogoutDialog) return;
mIsExistLogoutDialog = true;
try {
@ -176,16 +173,15 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
"你的账号已在另外一台设备登录多设备-重新登录"))
);
mBaseHandler.postDelayed(() -> mIsExistLogoutDialog = false, 5000);
} catch (JSONException e) {
} catch (Exception e) {
e.printStackTrace();
}
} else if ("notfound".equals(showDialog.getType())) {
} else if (DOWNLOAD_NOT_FOUND.equals(showDialog.getType())) {
DialogUtils.showAlertDialog(this, "下载失败", "下载链接已失效,建议提交反馈"
, "立即反馈", "取消"
, () -> {
SuggestionActivity.startSuggestionActivity(this, SuggestType.gameQuestion,
null, showDialog.getPath() + ",问题反馈:下载链接失效");
}, null);
, () -> SuggestionActivity.startSuggestionActivity(this,
SuggestType.gameQuestion, null,
(showDialog.getPath() + ",问题反馈:下载链接失效")), null);
}
}
}
@ -194,33 +190,48 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
protected void onPause() {
TeaHelper.onPause(this);
super.onPause();
mIsPause = true;
}
@Override
protected void onResume() {
TeaHelper.onResume(this);
super.onResume();
mIsPause = false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
}
protected void setStatusBarColor(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(color);
}
}
/**
* 提供当前 activity 的中文名 (不重载的话为类名)
*/
public String getActivityNameInChinese() {
return getClass().getSimpleName();
}
/**
* @param entrance 上一个页面的链式入口名称
* @param path 当前页面名称
@ -237,8 +248,4 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
return StringUtils.buildString(entrance, "+(", path, ")");
}
@Override
protected boolean showDownloadMenu() {
return false;
}
}

View File

@ -2,15 +2,16 @@ package com.gh.base;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import android.view.View;
import com.gh.base.adapter.FragmentAdapter;
import com.gh.common.view.TabIndicatorView;
import com.gh.gamecenter.R;
import com.google.android.material.tabs.TabLayout;
import com.lightgame.view.NoScrollableViewPager;
import java.util.ArrayList;
@ -22,7 +23,7 @@ import butterknife.BindView;
* Created by khy on 15/03/18.
*/
public abstract class BaseActivity_TabLayout extends BaseActivity implements ViewPager.OnPageChangeListener {
public abstract class BaseActivity_TabLayout extends ToolBarActivity implements ViewPager.OnPageChangeListener {
public static final String PAGE_INDEX = "PAGE_INDEX";

View File

@ -27,7 +27,7 @@ import com.lightgame.utils.Utils
import com.lightgame.view.CheckableImageView
import kotterknife.bindView
abstract class BaseRichEditorActivity : BaseActivity() {
abstract class BaseRichEditorActivity : ToolBarActivity() {
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)

View File

@ -9,15 +9,14 @@ import android.view.View;
* Created by khy on 25/04/18.
*/
public abstract class onDoubleTapListener implements View.OnTouchListener {
public abstract class OnDoubleTapListener implements View.OnTouchListener {
private GestureDetector mGestureDetector;
public onDoubleTapListener(Context context) {
protected OnDoubleTapListener(Context context) {
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
onDoubleTapListener.this.onDoubleTap();
OnDoubleTapListener.this.onDoubleTap();
return true;
}
});
@ -26,7 +25,7 @@ public abstract class onDoubleTapListener implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
return false;
}
public abstract void onDoubleTap();

View File

@ -2,6 +2,6 @@ package com.gh.base;
import android.view.View;
public interface OnViewClickListener {
void onClick(View v, Object data);
public interface OnViewClickListener<T> {
void onClick(View v, T data);
}

View File

@ -1,5 +1,7 @@
package com.gh.base;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
@ -22,12 +24,13 @@ import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.normal.ToolbarController;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.lightgame.BaseAppCompatActivity;
import com.lightgame.OnTitleClickListener;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import androidx.annotation.DrawableRes;
@ -38,10 +41,12 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
/**
* Created by csheng on 15-10-12.
* 需要用到工具栏的页面使用
* <p>
* 特殊页面请参考{@link BaseActivity}
*/
public abstract class BaseToolBarActivity extends BaseAppCompatActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
public abstract class ToolBarActivity extends BaseActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
@Nullable
private PackageViewModel mPackageViewModel;
@ -56,6 +61,8 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarDarkMode(true, this);
initToolbar();
if (showDownloadMenu()) {
@ -64,6 +71,21 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
}
}
// 小米沉浸式黑色字体
@SuppressLint("PrivateApi")
public void setStatusBarDarkMode(boolean darkmode, Activity activity) {
Class<? extends Window> clazz = activity.getWindow().getClass();
try {
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
int darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
} catch (Exception ignore) {
}
}
private void initToolbar() {
mToolbar = findViewById(R.id.normal_toolbar);
mTitleTv = findViewById(R.id.normal_title);
@ -206,44 +228,18 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_download) {
// todo mEntrance set real value
MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, "");
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, mEntrance);
startActivity(intent);
}
return false;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
return onNavigationIconClicked();
}
return super.onOptionsItemSelected(item);
}
/**
* 提供当前 activity 的中文名 (不重载的话为类名)
*/
public String getActivityNameInChinese() {
return getClass().getSimpleName();
}
protected void setStatusBarColor(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(color);
}
}
protected abstract boolean onNavigationIconClicked();
protected View.OnClickListener provideNavigationItemClickListener() {
return view -> onBackPressed();
}
protected abstract boolean showDownloadMenu();
protected boolean showDownloadMenu() {
return false;
}
}

View File

@ -1,12 +1,13 @@
package com.gh.base.fragment;
import android.app.Dialog;
import androidx.lifecycle.Lifecycle;
import android.os.Bundle;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import android.view.KeyEvent;
import androidx.lifecycle.Lifecycle;
import com.gh.common.util.ClickUtils;
import com.gh.gamecenter.R;
@ -27,7 +28,7 @@ public class BaseDialogFragment extends DialogFragment {
final Dialog dialog = new Dialog(getActivity(), R.style.DialogWindowTransparent);
dialog.setCanceledOnTouchOutside(false);
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK && ClickUtils.isFastDoubleClick()) { //会多次响应??
if (keyCode == KeyEvent.KEYCODE_BACK && !ClickUtils.isFastDoubleClick()) {
return onBack();
}
return false;

View File

@ -10,13 +10,20 @@
package com.gh.base.fragment;
import android.os.Bundle;
import androidx.annotation.IdRes;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import androidx.annotation.IdRes;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import java.util.List;
/**
* ViewPager 配合ViewGroup Checkable实现双切换<br/>
@ -31,6 +38,8 @@ public abstract class BaseFragment_ViewPager_Checkable extends BaseFragment_View
protected ViewGroup mCheckableGroup;
private int mLastPosition = MainWrapperFragment.INDEX_HOME;
@IdRes
protected abstract int getCheckableGroupId();
@ -68,6 +77,33 @@ public abstract class BaseFragment_ViewPager_Checkable extends BaseFragment_View
@Override
public void onPageSelected(int index) {
onPageChanged(index);
try {
// 补充Viewpager Fragment的生命周期
if (mFragmentsList.size() > index) {
Fragment fragment = mFragmentsList.get(index);
fragment.onResume();
FragmentManager childFragmentManager = fragment.getChildFragmentManager();
List<Fragment> fragments = childFragmentManager.getFragments();
for (Fragment childFragment : fragments) {
childFragment.onResume();
}
}
if (mFragmentsList.size() > mLastPosition) {
Fragment fragment = mFragmentsList.get(mLastPosition);
fragment.onPause();
FragmentManager childFragmentManager = fragment.getChildFragmentManager();
List<Fragment> fragments = childFragmentManager.getFragments();
for (Fragment childFragment : fragments) {
childFragment.onPause();
}
}
mLastPosition = index;
} catch (Exception ignore) {
}
}
@Override

View File

@ -1,15 +1,29 @@
package com.gh.common
import android.annotation.SuppressLint
import android.content.Context
import android.webkit.JavascriptInterface
import androidx.annotation.Keep
import com.gh.base.CurrentActivityHolder
import com.gh.common.util.MtaHelper
import com.gh.common.util.toObject
import com.gh.common.util.*
import com.gh.gamecenter.LoginActivity
import com.gh.gamecenter.ViewImageActivity
import com.gh.gamecenter.entity.Badge
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.user.LoginTag
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException
import wendu.dsbridge.CompletionHandler
class DefaultJsApi {
class DefaultJsApi(var context: Context) {
@JavascriptInterface
fun isGhzs(msg: Any): String {
@ -28,6 +42,89 @@ class DefaultJsApi {
MtaHelper.onEvent(mtaEvent.name, mtaEvent.key, mtaEvent.value)
}
@JavascriptInterface
fun getUserInfo(msg: Any): String {
return UserManager.getInstance().userInfoEntity.toJson()
}
@JavascriptInterface
fun getUserToken(msg: Any): String {
return UserManager.getInstance().loginTokenEntity.accessToken.value
}
@JavascriptInterface
fun login(msg: Any) {
val intent = LoginActivity.getIntent(context, "浏览器")
context.startActivity(intent)
}
@JavascriptInterface
fun refreshUserInfoBadge(msg: Any) {
val userInfoEntity = UserManager.getInstance().userInfoEntity
if (msg.toString().isNotEmpty()) {
val badge = msg.toString().toObject() ?: Badge()
userInfoEntity.badge = badge
} else {
userInfoEntity.badge = null
}
UserManager.getInstance().userInfoEntity = userInfoEntity
AppDatabase.getInstance(context).userInfoDao().updateUserInfo(userInfoEntity)
}
@JavascriptInterface
fun getChannel(msg: Any): String {
return HaloApp.getInstance().channel
}
@JavascriptInterface
fun bindWechat(msg: Any, handler: CompletionHandler<Any>) {
context.ifLogin("浏览器") {
LoginHelper.loginWithWechat(object : LoginHelper.LoginCallback {
@SuppressLint("CheckResult")
override fun onLoginSuccess(loginType: LoginTag, jsonContent: JSONObject) {
val wechatLoginInfoMap = hashMapOf<String, String>()
wechatLoginInfoMap["openid"] = jsonContent.getString("openid")
wechatLoginInfoMap["unionid"] = jsonContent.getString("unionid")
wechatLoginInfoMap["access_token"] = jsonContent.getString("access_token")
wechatLoginInfoMap["refresh_token"] = jsonContent.getString("refresh_token")
RetrofitManager.getInstance(HaloApp.getInstance().application)
.api
.postBindWechat(wechatLoginInfoMap.createRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
handler.complete(true)
}
override fun onFailure(exception: Exception) {
handler.complete(false)
if (exception is HttpException) {
ErrorHelper.handleError(HaloApp.getInstance().application, exception.response().errorBody()?.string())
}
}
})
}
override fun onLoginFailure(loginType: LoginTag, error: String) {
handler.complete(false)
}
})
}
}
@JavascriptInterface
fun copyText(msg: Any) {
msg.toString().copyTextAndToast()
}
@JavascriptInterface
fun startApp(msg: Any) {
val packageName = msg.toString()
PackageUtils.launchApplicationByPackageName(HaloApp.getInstance().application, packageName)
}
@JavascriptInterface
fun openImage(event: Any) {

View File

@ -106,7 +106,6 @@ object DefaultWebViewUrlHandler {
context, typeId, communityId,
entrance, "文章链接")
}
DialogUtils.showLowVersionDialog(context)
}
else -> DialogUtils.showLowVersionDialog(context)
}

View File

@ -16,20 +16,24 @@ public class Constants {
public static final String USER_INFO_KEY = "userInfoKey";
public static final String DEVICE_KEY = "deviceKey";
public static final String HAS_REQUESTED_NOTIFICATION_PERMISSIONS = "has_requested_notification_permissions";
public static final String SHOULD_SHOW_VIDEO_MOBILE_WARNING = "should_show_video_mobile_warning";
public static final String GAME_DETAIL_COME_IN = "game_detail_come_in"; // 从游戏详情进入
public static final String XPOSED_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer";
public static final String EB_QUIT_LOGIN = "quit_login";
// 最近显示的弹窗信息
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_SHOWED_NOTIFICATION_HINT = "show_notification_hint";
//标记安装的游戏为已玩过弹窗最多取消2次
public static final String SP_MARK_INSTALLED_GAME = "mark_installed_game";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
@ -39,6 +43,14 @@ public class Constants {
//输入规则
public static final String INPUT_RULE = "0123456789abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ_";
// 微信绑定地址地址
public static final String WECHAT_BIND_ADDRESS_DEV = "https://resource.ghzs.com/page/wechat_dev/index.html#/";
public static final String WECHAT_BIND_ADDRESS = "https://resource.ghzs.com/page/wechat_pro/index.html#/";
// 徽章
public static final String BADGE_ADDRESS_DEV = "http://resource.ghzs.com/page/badge_dev/index.html#/";
public static final String BADGE_ADDRESS = "http://resource.ghzs.com/page/badge_pro/index.html#/";
//最少需要多少数据才能上传
public static final int DATA_AMOUNT = 20;
@ -58,6 +70,6 @@ public class Constants {
public static final String[] REPORT_LIST = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它"};
public static final String ENTRANCE_UNKNOWN = "(unknown)";
public static final String DEFAULT_TEXT_WRAPPER = "###";
}

View File

@ -9,6 +9,7 @@ public class ItemViewType {
public static final int GAME_SLIDE = 1; // 滚动图布局
public static final int GAME_NORMAL = 2; // 正常游戏布局
public static final int GAME_SUBJECT = 19;
public static final int GAME_SUBJECT_SLIDE = 26;
public static final int GAME_TEST = 3; // 测试游戏布局
public static final int GAME_IMAGE = 4; // 游戏大图布局
public static final int NEWS_HEADER = 5; // 新闻头部布局

View File

@ -1,7 +1,11 @@
package com.gh.common.databind;
import android.content.Intent;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@ -9,11 +13,20 @@ import android.widget.EditText;
import android.widget.LinearLayout;
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;
import com.gh.base.OnViewClickListener;
import com.gh.common.constant.Config;
import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.common.repository.ReservationRepository;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DisplayUtils;
@ -24,8 +37,9 @@ import com.gh.common.util.ImageUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.NumberUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.PermissionHelper;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.StringUtils;
import com.gh.common.util.ReservationHelper;
import com.gh.common.view.DownloadDialog;
import com.gh.common.view.DownloadProgressBar;
import com.gh.common.view.DrawableView;
@ -39,6 +53,7 @@ import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.entity.ServerCalendarEntity;
import com.gh.gamecenter.entity.TagStyleEntity;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.qa.entity.CommunityVideoEntity;
@ -52,10 +67,6 @@ import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/**
* Created by khy on 12/02/18.
*/
@ -308,8 +319,14 @@ public class BindingAdapters {
}
// 大图下的进度条
@BindingAdapter({"downloadButton", "traceEvent"})
public static void setDownloadButton(DownloadProgressBar progressBar, GameEntity gameEntity, ExposureEvent traceEvent) {
@BindingAdapter({"downloadButton", "traceEvent", "clickCallBack", "entrance", "location"})
public static void setDownloadButton(DownloadProgressBar progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@Nullable View.OnClickListener clickCallBack,
@Nullable String entrance,
@Nullable String location) {
// 判断是否显示按钮
if (gameEntity != null
&& Config.isShowDownload(gameEntity.getId())
@ -320,13 +337,101 @@ public class BindingAdapters {
return;
}
// 点击事件
progressBar.setOnClickListener(v -> {
if (clickCallBack != null) clickCallBack.onClick(v);
switch (progressBar.getDownloadType()) {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
break;
case NONE:
Utils.toast(v.getContext(), "该游戏已关闭下载");
break;
case NORMAL:
case PLUGIN:
if (gameEntity.getApk().size() == 1) {
ApkEntity apk = gameEntity.getApk().get(0);
DownloadDialogHelper.findAvailableDialogAndShow(
v.getContext(),
gameEntity,
apk,
() -> {
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
});
} else {
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
entrance, location + gameEntity.getName(), traceEvent);
}
break;
case LAUNCH_OR_OPEN:
if (gameEntity.getApk().size() == 1) {
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
} else {
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
entrance, location + gameEntity.getName(), traceEvent);
}
break;
case INSTALL_PLUGIN:
case INSTALL_NORMAL:
if (gameEntity.getApk().size() == 1) {
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
PackageUtils.launchSetup(v.getContext(), downloadEntity.getPath());
}
}
break;
case RESERVABLE:
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(progressBar.getContext(), () -> {
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
gameEntity,
() -> updateReservation(progressBar, gameEntity));
dialogFragment.show(((AppCompatActivity) progressBar.getContext()).getSupportFragmentManager(), "reserve");
});
});
break;
case RESERVED:
if ("download".equals(gameEntity.getReserveStatus())) {
ReservationHelper.showDeleteReservationDialog(progressBar.getContext(), () -> {
ReservationHelper.deleteReservation(gameEntity, () -> {
updateReservation(progressBar, gameEntity);
});
});
} else {
ReservationHelper.showCancelReservationDialog(progressBar.getContext(), () -> {
ReservationHelper.cancelReservation(gameEntity, () -> {
updateReservation(progressBar, gameEntity);
});
});
}
break;
}
});
// 显示预约
if (gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
progressBar.setText("预约");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.RESERVABLE);
} else {
progressBar.setText("已预约");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.RESERVED);
}
return;
}
// 显示下载按钮状态
if (gameEntity.getApk().isEmpty() || gameEntity.getDownloadOffStatus() != null) {
String offStatus = gameEntity.getDownloadOffStatus();
if (offStatus != null && "dialog".equals(offStatus)) {
progressBar.setText("查看");
} else {
progressBar.setText("暂无下载");
progressBar.setText("暂无");
}
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
} else {
@ -382,61 +487,30 @@ public class BindingAdapters {
}
}
}
// 点击事件
progressBar.setOnClickListener(v -> {
switch (progressBar.getDownloadType()) {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().get(0).getUrl(), "(我的光环:我的游戏)");
v.getContext().startActivity(intent);
break;
case NONE:
Utils.toast(v.getContext(), "该游戏已关闭下载");
break;
case NORMAL:
case PLUGIN:
if (gameEntity.getApk().size() == 1) {
ApkEntity apk = gameEntity.getApk().get(0);
DownloadDialogHelper.findAvailableDialogAndShow(
v.getContext(),
gameEntity,
apk,
() -> {
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe));
});
} else {
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
"(我的光环:我的游戏)", "我的光环-我的游戏:" + gameEntity.getName(), traceEvent);
}
break;
case LAUNCH_OR_OPEN:
if (gameEntity.getApk().size() == 1) {
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), "我的光环-我的游戏");
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
} else {
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
"(我的光环:我的游戏)", "我的光环-我的游戏:" + gameEntity.getName(), traceEvent);
}
break;
case INSTALL_PLUGIN:
case INSTALL_NORMAL:
if (gameEntity.getApk().size() == 1) {
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
PackageUtils.launchSetup(v.getContext(), downloadEntity.getPath());
}
}
break;
}
});
}
private static void updateReservation(DownloadProgressBar progressBar, GameEntity gameEntity) {
// 显示预约
if (gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
progressBar.setText("预约");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.RESERVABLE);
} else {
progressBar.setText("已预约");
progressBar.setDownloadType(DownloadProgressBar.DownloadType.RESERVED);
}
}
}
// 开始下载
private static void download(DownloadProgressBar progressBar, GameEntity
gameEntity, ExposureEvent traceEvent, boolean isSubscribe) {
private static void download(DownloadProgressBar progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
boolean isSubscribe,
String entrance,
String location) {
String str = progressBar.getText();
String method;
if (str.contains("更新")) {
@ -449,7 +523,7 @@ public class BindingAdapters {
ApkEntity apkEntity = gameEntity.getApk().get(0);
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
if (TextUtils.isEmpty(msg)) {
DataUtils.onGameDownloadEvent(progressBar.getContext(), gameEntity.getName(), apkEntity.getPlatform(), "(我的光环:我的游戏)", "下载开始", method);
DataUtils.onGameDownloadEvent(progressBar.getContext(), gameEntity.getName(), apkEntity.getPlatform(), entrance, "下载开始", method);
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, apkEntity.getPlatform(), traceEvent, ExposureUtils.DownloadType.DOWNLOAD);
@ -457,7 +531,8 @@ public class BindingAdapters {
apkEntity,
gameEntity,
method,
StringUtils.buildString("(我的光环:我的游戏)"), "我的光环-我的游戏:" + gameEntity.getName(),
entrance,
location + gameEntity.getName(),
isSubscribe,
downloadExposureEvent);
@ -494,9 +569,7 @@ public class BindingAdapters {
@BindingAdapter("isRefreshing")
public static void isRefreshing(SwipeRefreshLayout layout, LoadStatus status) {
if (status == LoadStatus.INIT_LOADING) {
layout.setRefreshing(true);
} else {
if (status != LoadStatus.INIT_LOADING && status != LoadStatus.LIST_LOADING) {
layout.setRefreshing(false);
}
}
@ -538,4 +611,33 @@ public class BindingAdapters {
mVideoDuration.setVisibility(View.GONE);
}
}
@BindingAdapter({"setGameTags", "setMaxGameTags"})
public static void setGameTags(TextView view, List<TagStyleEntity> tags, int maxTags) {
if (tags == null) {
view.setText("");
return;
}
int showCount = tags.size() > maxTags ? maxTags : tags.size(); // 最多显示3个
StringBuilder content = new StringBuilder();
for (int i = 0; i < showCount; i++) {
TagStyleEntity tag = tags.get(i);
content.append(tag.getName());
if (i != showCount - 1) content.append("/");
}
Spannable span = new SpannableString(content);
int index = 0;
for (int i = 0; i < showCount; i++) {
TagStyleEntity tag = tags.get(i);
int start = index;
int end = start + tag.getName().length() + ((i != showCount - 1) ? 1 : 0);
index = end;
span.setSpan(new ForegroundColorSpan(Color.parseColor("#" + tag.getColor())),
start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
view.setText(span);
}
}

View File

@ -25,6 +25,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
// 预约弹窗
class ReserveDialogFragment : BaseTrackableDialogFragment() {
@ -83,14 +84,14 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
mViewModel.reservation.observeNonNull(this) {
if (it.success) {
showSuccessDialog(it.withMobile)
showSuccessDialog(it.withMobile, it.boundWechat)
mSuccessCallback?.onSuccess()
}
}
dialog?.setCanceledOnTouchOutside(true)
}
private fun showSuccessDialog(withMobile: Boolean) {
private fun showSuccessDialog(withMobile: Boolean, boundWechat: Boolean) {
reserveHintTv.text = "游戏预约成功"
reserveContainer.visibility = View.GONE
reserveCompletedContainer.visibility = View.VISIBLE
@ -100,7 +101,7 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
reserveCompletedContentTv.text = dialogConfig?.htmlContent?.fromHtml()
if (dialogConfig?.text.isNullOrEmpty()
|| dialogConfig?.toLinkEntity()?.link.isNullOrEmpty()) {
|| (dialogConfig?.type == "wechat_bind" && boundWechat)) {
customizableBtn.visibility = View.GONE
} else {
customizableBtn.text = dialogConfig?.text
@ -176,7 +177,12 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
reservation.postValue(Reservation(success = true, withMobile = mobile.isNotEmpty()))
var boundWechat = false
tryWithDefaultCatch {
boundWechat = JSONObject(data.string() ?: "").getBoolean("wechat_bind")
}
reservation.postValue(Reservation(success = true, withMobile = mobile.isNotEmpty(), boundWechat = boundWechat))
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
MtaHelper.onEvent("预约游戏", "预约", gameName)
@ -188,6 +194,5 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
})
}
class Reservation(var success: Boolean = false, var withMobile: Boolean = false)
class Reservation(var success: Boolean = false, var withMobile: Boolean = false, var boundWechat: Boolean = false)
}

View File

@ -7,7 +7,7 @@ import android.view.KeyEvent
import com.gh.common.util.MtaHelper
import java.util.concurrent.atomic.AtomicBoolean
class TrackableDialog(context: Context,
open class TrackableDialog(context: Context,
themeResId: Int,
private var mEvent: String,
private var mKey: String,

View File

@ -1,5 +1,6 @@
package com.gh.common.util;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ClipboardManager;
import android.content.Context;
@ -20,11 +21,17 @@ import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.MeEntity;
import com.gh.gamecenter.entity.UserInfoEntity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@ -33,6 +40,9 @@ import java.util.List;
import java.util.Locale;
import androidx.core.content.ContextCompat;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.HttpException;
/**
@ -343,6 +353,16 @@ public class CommentUtils {
holder.commentLikeCountTv.setText(NumberUtils.transSimpleCount(entity.getVote()));
}
if (entity.getUser().getBadge() != null) {
holder.userBadgeSdv.setVisibility(View.VISIBLE);
holder.badgeNameTv.setVisibility(View.VISIBLE);
ImageUtils.display(holder.userBadgeSdv, entity.getUser().getBadge().getIcon());
holder.badgeNameTv.setText(entity.getUser().getBadge().getName());
} else {
holder.userBadgeSdv.setVisibility(View.GONE);
holder.badgeNameTv.setVisibility(View.GONE);
}
//检查是否是自身评论
UserInfoEntity userInfo = UserManager.getInstance().getUserInfoEntity();
if (userDataEntity != null && userDataEntity.isCommentOwner() && userInfo != null) {
@ -376,6 +396,36 @@ public class CommentUtils {
}
}
@SuppressLint("CheckResult")
public static void isUserCommentedOnThisGame(String gameId, WeakReference<SimpleCallback<Boolean>> callback) {
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
.getApi()
.isUserCommentedOnThisGame(UserManager.getInstance().getUserId(), gameId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<ResponseBody>() {
@Override
public void onSuccess(ResponseBody data) {
SimpleCallback<Boolean> cb = callback.get();
if (cb != null) {
try {
JSONObject object = new JSONObject(data.string());
cb.onCallback(object.getBoolean("status"));
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(@NotNull Exception exception) {
Utils.toast(HaloApp.getInstance().getApplication(), "网络异常");
}
});
}
//复制文字
public static void copyText(String copyContent, Context context) {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);

View File

@ -420,7 +420,7 @@ public class DialogUtils {
contentTv.setText(message);
titleTv.setText(title);
negativeTv.setText(negative);
negativeTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
//negativeTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
positiveTv.setText(positive);
negativeTv.setOnClickListener(new View.OnClickListener() {

View File

@ -11,15 +11,17 @@ import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.AppExecutor
import com.gh.common.util.EntranceUtils.*
import com.gh.gamecenter.*
import com.gh.gamecenter.amway.AmwayActivity
import com.gh.gamecenter.category.CategoryDirectoryActivity
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.mygame.PlayedGameActivity
import com.gh.gamecenter.personalhome.HomeActivity
import com.gh.gamecenter.personalhome.UserHomeActivity
import com.gh.gamecenter.qa.CommunityFragment
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.qa.article.SimpleArticleListActivity
@ -27,6 +29,7 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
import com.gh.gamecenter.servers.GameServersActivity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.suggest.SuggestType
import com.gh.gamecenter.tag.TagsActivity
@ -127,14 +130,27 @@ object DirectUtils {
display = linkEntity.display ?: Display())))
}
"column_collection" -> {
context.startActivity(ColumnCollectionDetailActivity.getIntent(context, linkEntity.link!!, entrance))
"column_collection" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
"server" -> {
context.startActivity(GameServersActivity.getIntent(context, entrance, path))
}
"top_game_comment" -> directToAmway(context, null, entrance, path)
"wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context))
else -> DialogUtils.showLowVersionDialog(context)
}
}
/**
* 跳转至专题合集
*/
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String) {
context.startActivity(ColumnCollectionDetailActivity.getIntent(context, id, position, entrance))
}
/**
* 跳转到新闻详情
*/
@ -147,9 +163,20 @@ object DirectUtils {
jumpActivity(context, bundle)
}
/**
* 跳转至个人主页
*/
@JvmStatic
fun directToHomeActivity(context: Context, userId: String?, entrance: String? = null, path: String? = null) {
context.startActivity(HomeActivity.getIntent(context, userId ?: "", entrance, path))
context.startActivity(UserHomeActivity.getIntent(context, userId ?: "", entrance, path))
}
/**
* 回到首页
*/
fun directToMainActivity(context: Context) {
val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_CLEAR_TOP }
context.startActivity(intent)
}
/**
@ -348,7 +375,7 @@ object DirectUtils {
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 1))
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
}
}
@ -396,4 +423,26 @@ object DirectUtils {
DialogUtils.showLowSystemVersionDialog(context)
}
}
/**
* 跳转至安利墙
* @param fixedTopAmwayCommentId 需要置顶的安利Id
*/
@JvmStatic
fun directToAmway(context: Context, fixedTopAmwayCommentId: String? = null, entrance: String? = null, path: String? = "") {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, AmwayActivity::class.java.name)
bundle.putString(KEY_ID, fixedTopAmwayCommentId)
bundle.putString(KEY_PATH, path)
jumpActivity(context, bundle)
}
/**
* 跳转至徽章墙
*/
@JvmStatic
fun directToBadgeWall(context: Context, userId: String?, name: String?, icon: String?) {
context.startActivity(WebActivity.getBadgeCenterIntent(context, userId, name, icon))
}
}

View File

@ -7,6 +7,12 @@ import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
@ -29,12 +35,6 @@ import com.lightgame.utils.Utils;
import java.util.concurrent.LinkedBlockingQueue;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
public class DownloadItemUtils {
// 更新下载进度条
@ -176,6 +176,7 @@ public class DownloadItemUtils {
if ("dialog".equals(offStatus)) {
holder.gameDownloadBtn.setText("查看");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
} else {
holder.gameDownloadBtn.setText("暂无");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
@ -367,6 +368,9 @@ public class DownloadItemUtils {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
downloadBtn.setOnClickListener(v -> {
CheckLoginUtils.checkLogin(context, entrance, () -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(context, () -> {
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
gameEntity,
@ -374,13 +378,13 @@ public class DownloadItemUtils {
);
dialogFragment.show(((AppCompatActivity) context).getSupportFragmentManager(), "reserve");
});
if (clickCallback != null) {
clickCallback.onCallback();
}
});
});
} else {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
if ("download".equals(gameEntity.getReserveStatus())) {
ReservationHelper.showDeleteReservationDialog(context, () -> {
ReservationHelper.deleteReservation(gameEntity, () -> {
@ -402,10 +406,10 @@ public class DownloadItemUtils {
if (gameEntity.getApk().size() == 1) {
downloadBtn.setOnClickListener(v -> {
EmptyCallback clickRunnable = () -> {
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent);
if (clickCallback != null) {
clickCallback.onCallback();
}
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent);
};
// 启动不需要请求存储权限
@ -417,11 +421,11 @@ public class DownloadItemUtils {
});
} else {
downloadBtn.setOnClickListener(v -> {
if (clickCallback != null) {
clickCallback.onCallback();
}
PermissionHelper.checkStoragePermissionBeforeAction(context, () -> {
DownloadDialog.getInstance(context).showPopupWindow(v, gameEntity, entrance, location, traceEvent);
if (clickCallback != null) {
clickCallback.onCallback();
}
});
});
}

View File

@ -46,6 +46,7 @@ public class EntranceUtils {
public static final String KEY_TYPE = "type";
public static final String KEY_LINK = "link";
public static final String KEY_NAME = "name";
public static final String KEY_POSITION = "position";
public static final String KEY_ENTRANCE = "entrance";
public static final String KEY_TARGET = "target";
public static final String ENTRANCE_BROWSER = "(浏览器)";
@ -65,6 +66,7 @@ public class EntranceUtils {
public static final String KEY_LOCATION = "location";
public static final String KEY_CURRENTITEM = "currentItem";
public static final String KEY_COMMENTID = "commentId";
public static final String KEY_SHOW_KEYBOARD_IF_NEEDED = "show_key_board_if_needed";
public static final String KEY_PATH = "path";
public static final String KEY_OUTER_INFO = "outerInfo";
public static final String KEY_OLDERUSER = "isOldUser";
@ -120,6 +122,7 @@ public class EntranceUtils {
public static final String KEY_VIDEO_ID = "videoId";
public static final String KEY_DIRECT_COMMENT = "directComment";
public static final String KEY_SORT = "sort";
public static final String KEY_AMWAY = "amway";
public static final String KEY_COLLECTION_ID = "collectionId";
public static final String KEY_NAVIGATION_TITLE = "navigationTitle";

View File

@ -111,6 +111,8 @@ object ErrorHelper {
403018 -> Utils.toast(context, R.string.comment_failed_unable)
403070 -> Utils.toast(context, "请勿重复提交~")
403073 -> Utils.toast(context, "标题可能包含敏感词,请修改后再提交")
403074 -> Utils.toast(context, "该微信号(${errorEntity.data?.nickname})已绑定")
403078 -> Utils.toast(context, "已点赞")
403020 -> if (showHighPriorityHint) {
DialogUtils.showAlertDialog(context,

View File

@ -79,6 +79,21 @@ fun ViewPager.addOnPageChangeListener(onSelected: ((position: Int) -> Unit)? = n
addOnPageChangeListener(listener)
}
fun ViewPager.addOnScrollStateChanged(onStateChanged: ((state: Int) -> Unit)? = null) {
val listener = object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
onStateChanged?.invoke(state)
}
}
addOnPageChangeListener(listener)
}
/**
* RecyclerView Extensions
*/
@ -353,7 +368,7 @@ fun FragmentActivity.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
/**
* TextView related.
*/
fun TextView.setTextWithHighlightedTextWrappedInsideWrapper(text: String,
fun TextView.setTextWithHighlightedTextWrappedInsideWrapper(text: CharSequence,
wrapper: String = Constants.DEFAULT_TEXT_WRAPPER,
@ColorRes
highlightColorId: Int = R.color.theme,

View File

@ -8,6 +8,8 @@ import org.json.JSONObject
/**
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
*
* 更换帐号 [https://gitlab.ghzs.com/pm/yunying/issues/893]
*/
object GdtHelper {
@ -21,7 +23,7 @@ object GdtHelper {
const val PLATFORM = "PLATFORM"
fun init(application: Application) {
GDTAction.init(application, "1108222478", "0b2bb2b971c8221be45a8454f05a0b1f")
GDTAction.init(application, "1110071928", "7fe03caa04ed382e9dce401312b1d0ae")
}
fun logAction(type: String) {

View File

@ -1,303 +0,0 @@
package com.gh.common.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.gh.gamecenter.user.LoginTag;
import com.lightgame.utils.RuntimeUtils;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.WbSdk;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WbAuthListener;
import com.sina.weibo.sdk.auth.WbConnectErrorMessage;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
/**
* Created by khy on 14/06/17.
* <p>
* 获取第三方登录数据
*/
public class GetLoginDataUtils {
private static GetLoginDataUtils instance;
private Context mContext;
private OnLoginDataListener mLoginListener; //登录成功回调
private Tencent mTencent;
private IWXAPI mIWXAPI;
private SsoHandler mSsoHandler;
private Oauth2AccessToken mAccessToken; // weibo
public static final String SCOPE =
"email,direct_messages_read,direct_messages_write,"
+ "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
+ "follow_app_official_microblog," + "invitation_write"; // weiboCode
private GetLoginDataUtils(Context context) {
mContext = context;
mTencent = Tencent.createInstance(Config.TENCENT_APPID, mContext); //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(mContext, Config.WECHAT_APPID, true); //初始化微信分享
WbSdk.install(context, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", SCOPE));
Utils.log(GetLoginDataUtils.class.getSimpleName(), "initLogin");
}
public static GetLoginDataUtils getInstance(Context context) {
if (instance == null) {
instance = new GetLoginDataUtils(context.getApplicationContext());
}
return instance;
}
//QQ登录回调处理
public IUiListener QqLoginListener = new IUiListener() {
@Override
public void onComplete(Object o) {
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQ 登录成功");
if (o instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) o;
String s = jsonObject.toString();
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQLoginComplete::" + s);
try {
mTencent.setOpenId(jsonObject.getString("openid"));
mTencent.setAccessToken(jsonObject.getString("access_token"), jsonObject.getString("expires_in"));
JSONObject content = new JSONObject();
content.put("openid", jsonObject.getString("openid"));
content.put("access_token_expire", Utils.getTime(mContext) + jsonObject.getLong("expires_in"));
content.put("access_token", jsonObject.getString("access_token"));
if (mLoginListener != null) {
mLoginListener.OnLoginData(content, LoginTag.qq);// QQ 登录回调
}
} catch (JSONException e) {
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQ登录数据回调异常" + e.toString());
e.printStackTrace();
}
}
// QQToken qqToken = mTencent.getQQToken();
// UserInfo userInfo = new UserInfo(mContext, qqToken);
// userInfo.getUserInfo(new IUiListener() { // 获取QQ用户信息
// @Override
// public void onComplete(Object o) {
// Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQUserInfo::" + o.toString());
// }
//
// @Override
// public void onError(UiError uiError) {
// Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQUserInfoUiError::" + uiError.errorDetail + "==" + uiError.errorMessage + "==" + uiError.errorCode);
// }
//
// @Override
// public void onCancel() {
// Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQUserInfoonCancel");
// }
// });
}
@Override
public void onError(UiError uiError) {
Utils.toast(mContext, "登录失败");
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQ 登录失败");
}
@Override
public void onCancel() {
Utils.toast(mContext, "登录取消");
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQ 登录取消");
}
};
public void onQQCallback(int requestCode, int resultCode, Intent data) {
Tencent.onActivityResultData(requestCode, resultCode, data, QqLoginListener);
}
// QQ登录
public void QQLogin(OnLoginDataListener listener, Activity activity) {
mLoginListener = listener;
if (mTencent != null && !mTencent.isSessionValid()) {
Utils.log(GetLoginDataUtils.class.getSimpleName(), "QQLogin");
mTencent.login(activity, "all", QqLoginListener);
}
}
public void QQLogout() {
if (mTencent != null && mTencent.isSessionValid()) {
mTencent.logout(mContext);
}
}
// 微信登录
public void WCLogin(OnLoginDataListener listener) {
mLoginListener = listener;
if (mIWXAPI != null) {
boolean register = mIWXAPI.registerApp(Config.WECHAT_APPID);
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = mContext.getString(R.string.app_name);
boolean b = mIWXAPI.sendReq(req);
Utils.log(GetLoginDataUtils.class.getSimpleName(), "微信注册状态::" + register + "\n 发送状态::" + b);
if (!register || !b) {
Utils.toast(mContext, "请检查是否安装微信客户端");
}
}
}
public void WCLoginCallBack(JSONObject content) {
if (mLoginListener != null) {
mLoginListener.OnLoginData(content, LoginTag.wechat);
}
}
public void onWeiboCallback(int requestCode, int resultCode, Intent data) {
if (mSsoHandler != null) {
mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
}
}
// 微博登录
public void WeiBoLogin(OnLoginDataListener listener, Activity context) {
mSsoHandler = new SsoHandler(context);
mLoginListener = listener;
mSsoHandler.authorizeClientSso(new SelfWbAuthListener());
// 第一次启动本应用AccessToken 不可用
mAccessToken = AccessTokenKeeper.readAccessToken(mContext);
// if (mAccessToken.isSessionValid()) {
// updateTokenView(true);
// }
}
// 微博登录回调处理
private class SelfWbAuthListener implements WbAuthListener {
@Override
public void onSuccess(final Oauth2AccessToken token) {
RuntimeUtils.getInstance().runOnUiThread(new Runnable() {
@Override
public void run() {
mAccessToken = token;
if (mAccessToken.isSessionValid()) {
// 显示 Token
// updateTokenView(false);
// 保存 Token 到 SharedPreferences
AccessTokenKeeper.writeAccessToken(mContext, mAccessToken);
Toast.makeText(mContext, "授权成功", Toast.LENGTH_SHORT).show();
}
}
});
JSONObject content = new JSONObject();
try {
content.put("uid", token.getUid());
content.put("access_token", token.getToken());
content.put("access_token_expire", Utils.getTime(mContext) + token.getExpiresTime());
content.put("refresh_token", token.getRefreshToken());
// content.put("refresh_token_expire", Utils.getTime(mContext) + 86400 * 30); // refresh_token 有效期30天
if (mLoginListener != null) {
mLoginListener.OnLoginData(content, LoginTag.weibo);// 微博 登录回调
}
} catch (JSONException e) {
e.printStackTrace();
}
// AppController.MAIN_EXECUTOR.execute(new Runnable() {
// @Override
// public void run() {
// getWeiBoUserInfo(token.getToken(), token.getUid());
// }
// });
}
@Override
public void cancel() {
Utils.toast(mContext, "取消授权");
}
@Override
public void onFailure(WbConnectErrorMessage errorMessage) {
Utils.toast(mContext, "微博登录需要客户端支持,请先安装微博");
}
}
//微博 获取用户信息
private void getWeiBoUserInfo(String accessToken, String uid) {
String path = "https://api.weibo.com/2/users/show.json?access_token=" + accessToken + "&uid=" + uid;
Utils.log(GetLoginDataUtils.class.getSimpleName(), "getWeiBoUserInfo-url::" + path);
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
int code = conn.getResponseCode();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
Utils.log(GetLoginDataUtils.class.getSimpleName(), "getWeiBoUserInfo-RequestCode::" + code);
if (code == 200) {
InputStream is = conn.getInputStream();
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
String str = new String(baos.toByteArray());
Utils.log(GetLoginDataUtils.class.getSimpleName(), "getWeiBoUserInfo-Body::" + str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 微博显示当前 Token 信息。
*
* @param hasExisted 配置文件中是否已存在 token 信息并且合法
*/
private void updateTokenView(boolean hasExisted) {
String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(
new java.util.Date(mAccessToken.getExpiresTime()));
String format = "Token%1$s \\n有效期%2$s";
String token = String.format(format, mAccessToken.getToken(), date);
Utils.log(GetLoginDataUtils.class.getSimpleName(), "::WB_TOKEN::" + token);
String message = String.format(format, mAccessToken.getToken(), date);
if (hasExisted) {
message = "Token 仍在有效期内,无需再次登录。" + "\n" + message;
}
Utils.log(GetLoginDataUtils.class.getSimpleName(), "::WB_MESSAGE::" + message);
}
// 登录成功回调
public interface OnLoginDataListener {
void OnLoginData(JSONObject content, LoginTag loginTag);
}
}

View File

@ -0,0 +1,196 @@
package com.gh.common.util
import android.app.Activity
import android.content.Intent
import android.widget.Toast
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import com.gh.gamecenter.user.LoginTag
import com.halo.assistant.HaloApp
import com.lightgame.utils.RuntimeUtils
import com.lightgame.utils.Utils
import com.sina.weibo.sdk.WbSdk
import com.sina.weibo.sdk.auth.AuthInfo
import com.sina.weibo.sdk.auth.Oauth2AccessToken
import com.sina.weibo.sdk.auth.WbAuthListener
import com.sina.weibo.sdk.auth.WbConnectErrorMessage
import com.sina.weibo.sdk.auth.sso.SsoHandler
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.tencent.tauth.IUiListener
import com.tencent.tauth.Tencent
import com.tencent.tauth.UiError
import org.json.JSONException
import org.json.JSONObject
/**
* 第三方登录辅助类
*/
object LoginHelper {
const val WEIBO_SCOPE = (
"email,direct_messages_read,direct_messages_write,"
+ "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
+ "follow_app_official_microblog," + "invitation_write") // weiboCode
private var mTencent: Tencent // QQ
private var mIWXAPI: IWXAPI // 微信
private var mSsoHandler: SsoHandler? = null // 微博 // TODO 完成回调时清掉这个 handler
private var mQqLoginListener: IUiListener
private var mAccessToken: Oauth2AccessToken? = null // weibo
private var mLoginCallback: LoginCallback? = null
init {
val context = HaloApp.getInstance().application.applicationContext
mTencent = Tencent.createInstance(Config.TENCENT_APPID, context) //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(context, Config.WECHAT_APPID, true) //初始化微信分享
mQqLoginListener = object : IUiListener {
override fun onComplete(o: Any?) {
Utils.log("QQ 登录成功")
if (o is JSONObject) {
val s = o.toString()
Utils.log("QQLoginComplete::$s")
try {
mTencent.openId = o.getString("openid")
mTencent.setAccessToken(o.getString("access_token"), o.getString("expires_in"))
val content = JSONObject()
content.put("openid", o.getString("openid"))
content.put("access_token_expire", Utils.getTime(context) + o.getLong("expires_in"))
content.put("access_token", o.getString("access_token"))
mLoginCallback?.onLoginSuccess(LoginTag.qq, content) // 回调QQ登录成功
} catch (e: JSONException) {
val errorString = "QQ登录数据回调异常$e"
mLoginCallback?.onLoginFailure(LoginTag.qq, errorString) // 回调QQ登录失败
Utils.log(errorString)
e.printStackTrace()
}
}
}
override fun onCancel() {
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录取消")
Utils.log("QQ 登录取消")
}
override fun onError(p0: UiError?) {
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录失败")
Utils.log("QQ 登录失败")
}
}
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
Utils.log("LoginHelper initialization")
}
@JvmStatic
fun onQQLoginCallback(requestCode: Int, resultCode: Int, data: Intent?) {
Tencent.onActivityResultData(requestCode, resultCode, data, mQqLoginListener);
}
@JvmStatic
fun onWechatLoginSuccess(content: JSONObject) {
mLoginCallback?.onLoginSuccess(LoginTag.wechat, content)
}
@JvmStatic
fun onWechatLoginFailure(error: String) {
mLoginCallback?.onLoginFailure(LoginTag.wechat, error)
}
@JvmStatic
fun onWeiboLoginCallback(requestCode: Int, resultCode: Int, data: Intent?) {
mSsoHandler?.authorizeCallBack(requestCode, resultCode, data)
}
// QQ登录
@JvmStatic
fun loginWithQQ(loginCallback: LoginCallback, activity: Activity) {
mLoginCallback = loginCallback
if (!mTencent.isSessionValid) {
Utils.log("QQLogin")
mTencent.login(activity, "all", mQqLoginListener)
}
}
@JvmStatic
fun logoutWithQQ() {
if (mTencent.isSessionValid) {
mTencent.logout(HaloApp.getInstance().application.applicationContext)
}
}
// 微信登录
@JvmStatic
fun loginWithWechat(loginCallback: LoginCallback) {
mLoginCallback = loginCallback
val register = mIWXAPI.registerApp(Config.WECHAT_APPID)
val req = SendAuth.Req()
req.scope = "snsapi_userinfo"
req.state = HaloApp.getInstance().application.getString(R.string.app_name)
val b = mIWXAPI.sendReq(req)
Utils.log("微信注册状态::$register\n 发送状态::$b")
if (!register || !b) {
loginCallback.onLoginFailure(LoginTag.wechat, "请检查是否安装微信客户端")
Utils.toast(HaloApp.getInstance().application, "请检查是否安装微信客户端")
}
}
// 微博登录
@JvmStatic
fun loginWithWeibo(loginCallback: LoginCallback, context: Activity) {
mLoginCallback = loginCallback
mSsoHandler = SsoHandler(context)
mSsoHandler?.authorizeClientSso(object : WbAuthListener {
override fun onSuccess(token: Oauth2AccessToken?) {
token?.let {
RuntimeUtils.getInstance().runOnUiThread {
mAccessToken = token
if (mAccessToken?.isSessionValid == true) {
// 保存 Token 到 SharedPreferences
AccessTokenKeeper.writeAccessToken(context, mAccessToken)
Toast.makeText(context, "授权成功", Toast.LENGTH_SHORT).show()
}
}
val content = JSONObject()
tryWithDefaultCatch {
content.put("uid", token.uid)
content.put("access_token", token.token)
content.put("access_token_expire", Utils.getTime(context) + token.expiresTime)
content.put("refresh_token", token.refreshToken)
// content.put("refresh_token_expire", Utils.getTime(mContext) + 86400 * 30); // refresh_token 有效期30天
mLoginCallback?.onLoginSuccess(LoginTag.weibo, content)// 微博 登录回调
}
}
}
override fun onFailure(p0: WbConnectErrorMessage?) {
mLoginCallback?.onLoginFailure(LoginTag.weibo, "微博登录需要客户端支持,请先安装微博")
}
override fun cancel() {
mLoginCallback?.onLoginFailure(LoginTag.weibo, "取消授权")
}
})
// 第一次启动本应用AccessToken 不可用
mAccessToken = AccessTokenKeeper.readAccessToken(context)
}
interface LoginCallback {
fun onLoginSuccess(loginType: LoginTag, jsonContent: JSONObject)
fun onLoginFailure(loginType: LoginTag, error: String)
}
}

View File

@ -49,6 +49,10 @@ object MtaHelper {
}
}
if (prop.size == 0 && kv.size == 1) {
prop.setProperty(kv[0], kv[0])
}
if (prop.size == 0) return
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)

View File

@ -7,9 +7,9 @@ object NumberUtils {
@JvmStatic
fun transSimpleCount(count: Int): String {
val s: String
s = if (count > 100000) {
s = if (count > 10000) {
val number = count / 10000f
val fmt = DecimalFormat("#")
val fmt = DecimalFormat("#.0")
fmt.format(number) + ""
} else {
count.toString()

View File

@ -1,5 +1,9 @@
package com.gh.common.util;
import androidx.annotation.ColorRes;
import com.gh.gamecenter.R;
import java.math.BigDecimal;
import java.util.Random;
@ -44,6 +48,7 @@ public class RandomUtils {
/**
* 四舍五入取整
*
* @return
*/
public static int getInt(double d) {
@ -51,4 +56,13 @@ public class RandomUtils {
return bigDecimal.intValue();
}
public static final int[] placeholderColors = {
R.color.placeholder_5C8399, R.color.placeholder_5C9599,
R.color.placeholder_6F5EA8, R.color.placeholder_996283,
R.color.placeholder_748054, R.color.placeholder_946262};
@ColorRes
public static int getRandomPlaceholderColor() {
return placeholderColors[nextInt(placeholderColors.length - 1)];
}
}

View File

@ -69,8 +69,8 @@ object ReservationHelper {
context,
"删除预约",
"游戏已上线,你可以删除此预约记录,确定删除吗?",
"确定",
"取消",
"确定删除",
"暂不删除",
{ emptyCallback.onCallback() },
null,
trackMtaEvent = true,

View File

@ -53,7 +53,7 @@ import java.util.List;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import static com.gh.common.util.GetLoginDataUtils.SCOPE;
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
/**
* Created by khy on 2016/9/4.
@ -122,7 +122,7 @@ public class ShareUtils {
private ShareUtils(Context context) {
mTencent = Tencent.createInstance(Config.TENCENT_APPID, context); //初始化QQ分享
mIWXAPI = WXAPIFactory.createWXAPI(context, Config.WECHAT_APPID); //初始化微信分享
WbSdk.install(context, new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", SCOPE));
WbSdk.install(context, new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
mContext = context.getApplicationContext();
}

View File

@ -82,4 +82,11 @@ object SPUtils {
sp.edit().putString(key, value).apply()
}
}
@JvmStatic
fun remove(key: String) {
val editor = sp.edit()
editor.remove(key)
editor.apply()
}
}

View File

@ -0,0 +1,61 @@
package com.gh.common.util
import android.content.Context
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import com.gh.common.view.CenterImageSpan
class SpanBuilder(content: String) {
private var spannableString: SpannableStringBuilder = SpannableStringBuilder(content)
fun color(context: Context, start: Int, end: Int, colorRes: Int): SpanBuilder {
val colorSpan = ForegroundColorSpan(ContextCompat.getColor(context, colorRes))
spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
fun size(start: Int, end: Int, dpSize: Int): SpanBuilder {
val s = AbsoluteSizeSpan(dpSize, true)
spannableString.setSpan(s, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
//删除线
fun strikeThrough(start: Int, end: Int): SpanBuilder {
val strike = StrikethroughSpan()
spannableString.setSpan(strike, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
//加粗
fun bold(start: Int, end: Int): SpanBuilder {
val styleSpan = StyleSpan(Typeface.BOLD)
spannableString.setSpan(styleSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
//正常字体
fun normal(start: Int, end: Int): SpanBuilder {
val styleSpan = StyleSpan(Typeface.NORMAL)
spannableString.setSpan(styleSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
//添加图标
fun image(context: Context, start: Int, end: Int, @DrawableRes res: Int): SpanBuilder {
val imageSpan = CenterImageSpan(context, res)
spannableString.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
fun build(): SpannableStringBuilder {
return spannableString
}
}

View File

@ -70,4 +70,49 @@ public class StringUtils {
}
return text;
}
/**
* 删除尾部\n字符
*
* @param str
* @return
*/
public static String deleteStringTailLineBreak(String str) {
if (TextUtils.isEmpty(str)) {
return str;
}
if (str.length() == 1) {
char ch = str.charAt(0);
if (ch == '\n') {
return "";
}
return str;
}
int lastIdx = str.length() - 1;
char last = str.charAt(lastIdx);
if (last == '\n') {
return str.substring(0, lastIdx);
} else {
return str;
}
}
/**
* 判断字符串末尾是否有\n
* @param str
* @return
*/
public static boolean isStringTailHasLineBreak(String str) {
if (TextUtils.isEmpty(str)) {
return false;
}
int lastIdx = str.length() - 1;
char last = str.charAt(lastIdx);
return last == '\n';
}
}

View File

@ -5,12 +5,14 @@ import android.content.Context
import android.graphics.Color
import android.text.*
import android.text.style.ClickableSpan
import android.text.style.RelativeSizeSpan
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import com.gh.common.view.CustomLinkMovementMethod
import com.gh.common.view.RoundStrokeBackgroundColorSpan
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
@ -76,7 +78,7 @@ object TextHelper {
@JvmStatic
fun highlightTextThatIsWrappedInsideWrapper(textView: TextView,
text: String,
text: CharSequence,
wrapper: String,
@ColorRes
highlightColorId: Int,
@ -150,6 +152,61 @@ object TextHelper {
return sBuilder
}
/**
* [amwayStyle] 是否为安利墙列表样式,安利墙列表样式与其它地方略有不同
*/
fun getCommentLabelSpannableStringBuilder(comment: CharSequence,
lineFeed: String = "\n",
amwayStyle: Boolean = false,
tagStrokeColor: String = "#FFDAA2",
tagTextColor: String = "#FF9B06"): SpannableStringBuilder {
val contents = SpannableStringBuilder()
var count = 0
val splits = comment.split("<tag>")
splits.forEachIndexed { index, s ->
if (index != 0) {
val item = "<tag>$s"
val pattern = Pattern.compile("<tag>(\\S+)</tag>(\\S+)")
val matcher = pattern.matcher(item)
if (matcher.find()) {
val label = matcher.group(1)
val content = matcher.group(2)
val newLabel = " $label "
val newContent = if (index != splits.size - 1) "$content$lineFeed" else content
contents.append(newLabel)
contents.setSpan(RelativeSizeSpan(0.8f), count, count + newLabel.length - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
contents.setSpan(
getRoundStrokeBackgroundColorSpan(amwayStyle, tagStrokeColor, tagTextColor),
count,
count + newLabel.length - 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
count += newLabel.length
contents.append(newContent)
count += newContent.length
}
}
}
return contents
}
private fun getRoundStrokeBackgroundColorSpan(amwayStyle: Boolean,
tagStrokeColor: String,
tagTextColor: String): RoundStrokeBackgroundColorSpan {
return if (amwayStyle) {
val strokeWidth = DisplayUtils.dip2px(1F)
RoundStrokeBackgroundColorSpan(
Color.parseColor(tagStrokeColor),
Color.parseColor(tagTextColor),
strokeWidth,
DisplayUtils.sp2px(HaloApp.getInstance().application, 10F))
} else {
RoundStrokeBackgroundColorSpan(
Color.parseColor(tagStrokeColor),
Color.parseColor(tagTextColor))
}
}
interface ExceedTextLengthLimitCallback {
fun onExceed()
}

View File

@ -0,0 +1,55 @@
package com.gh.common.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan;
/**
* 图文中心对齐
*/
public class CenterImageSpan extends ImageSpan {
public CenterImageSpan(Context context, int resourceId) {
super(context, resourceId);
}
public CenterImageSpan(Drawable drawable) {
super( drawable);
}
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fm) {
Drawable d = getDrawable();
Rect rect = d.getBounds();
if (fm != null) {
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.bottom - fmPaint.top;
int drHeight = rect.bottom - rect.top;
int top = drHeight / 2 - fontHeight / 4;
int bottom = drHeight / 2 + fontHeight / 4;
fm.ascent = -bottom;
fm.top = -bottom;
fm.bottom = top;
fm.descent = top;
}
return rect.right;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end,
float x, int top, int y, int bottom, Paint paint) {
Drawable b = getDrawable();
canvas.save();
int transY;
transY = ((bottom - top) - b.getBounds().bottom) / 2 + top;
canvas.translate(x, transY);
if (b.isVisible()) {
b.draw(canvas);
}
canvas.restore();
}
}

View File

@ -15,17 +15,18 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ProgressBar;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
public class DownloadProgressBar extends ProgressBar {
private static final int MAX_LENGTH = 1000;
private static final int DOWNLOAD_NORMAL_STYLE = 0;
private static final int DOWNLOAD_RECT_STYLE = 1;
private static final int DOWNLOAD_IMAGE_STYLE = 2;
public static final int MAX_LENGTH = 1000;
public static final int DOWNLOAD_NORMAL_STYLE = 0;
public static final int DOWNLOAD_RECT_STYLE = 1;
public static final int DOWNLOAD_IMAGE_STYLE = 2;
public static final int DOWNLOAD_SLIDE_STYLE = 3;
public enum DownloadType {
NORMAL,
@ -54,6 +55,8 @@ public class DownloadProgressBar extends ProgressBar {
private int mDefaultColor;
private int mTextSize;
private boolean mShowDownloadPercent = false;
private Rect mTextBound = new Rect();
public DownloadProgressBar(Context context) {
@ -66,6 +69,7 @@ public class DownloadProgressBar extends ProgressBar {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DownloadProgressBar);
mDownloadStyle = ta.getInteger(R.styleable.DownloadProgressBar_downloadStyle, DOWNLOAD_NORMAL_STYLE);
mTextSize = ta.getDimensionPixelSize(R.styleable.DownloadProgressBar_textSize, DisplayUtils.sp2px(getContext(), 14));
mShowDownloadPercent = ta.getBoolean(R.styleable.DownloadProgressBar_showDownloadPercent, false);
ta.recycle();
}
setMax(MAX_LENGTH);
@ -103,11 +107,17 @@ public class DownloadProgressBar extends ProgressBar {
canvas.getClipBounds(mTextBound); //The dimensions of your canvas
int width = mTextBound.width() - 20; //10 to keep some space on the right for the "..."
String txt = TextUtils.ellipsize(mText, mFakeTextPaint, width, TextUtils.TruncateAt.END).toString();
String txt = TextUtils.ellipsize(mText, mFakeTextPaint, width, TextUtils.TruncateAt.END).toString();
srcCanvas.drawText(txt, getWidth() / 2, baseline, mPaint);
mPaint.setXfermode(mDuffXFerMode);
if (getProgress() != 0) {
mPaint.setColor(DOWNLOAD_IMAGE_STYLE == mDownloadStyle ? Color.BLACK : Color.WHITE); // 反向颜色
int color = Color.WHITE;
if (DOWNLOAD_IMAGE_STYLE == mDownloadStyle) {
color = Color.BLACK;
} else if (DOWNLOAD_SLIDE_STYLE == mDownloadStyle) {
color = getResources().getColor(R.color.theme);
}
mPaint.setColor(color); // 反向颜色
}
srcCanvas.drawRect(rectF, mPaint);
@ -120,11 +130,34 @@ public class DownloadProgressBar extends ProgressBar {
}
public String getText() {
if (mText != null && mText.contains("%")) {
return getResources().getString(R.string.downloading);
}
return mText;
}
public void setText(@StringRes int res) {
setText(getResources().getString(res));
if (mShowDownloadPercent && res == R.string.downloading) {
setText(getProgressPercent());
} else {
setText(getResources().getString(res));
}
}
public void setDownloadStyle(int downloadStyle) {
this.mDownloadStyle = downloadStyle;
}
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
if (getResources().getString(R.string.downloading).equals(mText)) {
setText(getProgressPercent());
}
}
private String getProgressPercent() {
return getProgress() / 10 + "%";
}
public void setDownloadType(DownloadType downloadType) {
@ -185,6 +218,7 @@ public class DownloadProgressBar extends ProgressBar {
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
break;
case DOWNLOAD_IMAGE_STYLE:
case DOWNLOAD_SLIDE_STYLE:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_image_style));
mDefaultColor = Color.WHITE;
break;

View File

@ -0,0 +1,52 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
/**
* TextView using Spannable - ellipsize doesn't work
* https://stackoverflow.com/questions/14691511/textview-using-spannable-ellipsize-doesnt-work
*/
class EllipsizeTextView : AppCompatTextView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
if (lineCount > maxLines) {
val lastLineEnd = layout.getLineEnd(maxLines - 1)
val secondLastLineEnd = layout.getLineEnd(maxLines - 2)
val charSequence: CharSequence
val width = paint.measureText(text.subSequence(secondLastLineEnd, lastLineEnd).toString() + "...")
if (width > layout.width) {
val lastLineText = text.subSequence(secondLastLineEnd, lastLineEnd)
for (i in 0 until lastLineText.length) {
val cutWidth = paint.measureText(text.subSequence(secondLastLineEnd, lastLineEnd - i).toString() + "...")
if (cutWidth <= layout.width) {
charSequence = text.subSequence(0, lastLineEnd - i)
text = "$charSequence..."
break
}
}
} else {
charSequence = text.subSequence(0, lastLineEnd)
text = charSequence
}
}
}
/**
* 阻止TextView移动
* https://stackoverflow.com/questions/24027108/how-do-i-completely-prevent-a-textview-from-scrolling
*/
override fun scrollTo(x: Int, y: Int) {
//super.scrollTo(x, y)
//do nothing
}
}

View File

@ -12,36 +12,36 @@ import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
public class ExpendTextView extends AppCompatTextView {
private CharSequence mSnapshotText;
private String mExpendText = "...全文";
private int mMaxLines = 3; // 由于sdk版本限制(getMaxLines) 这里设置默认值
private boolean mInitLayout = false;
private boolean mOpenLayout = false;
private ExpandCallback mExpandCallback;
public ExpendTextView(Context context) {
super(context);
}
public ExpendTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mMaxLines = getMaxLines();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@ -51,35 +51,35 @@ public class ExpendTextView extends AppCompatTextView {
showExpendButton();
}
}
public void setExpendText(String text) {
this.mExpendText = text;
}
public void setExpandCallback(ExpandCallback callback) {
this.mExpandCallback = callback;
}
@Override
public void setText(CharSequence text, BufferType type) {
mInitLayout = true;
super.setText(text, type);
}
private void showExpendButton() {
Layout layout = getLayout();
int start = layout.getLineStart(0);
int lastLineEnd = layout.getLineEnd(mMaxLines - 1);
int lastLineStart = layout.getLineStart(mMaxLines - 1);
float lastLineRight = layout.getLineRight(mMaxLines - 1);
int viewWidth = getWidth() - getPaddingRight() - getPaddingLeft();
TextPaint paint = getPaint();
float expendTextWidth = paint.measureText(mExpendText);
CharSequence content = mSnapshotText.subSequence(start, lastLineEnd);
if (viewWidth - lastLineRight > expendTextWidth) {
content = content.toString().trim() + mExpendText ;
content = content.toString().trim() + mExpendText;
} else {
CharSequence lastText = mSnapshotText.subSequence(lastLineStart, lastLineEnd);
for (int i = lastText.length() - 1; i > 0; i--) {
@ -103,32 +103,32 @@ public class ExpendTextView extends AppCompatTextView {
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme));
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
mOpenLayout = true;
setMaxLines(Integer.MAX_VALUE);
setText(mSnapshotText);
if (mExpandCallback != null) {
mExpandCallback.onExpand();
}
}
}, startPosition, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}, startPosition + 3, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
msp.setSpan(new BackgroundColorSpan(Color.WHITE), startPosition, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(msp);
setMovementMethod(CustomLinkMovementMethod.getInstance());
}
public void setExpendMaxLines(int maxLines) {
mMaxLines = maxLines;
setMaxLines(maxLines);
}
public interface ExpandCallback {
void onExpand();
}
}

View File

@ -5,58 +5,59 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by khy on 2017/3/28.
*/
public class GridDivider extends RecyclerView.ItemDecoration {
public final int[] ATRRS = new int[]{android.R.attr.listDivider};
private Drawable mDividerDarwable;
private Paint mColorPaint;
private int mDividerHight = 1;
private int mGridCount;
private int mSpanCount;
private int mDividerStrokeWidth = 1;
private boolean mIsFilterLast;
/*
int dividerHight 分割线的线宽
int dividerColor 分割线的颜色
private Paint mColorPaint;
private Drawable mDividerDrawable;
/**
* @param dividerStrokeWidth 分割线的线宽
* @param dividerColor 分割线的颜色
*/
public GridDivider(Context context, int dividerHight, int gridCount, int dividerColor) {
public GridDivider(Context context, int dividerStrokeWidth, int spanCount, int dividerColor) {
this(context);
mDividerHight = dividerHight;
mGridCount = gridCount;
mDividerStrokeWidth = dividerStrokeWidth;
mSpanCount = spanCount;
mColorPaint = new Paint();
mColorPaint.setColor(dividerColor);
}
public GridDivider(Context context, int dividerHight, int gridCount, int dividerColor, boolean isFilterLast) {
public GridDivider(Context context, int dividerStrokeWidth, int spanCount, int dividerColor, boolean isFilterLast) {
this(context);
mDividerHight = dividerHight;
mGridCount = gridCount;
mDividerStrokeWidth = dividerStrokeWidth;
mSpanCount = spanCount;
mColorPaint = new Paint();
mColorPaint.setColor(dividerColor);
mIsFilterLast = isFilterLast;
}
public GridDivider(Context context) {
final TypedArray ta = context.obtainStyledAttributes(ATRRS);
this.mDividerDarwable = ta.getDrawable(0);
int[] attrs = new int[]{android.R.attr.listDivider};
final TypedArray ta = context.obtainStyledAttributes(attrs);
this.mDividerDrawable = ta.getDrawable(0);
ta.recycle();
}
/*
int dividerHight 分割线的线宽
Drawable dividerDrawable 图片分割线
/**
* @param dividerStrokeWidth 分割线的线宽
* @param dividerDrawable 图片分割线
*/
public GridDivider(Context context, int dividerHight, Drawable dividerDrawable) {
public GridDivider(Context context, int dividerStrokeWidth, Drawable dividerDrawable) {
this(context);
mDividerHight = dividerHight;
mDividerDarwable = dividerDrawable;
mDividerStrokeWidth = dividerStrokeWidth;
mDividerDrawable = dividerDrawable;
}
@Override
@ -67,46 +68,45 @@ public class GridDivider extends RecyclerView.ItemDecoration {
drawVerticalDivider(c, parent);
}
public void drawHorizontalDivider(Canvas c, RecyclerView parent) {
private void drawHorizontalDivider(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
if (mIsFilterLast && i == childCount - 1) continue;
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin - mDividerHight;
final int left = child.getLeft() - params.leftMargin - mDividerStrokeWidth;
final int right = child.getRight() + params.rightMargin;
int top = 0;
int bottom = 0;
// 最上面一行
if ((i / mGridCount) == 0) {
if ((i / mSpanCount) == 0) {
//当前item最上面的分割线
top = child.getTop();
//当前item下面的分割线
bottom = top + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
bottom = top + mDividerStrokeWidth;
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
top = child.getBottom() + params.bottomMargin;
bottom = top + mDividerHight;
bottom = top + mDividerStrokeWidth;
} else {
top = child.getBottom() + params.bottomMargin;
bottom = top + mDividerHight;
bottom = top + mDividerStrokeWidth;
}
//画分割线
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
}
}
public void drawVerticalDivider(Canvas c, RecyclerView parent) {
private void drawVerticalDivider(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
@ -119,26 +119,26 @@ public class GridDivider extends RecyclerView.ItemDecoration {
int right = 0;
//左边第一列
if ((i % mGridCount) == 0) {
if ((i % mSpanCount) == 0) {
//item左边分割线
left = child.getLeft();
right = left + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
right = left + mDividerStrokeWidth;
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
//item右边分割线
left = child.getRight() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
left = child.getRight() + params.rightMargin - mDividerStrokeWidth;
right = left + mDividerStrokeWidth;
} else {
//非左边第一列
left = child.getRight() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
left = child.getRight() + params.rightMargin - mDividerStrokeWidth;
right = left + mDividerStrokeWidth;
}
//画分割线
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}

View File

@ -0,0 +1,25 @@
package com.gh.common.view
import android.annotation.TargetApi
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.WindowInsets
import android.widget.FrameLayout
class MaterializedFrameLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
: FrameLayout(context, attrs) {
/**
* 将 windowInsets 传递给子 view [https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec#.raoa9t506]
*/
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
val childCount = childCount
for (index in 0 until childCount) {
getChildAt(index).dispatchApplyWindowInsets(insets)
}
return insets
}
}

View File

@ -0,0 +1,52 @@
package com.gh.common.view
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.text.style.ReplacementSpan
import androidx.annotation.Dimension
import com.gh.common.util.DisplayUtils
import com.halo.assistant.HaloApp
class RoundStrokeBackgroundColorSpan(private val strokeColor: Int,
private val textColor: Int,
private val strokeWidth: Int = 2,
@Dimension(unit = Dimension.PX)
private val textSize: Int = 0) : ReplacementSpan() {
private var halfStrokeWidth = 0
init {
halfStrokeWidth = strokeWidth / 2
}
override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
return paint.measureText(text, start, end).toInt()
}
override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
val originalColor = paint.color
paint.color = this.strokeColor
paint.style = Paint.Style.STROKE
paint.strokeWidth = strokeWidth.toFloat()
if (textSize != 0) {
paint.textSize = textSize.toFloat()
}
val fontMetrics = paint.fontMetrics
canvas.drawRoundRect(RectF(
x + halfStrokeWidth,
top.toFloat() + halfStrokeWidth,
x + halfStrokeWidth + paint.measureText(text, start, end).toInt(),
top + fontMetrics.bottom - fontMetrics.top + strokeWidth * 2 - halfStrokeWidth),
DisplayUtils.dip2px(HaloApp.getInstance().application, 3f).toFloat(),
DisplayUtils.dip2px(HaloApp.getInstance().application, 3f).toFloat(),
paint)
paint.color = this.textColor
paint.style = Paint.Style.FILL
paint.strokeWidth = 0f
canvas.drawText(text, start, end, x + halfStrokeWidth, y.toFloat() - strokeWidth, paint)
paint.color = originalColor
}
}

View File

@ -0,0 +1,17 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import com.google.android.material.appbar.CollapsingToolbarLayout
class ScrimAwareCollapsingToolbarLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
: CollapsingToolbarLayout(context, attrs) {
var scrimShownAction: ((shown: Boolean) -> Unit)? = null
override fun setScrimsShown(shown: Boolean) {
scrimShownAction?.invoke(shown)
super.setScrimsShown(shown)
}
}

View File

@ -7,11 +7,11 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import java.lang.reflect.Field;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.lang.reflect.Field;
/**
* Auto Scroll View Pager
* <ul>
@ -353,5 +353,19 @@ public class AutoScrollViewPager extends ViewPager {
public void setBorderAnimation(boolean isBorderAnimation) {
this.isBorderAnimation = isBorderAnimation;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mTouchListener.onTouch(this, ev);
return super.dispatchTouchEvent(ev);
}
private OnTouchListener mTouchListener;
@Override
public void setOnTouchListener(OnTouchListener l) {
mTouchListener = l;
}
}

View File

@ -7,12 +7,13 @@ import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Message;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.view.MenuItem;
import android.widget.ImageView;
import com.gh.base.BaseActivity;
import androidx.annotation.NonNull;
import com.gh.base.ToolBarActivity;
import com.gh.base.fragment.WaitingDialogFragment;
import com.gh.common.util.BitmapUtils;
import com.gh.common.util.EntranceUtils;
@ -37,7 +38,7 @@ import io.reactivex.ObservableOnSubscribe;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
public class CropImageActivity extends BaseActivity {
public class CropImageActivity extends ToolBarActivity {
@BindView(R.id.cropimage_custom)
CropImageCustom mCropimageCustom;

View File

@ -16,8 +16,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.ethanhua.skeleton.Skeleton;
import com.ethanhua.skeleton.ViewSkeletonScreen;
import com.gh.base.BaseActivity;
import com.gh.base.OnRequestCallBackListener;
import com.gh.base.ToolBarActivity;
import com.gh.common.util.ApkActiveUtils;
import com.gh.common.util.DetailDownloadUtils;
import com.gh.common.util.DeviceTokenUtils;
@ -65,7 +65,7 @@ import static com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG;
/**
* Created by khy on 2016/12/13.
*/
public class LibaoDetailActivity extends BaseActivity implements LibaoDetailAdapter.OnCodeScrollListener,
public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailAdapter.OnCodeScrollListener,
OnRequestCallBackListener {
@BindView(R.id.libaodetail_rv_show)

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.Context;
@ -9,11 +10,13 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@ -22,6 +25,9 @@ import android.view.View;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import com.gh.base.AppUncaughtHandler;
import com.gh.base.BaseActivity;
import com.gh.base.fragment.BaseFragment_ViewPager;
@ -52,6 +58,7 @@ import com.gh.common.util.PackageUtils;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.PushHelper;
import com.gh.common.util.SPUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.ThirdPartyPackageHelper;
import com.gh.common.util.UrlFilterUtils;
import com.gh.download.DownloadManager;
@ -89,6 +96,7 @@ import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Util_System_Phone_State;
import com.tencent.bugly.beta.tinker.TinkerManager;
import com.tencent.bugly.crashreport.CrashReport;
@ -109,11 +117,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
@ -127,8 +135,7 @@ import static com.gh.gamecenter.personal.PersonalFragment.LOGOUT_TAG;
public class MainActivity extends BaseActivity {
public final static String EB_MAINACTIVITY_TAG = "MainActivity";
public final static String EB_SKIP_GAMEFRAGMENT = "GameFragment";
public final static String EB_SKIP_MAIN = "MainActivity";
public final static String SHOULD_INIT_IM = "should_init_im";
public final static String SWITCH_TO_COMMUNITY = "switch_to_community";
@ -164,7 +171,7 @@ public class MainActivity extends BaseActivity {
DownloadManager.getInstance(getApplicationContext()).cancel(downloadEntity.getUrl());
toast("该链接已失效!请联系管理员。");
EventBus.getDefault().post(new EBShowDialog("notfound", downloadEntity.getName()));
EventBus.getDefault().post(new EBShowDialog(DOWNLOAD_NOT_FOUND, downloadEntity.getName()));
MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
"游戏", downloadEntity.getName(),
"平台", downloadEntity.getPlatform());
@ -194,7 +201,7 @@ public class MainActivity extends BaseActivity {
if (platform != null) {
if (downloadEntity.isPluggable()) {
// 弹出插件化提示框
EventBus.getDefault().post(new EBShowDialog("plugin", downloadEntity.getPath()));
EventBus.getDefault().post(new EBShowDialog(PLUGGABLE, downloadEntity.getPath()));
} else if (downloadEntity.isPlugin()) {
toast(downloadEntity.getName() + " - " + platform + " - 下载完成");
} else {
@ -214,7 +221,7 @@ public class MainActivity extends BaseActivity {
startActivity(PackageUtils.getInstallIntent(MainActivity.this, downloadEntity.getPath()));
} else {
// 弹出卸载提示框
EventBus.getDefault().post(new EBShowDialog("plugin", downloadEntity.getPath()));
EventBus.getDefault().post(new EBShowDialog(PLUGGABLE, downloadEntity.getPath()));
}
}
}
@ -243,9 +250,7 @@ public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 上传数据
DataCollectionManager.getInstance(getApplicationContext()).upload();
setStatusBarColor(Color.WHITE);
mSp = PreferenceManager.getDefaultSharedPreferences(this);
@ -262,9 +267,6 @@ public class MainActivity extends BaseActivity {
}
replaceFragment(mMainWrapperFragment);
// 检查助手更新
UpdateManager.getInstance(this).checkUpdate(true, null);
isNewFirstLaunch = mSp.getBoolean("isNewFirstLaunchV" + PackageUtils.getVersionName(), true);
if (isNewFirstLaunch) {
final LunchType lunchType = DeviceTokenUtils.getLaunchType();
@ -286,12 +288,6 @@ public class MainActivity extends BaseActivity {
DataUtils.getGid();
}
// 获取默认配置
getGhzsSettings();
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
// 添加观察者
DownloadManager.getInstance(this).addObserver(dataWatcher);
@ -304,7 +300,8 @@ public class MainActivity extends BaseActivity {
DialogUtils.showWarningDialog(this, "发生闪退", "光环助手刚刚发生了闪退,马上反馈以帮助我们更好地修复问题?(只需简单描述你刚才的操作)"
, "暂不", "马上反馈",
() -> {
SuggestionActivity.startSuggestionActivity(MainActivity.this, SuggestType.crash, "APP闪退");
// SuggestionActivity.startSuggestionActivity(MainActivity.this, SuggestType.crash, "APP闪退");
startActivityForResult(SuggestionActivity.getIntent(MainActivity.this, SuggestType.crash, "APP闪退"), 100);
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击反馈");
@ -317,7 +314,7 @@ public class MainActivity extends BaseActivity {
// checkTinkerPath(); // todo 看情况是否需要显示弹窗
checkRetryDownload();
checkNotificationPermission();
// 初始化 IM只有在 APP 刚启动时执行
@ -340,9 +337,41 @@ public class MainActivity extends BaseActivity {
handler.postDelayed(() -> {
PushHelper.postPushClickAction(this.getApplicationContext(), null);
}, 2000);
// 耗时操作
HaloApp.getInstance().getMainExecutor().execute(() -> {
// 上传数据
DataCollectionManager.getInstance(getApplicationContext()).upload();
// 获取默认配置
getGhzsSettings();
// 检查助手更新
UpdateManager.getInstance(this).checkUpdate(true, null);
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == SuggestSelectActivity.SUGGEST_TYPE_REQUEST) {
showKefuReportDialog();
}
}
private void showKefuReportDialog() {
// 只有是APP闪退反馈成功后弹出联系客服的弹窗
String str = "您也可以联系客服进一步描述闪退的情况,如果您反馈的是新问题,即有机会获得红包奖励";
DialogUtils.showWarningDialog(MainActivity.this, "反馈成功", Html.fromHtml(str.substring(0, str.indexOf("红包奖励")) + "<font color='#FF0000'>红包奖励</font>"), "暂不", "联系客服",
() -> {
if (ShareUtils.isQQClientAvailable(this)) {
DirectUtils.directToQqConversation(this, "3467475980");
} else {
toast("本机未安装QQ应用");
}
}, null);
}
@Override
protected void onDestroy() {
super.onDestroy();
@ -389,11 +418,11 @@ public class MainActivity extends BaseActivity {
}
}, 500);
}
private void checkNotificationPermission() {
// 仅登录后再启动光环时请求一次权限
if (!SPUtils.getBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS)
&& UserManager.getInstance().isLoggedIn()) {
&& UserManager.getInstance().isLoggedIn()) {
SPUtils.setBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS, true);
showNotificationHintDialog();
}
@ -469,7 +498,7 @@ public class MainActivity extends BaseActivity {
downloadEntity.setStatus(DownloadStatus.cancel);
DownloadManager.getInstance(getApplicationContext()).cancel(downloadEntity.getUrl());
// 弹出提示框
EventBus.getDefault().post(new EBShowDialog("hijack"));
EventBus.getDefault().post(new EBShowDialog(DOWNLOAD_HIJACK));
// 记录链接被劫持
DataCollectionUtils.uploadHijack(this, downloadEntity);
// 上传劫持log
@ -558,7 +587,7 @@ public class MainActivity extends BaseActivity {
private void switchToCommunityTabAndRefresh() {
getIntent().putExtra(SWITCH_TO_COMMUNITY, false);
Log.e("Switch", "true");
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 1));
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK));
EventBus.getDefault().post(new EBReuse(CommunityFragment.EB_RETRY_PAGE));
}
@ -679,22 +708,22 @@ public class MainActivity extends BaseActivity {
}
});
}
@SuppressLint("CheckResult")
private void showNotificationHintDialog() {
if (!SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_HINT)) {
RetrofitManager.getInstance(this).getApi().getBootPopup()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NotificationHint>() {
@Override
public void onSuccess(NotificationHint data) {
try {
NotificationHelper.showEnableNotificationDialogIfItsDisabled(MainActivity.this, data);
} catch (Exception ignore){
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NotificationHint>() {
@Override
public void onSuccess(NotificationHint data) {
try {
NotificationHelper.showEnableNotificationDialogIfItsDisabled(MainActivity.this, data);
} catch (Exception ignore) {
}
}
}
});
});
}
}
@ -705,7 +734,7 @@ public class MainActivity extends BaseActivity {
, "前往登录", "残忍拒绝", new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, INDEX_PERSONAL));
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, INDEX_PERSONAL));
}
}, null);
}
@ -920,9 +949,28 @@ public class MainActivity extends BaseActivity {
MetaUtil.INSTANCE.refreshMeta();
}
}
@Override
public String getActivityNameInChinese() {
return "游戏首页";
}
public static void skipToMainActivity(Context context, int position) {
Activity activity = AppManager.getInstance().findActivity(MainActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
&& activity != null && !activity.isDestroyed()) {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, position));
} else {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, position));
}
}, 300);
}
Intent intent = MainActivity.getMainIntent(context);
context.startActivity(intent);
}
}

View File

@ -18,6 +18,7 @@ import android.webkit.WebViewClient
import android.widget.ScrollView
import android.widget.TextView
import com.gh.base.BaseActivity
import com.gh.base.ToolBarActivity
import com.gh.common.util.CommentUtils
import com.gh.common.util.DeviceUtils
import com.gh.common.util.DialogUtils
@ -35,7 +36,7 @@ import java.io.IOException
import java.util.*
class NetworkDiagnosisActivity : BaseActivity() {
class NetworkDiagnosisActivity : ToolBarActivity() {
data class ProgressAndDetail(val progress: Int, val detail: String)

View File

@ -25,8 +25,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.ethanhua.skeleton.Skeleton;
import com.ethanhua.skeleton.ViewSkeletonScreen;
import com.gh.base.BaseActivity;
import com.gh.base.OnRequestCallBackListener;
import com.gh.base.ToolBarActivity;
import com.gh.common.history.HistoryHelper;
import com.gh.common.util.ApkActiveUtils;
import com.gh.common.util.CheckLoginUtils;
@ -80,7 +80,7 @@ import static com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG;
*
* @author 黄壮华
*/
public class NewsDetailActivity extends BaseActivity implements OnClickListener, OnRequestCallBackListener {
public class NewsDetailActivity extends ToolBarActivity implements OnClickListener, OnRequestCallBackListener {
@BindView(R.id.news_detail_rv_show)
RecyclerView mDetailRv;

View File

@ -3,19 +3,20 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.MotionEvent;
import com.gh.base.BaseActivity;
import androidx.fragment.app.Fragment;
import com.gh.base.ToolBarActivity;
import com.gh.gamecenter.normal.NormalFragment;
/**
* Created by khy on 17/10/17.
*/
public abstract class NormalActivity extends BaseActivity {
public abstract class NormalActivity extends ToolBarActivity {
private Fragment mTargetFragment;

View File

@ -1,327 +0,0 @@
package com.gh.gamecenter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import com.gh.base.BaseActivity;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.GdtHelper;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.TextHelper;
import com.gh.gamecenter.db.SearchHistoryDao;
import com.gh.gamecenter.eventbus.EBSearch;
import com.gh.gamecenter.search.SearchDefaultFragment;
import com.gh.gamecenter.search.SearchGameDetailFragment;
import com.gh.gamecenter.search.SearchGameListFragment;
import com.lightgame.utils.Util_System_Keyboard;
import com.qq.gdt.action.ActionType;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.concurrent.TimeUnit;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.subjects.PublishSubject;
public class SearchActivity extends BaseActivity {
private EditText searchInput;
private ImageView searchCancel;
private TextView searchButton;
private SearchHistoryDao dao;
private static final String KEY_CURRENTTAG = "currentTab";
private static final String KEY_SEARCHTYPE = "searchType";
private static final String KEY_CLICKED = "clicked";
private String searchKey;
private String searchType;
private int currentTab;
private boolean isSearchDetail;
private PublishSubject<String> mPublishSubject;
public static final String SEARCH_AUTO = "自动搜索";
public static final String SEARCH_DEFAULT = "默认搜索";
public static final String SEARCH_HISTORY = "历史搜索";
public static final String SEARCH_MANUALLY = "主动搜索";
public static final String SEARCH_HOT = "热门搜索";
@NonNull
public static Intent getIntent(Context context, boolean clicked, String hint, String entrance) {
Intent intent = new Intent(context, SearchActivity.class);
intent.putExtra(KEY_CLICKED, clicked);
intent.putExtra(EntranceUtils.KEY_HINT, hint);
intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance);
return intent;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_CURRENTTAG, currentTab);
outState.putString(EntranceUtils.KEY_SEARCHKEY, searchKey);
outState.putString(KEY_SEARCHTYPE, searchType);
}
@Override
protected int getLayoutId() {
return R.layout.activity_search;
}
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dao = new SearchHistoryDao(this);
mPublishSubject = PublishSubject.create();
mPublishSubject
.debounce(300, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
if (searchInput.getText().length() != 0) {
search("auto", s);
}
});
boolean isFromHome = getIntent().getBooleanExtra(KEY_CLICKED, false);
String hint = getIntent().getStringExtra(EntranceUtils.KEY_HINT);
setActionBarLayout();
currentTab = 0;
if (savedInstanceState != null) {
currentTab = savedInstanceState.getInt(KEY_CURRENTTAG, 0);
searchKey = savedInstanceState.getString(EntranceUtils.KEY_SEARCHKEY, null);
searchType = savedInstanceState.getString(KEY_SEARCHTYPE, null);
if (currentTab != 0 && !TextUtils.isEmpty(searchKey)) {
search(searchType, searchKey);
}
} else if (!TextUtils.isEmpty(hint)) {
searchInput.setHint(hint);
if (isFromHome) {
currentTab = 2;
dao.add(hint);
search("default", hint);
}
} else {
searchInput.setHint("搜索游戏...");
}
if (currentTab == 0) {
setResultPresentModel(0);
}
}
public void setActionBarLayout() {
searchInput = findViewById(R.id.etSearch);
searchInput.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
Util_System_Keyboard.hideSoftKeyboard(SearchActivity.this);
search("initiative", null);
}
return false;
});
searchButton = findViewById(R.id.btnSearch);
searchCancel = findViewById(R.id.ivDeleteText);
searchButton.setOnClickListener(v -> {
Util_System_Keyboard.hideSoftKeyboard(SearchActivity.this);
search("initiative", null);
});
searchCancel.setOnClickListener(v -> {
searchCancel.setVisibility(View.GONE);
searchInput.setText("");
});
searchInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
searchCancel.setVisibility(View.VISIBLE);
} else {
searchCancel.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable s) {
String newSearchKey = s.toString().trim();
if (newSearchKey.length() < 1) {
setResultPresentModel(0);
} else if (!isSearchDetail) {
mPublishSubject.onNext(newSearchKey);
}
}
});
searchInput.setFilters(new InputFilter[]{TextHelper.getFilter(50, "最多输入50个字")});
findViewById(R.id.btnGoBack).setOnClickListener(v -> onBackPressed());
}
private void search(String type, String key) {
searchType = type;
switch (type) {
case "auto":
//自动搜索
searchKey = key;
setResultPresentModel(1);
break;
case "default":
//默认搜索
isSearchDetail = true;
searchKey = key;
searchInput.setText(key);
searchInput.setSelection(searchInput.getText().length());
setResultPresentModel(2);
isSearchDetail = false;
MtaHelper.onEvent("游戏搜索", "默认搜索", key);
break;
case "remen":
//热门搜索
isSearchDetail = true;
searchKey = key;
searchInput.setText(key);
searchInput.setSelection(searchInput.getText().length());
setResultPresentModel(2);
isSearchDetail = false;
break;
case "history":
//历史搜索
isSearchDetail = true;
searchKey = key;
searchInput.setText(key);
searchInput.setSelection(searchInput.getText().length());
setResultPresentModel(2);
isSearchDetail = false;
MtaHelper.onEvent("游戏搜索", "历史搜索", key);
break;
case "initiative":
//主动搜索
String newSearchKey = searchInput.getText().toString().trim();
if (newSearchKey.length() < 1) {
String hint = searchInput.getHint().toString();
if (!TextUtils.isEmpty(hint) && !"搜索游戏...".equals(hint)) {
dao.add(hint);
search("default", hint);
}
} else if (!newSearchKey.equals(searchKey) || currentTab != 2) {
searchKey = newSearchKey;
if (!TextUtils.isEmpty(searchKey)) {
dao.add(searchKey);
setResultPresentModel(2);
} else {
toast("请输入搜索内容");
}
}
MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey);
break;
}
}
private void setResultPresentModel(int model) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (model) {
case 0:
SearchDefaultFragment search_history_fragment = new SearchDefaultFragment();
transaction.replace(R.id.search_result, search_history_fragment, SearchDefaultFragment.class.getSimpleName());
currentTab = 0;
break;
case 1:
SearchGameListFragment game_list_fragment = new SearchGameListFragment();
game_list_fragment.setParams(searchKey, searchType);
transaction.replace(R.id.search_result, game_list_fragment);
currentTab = 1;
break;
case 2:
SearchGameDetailFragment game_detail_fragment = new SearchGameDetailFragment();
game_detail_fragment.setParams(searchKey, searchType);
transaction.replace(R.id.search_result, game_detail_fragment);
currentTab = 2;
break;
default:
break;
}
transaction.commitAllowingStateLoss();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(EBSearch search) {
switch (search.getType()) {
case "history":
search("history", search.getKey());
break;
case "remen":
search("remen", search.getKey());
break;
case "click":
DataCollectionUtils.uploadSearchClick(this, searchKey, searchType, "搜索页面",
search.getGameId(), search.getGameName());
break;
case "search":
GdtHelper.INSTANCE.logAction(ActionType.SEARCH,
GdtHelper.KEYWORD, searchKey);
DataCollectionUtils.uploadSearch(this, searchKey, searchType, "搜索页面",
search.getGameId(), search.getGameName());
break;
}
}
@Override
protected boolean handleBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(SearchDefaultFragment.class.getSimpleName());
if (fragment == null) {
setResultPresentModel(0);
return true;
}
return super.handleBackPressed();
}
public static String convertSearchType(String type) {
switch (type) {
case "auto":
return SEARCH_AUTO;
case "default":
return SEARCH_DEFAULT;
case "remen":
return SEARCH_HOT;
case "history":
return SEARCH_HISTORY;
case "initiative":
return SEARCH_MANUALLY;
default:
return "未知搜索类型";
}
}
}

View File

@ -0,0 +1,279 @@
package com.gh.gamecenter
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doOnTextChanged
import com.gh.base.BaseActivity
import com.gh.common.util.*
import com.gh.gamecenter.DisplayType.*
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.search.SearchDefaultFragment
import com.gh.gamecenter.search.SearchGameDetailFragment
import com.gh.gamecenter.search.SearchGameListFragment
import com.lightgame.utils.Util_System_Keyboard
import com.qq.gdt.action.ActionType
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.PublishSubject
import kotlinx.android.synthetic.main.toolbar_search.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.concurrent.TimeUnit
open class SearchActivity : BaseActivity() {
private var mDao: SearchHistoryDao? = null
protected var mSearchKey: String? = null
protected var mIsAutoSearchDisabled: Boolean = false
protected var mSearchType = SearchType.DEFAULT
protected var mDisplayType = DisplayType.DEFAULT
private var mPublishSubject: PublishSubject<String>? = null
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt(KEY_DISPLAY_TYPE, mDisplayType.value)
outState.putString(EntranceUtils.KEY_SEARCHKEY, mSearchKey)
outState.putString(KEY_SEARCH_TYPE, mSearchType.value)
}
override fun getLayoutId(): Int {
return R.layout.activity_search
}
@SuppressLint("CheckResult")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val hint = intent.getStringExtra(EntranceUtils.KEY_HINT)
val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false)
mDao = SearchHistoryDao(this)
mPublishSubject = PublishSubject.create()
mPublishSubject!!
.debounce(300, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
if (searchEt.text.isNotEmpty()) {
search(SearchType.AUTO, it)
}
}
initSearchBar()
if (savedInstanceState != null) {
mDisplayType = DisplayType.fromInt(savedInstanceState.getInt(KEY_DISPLAY_TYPE, 0))
mSearchKey = savedInstanceState.getString(EntranceUtils.KEY_SEARCHKEY, null)
mSearchType = SearchType.fromString(savedInstanceState.getString(KEY_SEARCH_TYPE, null))
if (mDisplayType != DisplayType.DEFAULT && !TextUtils.isEmpty(mSearchKey)) {
search(mSearchType, mSearchKey)
}
} else if (!TextUtils.isEmpty(hint)) {
searchEt.hint = hint
if (searchImmediately) {
mDisplayType = DisplayType.GAME_DETAIL
mDao?.add(hint)
search(SearchType.DEFAULT, hint)
}
} else {
searchEt.hint = "搜索游戏..."
}
if (mDisplayType == DisplayType.DEFAULT) {
updateDisplayType(DisplayType.DEFAULT)
}
}
private fun initSearchBar() {
searchEt.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
Util_System_Keyboard.hideSoftKeyboard(this)
search(SearchType.MANUAL, null)
}
false
}
searchBtn.setOnClickListener {
Util_System_Keyboard.hideSoftKeyboard(this)
search(SearchType.MANUAL, null)
}
deleteIv.setOnClickListener {
deleteIv.visibility = View.GONE
searchEt.setText("")
}
searchEt.doOnTextChanged { text, _, _, _ -> deleteIv.goneIf(text?.length == 0) }
searchEt.doAfterTextChanged { editable ->
val newSearchKey = editable.toString().trim { it <= ' ' }
if (newSearchKey.isEmpty()) {
updateDisplayType(DisplayType.DEFAULT)
} else if (!mIsAutoSearchDisabled) {
mPublishSubject?.onNext(newSearchKey)
}
}
searchEt.filters = arrayOf(TextHelper.getFilter(50, "最多输入50个字"))
backBtn.setOnClickListener { onBackPressed() }
}
open fun search(type: SearchType, key: String?) {
mSearchType = type
mIsAutoSearchDisabled = true
// 自动搜索,默认搜索,热门搜索,历史搜索,主动搜索
when (type) {
SearchType.AUTO -> {
mSearchKey = key
updateDisplayType(DisplayType.GAME_DIGEST)
}
SearchType.DEFAULT -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
MtaHelper.onEvent("游戏搜索", "默认搜索", key)
}
SearchType.HOT -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
}
SearchType.HISTORY -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.GAME_DETAIL)
MtaHelper.onEvent("游戏搜索", "历史搜索", key)
}
SearchType.MANUAL -> {
val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
if (newSearchKey.isEmpty()) {
val hint = searchEt.hint.toString()
if (!TextUtils.isEmpty(hint) && "搜索游戏..." != hint) {
mDao?.add(hint)
search(SearchType.DEFAULT, hint)
}
} else if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
mDao?.add(mSearchKey)
updateDisplayType(DisplayType.GAME_DETAIL)
} else {
toast("请输入搜索内容")
}
}
MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
}
}
mIsAutoSearchDisabled = false
}
open fun updateDisplayType(type: DisplayType) {
val transaction = supportFragmentManager.beginTransaction()
when (type) {
DisplayType.DEFAULT -> {
transaction.replace(R.id.search_result, SearchDefaultFragment(), SearchDefaultFragment::class.java.simpleName)
}
DisplayType.GAME_DIGEST -> {
val digestListFragment = SearchGameListFragment()
digestListFragment.setParams(mSearchKey, mSearchType.value)
transaction.replace(R.id.search_result, digestListFragment)
}
DisplayType.GAME_DETAIL -> {
val detailListFragment = SearchGameDetailFragment()
detailListFragment.setParams(mSearchKey, mSearchType.value)
transaction.replace(R.id.search_result, detailListFragment)
}
}
mDisplayType = type
transaction.commitAllowingStateLoss()
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(search: EBSearch) {
when (search.type) {
SearchType.HISTORY.value -> search(SearchType.HISTORY, search.key)
SearchType.HOT.value -> search(SearchType.HOT, search.key)
"click" -> DataCollectionUtils.uploadSearchClick(this, mSearchKey, mSearchType.value, "搜索页面",
search.gameId, search.gameName)
"search" -> {
GdtHelper.logAction(ActionType.SEARCH, GdtHelper.KEYWORD, mSearchKey)
DataCollectionUtils.uploadSearch(this, mSearchKey, mSearchType.value, "搜索页面",
search.gameId, search.gameName)
}
}
}
override fun handleBackPressed(): Boolean {
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.simpleName)
if (fragment == null) {
updateDisplayType(DisplayType.DEFAULT)
return true
}
return super.handleBackPressed()
}
companion object {
private const val KEY_SEARCH_TYPE = "search_type"
private const val KEY_DISPLAY_TYPE = "display_type"
private const val KEY_SEARCH_IMMEDIATELY = "search_immediately"
@JvmStatic
fun getIntent(context: Context, searchImmediately: Boolean, hint: String, entrance: String): Intent {
val intent = Intent(context, SearchActivity::class.java)
intent.putExtra(KEY_SEARCH_IMMEDIATELY, searchImmediately)
intent.putExtra(EntranceUtils.KEY_HINT, hint)
intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance)
return intent
}
}
}
enum class SearchType(var value: String) {
AUTO("auto"),
DEFAULT("default"),
HISTORY("history"),
MANUAL("initiative"),
HOT("remen");
fun toChinese() = when (this) {
AUTO -> "自动搜索"
DEFAULT -> "默认搜索"
HISTORY -> "历史搜索"
MANUAL -> "主动搜索"
HOT -> "热门搜索"
}
companion object {
@JvmStatic
fun fromString(typeString: String) = values().find { typeString == it.value } ?: DEFAULT
}
}
/**
*
* [DEFAULT] 默认搜索页
* [GAME_DIGEST] 游戏为部分文字样式的列表
* [GAME_DETAIL] 游戏全为标准样式的列表
*/
enum class DisplayType(var value: Int) {
DEFAULT(0),
GAME_DIGEST(1),
GAME_DETAIL(2);
companion object {
fun fromInt(typeInt: Int) = values().find { typeInt == it.value } ?: DEFAULT
}
}

View File

@ -3,13 +3,10 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import android.text.Html;
import android.text.TextUtils;
import android.view.View;
@ -17,8 +14,11 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.BaseActivity;
import com.gh.base.ToolBarActivity;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MessageShareUtils;
@ -33,7 +33,7 @@ import butterknife.BindView;
* Created by khy on 2016/11/7.
* 分享卡片
*/
public class ShareCardActivity extends BaseActivity {
public class ShareCardActivity extends ToolBarActivity {
@BindView(R.id.sharecard_content)
TextView mShareContentTv;

View File

@ -9,7 +9,6 @@ import android.graphics.drawable.Animatable;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import androidx.core.content.ContextCompat;
import android.text.Html;
import android.text.TextUtils;
import android.view.View;
@ -19,13 +18,15 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.image.ImageInfo;
import com.gh.base.BaseActivity;
import com.gh.base.ToolBarActivity;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MessageShareUtils;
@ -50,7 +51,7 @@ import io.reactivex.functions.Consumer;
/**
* Created by khy on 2016/11/7.
*/
public class ShareCardPicActivity extends BaseActivity {
public class ShareCardPicActivity extends ToolBarActivity {
@BindView(R.id.sharecard_content)
TextView mShareContentTv;

View File

@ -4,15 +4,15 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.text.Html;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.gh.base.BaseActivity;
import androidx.annotation.NonNull;
import com.gh.base.ToolBarActivity;
import com.gh.common.util.MessageShareUtils;
import com.gh.common.util.QRCodeUtils;
import com.gh.common.util.ShareUtils;
@ -26,7 +26,7 @@ import butterknife.OnClick;
/**
* Created by khy on 2017/2/6.
*/
public class ShareGhActivity extends BaseActivity {
public class ShareGhActivity extends ToolBarActivity {
@BindView(R.id.gh_address_qrcode)
ImageView mGhQrcode;

View File

@ -0,0 +1,64 @@
package com.gh.gamecenter
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import com.gh.base.ToolBarActivity
import com.gh.base.fragment.BaseFragment
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.amway.AmwaySuccessFragment
/**
* ShellActivity 用来包裹那些几乎没有交互且运营也不会想要知道页面访问量的静态 fragment (如安利墙的评论提交成功页面)
*/
class ShellActivity : ToolBarActivity() {
private lateinit var mFragment: BaseFragment<Any>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) handleIntent(intent.extras)
}
private fun handleIntent(bundle: Bundle?) {
// We parse the bundle to fragment to let fragment get data from bundle itself to survive configuration changes.
val intentType = Type.fromString(bundle?.getString(INTENT_TYPE) ?: "")
when (intentType) {
Type.AMWAY_SUCCESS -> startFragment(AmwaySuccessFragment().with(bundle))
}
}
override fun getLayoutId(): Int {
return R.layout.activity_shell
}
private fun startFragment(fragment: BaseFragment<Any>) {
mFragment = fragment
supportFragmentManager.beginTransaction().replace(R.id.placeholder, fragment).commitAllowingStateLoss()
}
companion object {
const val INTENT_TYPE = "intent_type"
fun getIntent(context: Context, type: Type, extraParcelable: Parcelable? = null): Intent {
val intent = Intent(context, ShellActivity::class.java)
intent.putExtra(INTENT_TYPE, type.value)
intent.putExtra(EntranceUtils.KEY_DATA, extraParcelable)
return intent
}
}
enum class Type(val value: String) {
AMWAY_SUCCESS("amway_success");
companion object {
fun fromString(typeString: String): Type {
return values().find { typeString == it.value } ?: AMWAY_SUCCESS
}
}
}
}

View File

@ -15,11 +15,6 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.gh.base.BaseActivity;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DeviceTokenUtils;
@ -54,6 +49,10 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
@ -108,8 +107,6 @@ public class SplashScreenActivity extends BaseActivity {
// 判断是不是这个版本的新用户
if (isNewFirstLaunch) {
setTheme(R.style.AppGuideTheme);
// 删除更新后的光环助手包
List<DownloadEntity> all = DownloadManager.getInstance(this).getAll();
for (DownloadEntity downloadEntity : all) {
@ -125,25 +122,22 @@ public class SplashScreenActivity extends BaseActivity {
// 判断是不是光环的新用户
if (SPUtils.getBoolean(SP_BRAND_NEW_USER, true)) {
View introBackground = findViewById(R.id.splash_intro_background);
introBackground.setVisibility(View.VISIBLE);
showPrivacyPolicy(() -> {
introBackground.setVisibility(View.GONE);
// Dialog dismiss 后的回调
guideLayout.setVisibility(View.VISIBLE);
SPUtils.setBoolean(SP_BRAND_NEW_USER, false);
requestPermissionAndLaunchMainActivity();
requestPermission();
});
} else {
requestPermissionAndLaunchMainActivity();
guideLayout.setVisibility(View.VISIBLE);
requestPermission();
}
} else {
setTheme(R.style.AppFullScreenTheme);
getWindow().getDecorView().postDelayed(this::launchMainActivity, 1000);
launchMainActivity();
}
}
private void requestPermissionAndLaunchMainActivity() {
private void requestPermission() {
if (EasyPermissions.hasPermissions(this, mPermissions)) {
GdtHelper.INSTANCE.logAction(ActionType.START_APP, GdtHelper.NETWORK_TYPE, DeviceUtils.getNetwork(this));
} else {

View File

@ -3,24 +3,25 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import com.gh.base.BaseActivity;
import com.gh.base.ToolBarActivity;
import com.gh.common.constant.Config;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.ShareUtils;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.suggest.SuggestType;
import androidx.annotation.NonNull;
import butterknife.BindView;
import butterknife.OnClick;
/**
* Created by khy on 2017/3/31.
*/
public class SuggestSelectActivity extends BaseActivity {
public class SuggestSelectActivity extends ToolBarActivity {
public final static int SUGGEST_TYPE_REQUEST = 11; // 只要进入反馈页面(下一个), 无论怎么回退当前页面都会退出
@ -84,12 +85,17 @@ public class SuggestSelectActivity extends BaseActivity {
type = SuggestType.articleCollect;
break;
case R.id.suggest_qqun_rl:
String groupNumber = "vd754P2_uNUJqDcgX4V-pyXEGZZVH0DE";
if (mSettings != null && mSettings.getSupport() != null &&
!TextUtils.isEmpty(mSettings.getSupport().getQQunKey())) {
groupNumber = mSettings.getSupport().getQQunKey();
if (ShareUtils.isQQClientAvailable(this)) {
String groupNumber = "vd754P2_uNUJqDcgX4V-pyXEGZZVH0DE";
if (mSettings != null && mSettings.getSupport() != null &&
!TextUtils.isEmpty(mSettings.getSupport().getQQunKey())) {
groupNumber = mSettings.getSupport().getQQunKey();
}
DirectUtils.directToQqGroup(this, groupNumber); // Q群367541038 KEY
}else{
toast("请先安装QQ");
}
DirectUtils.directToQqGroup(this, groupNumber); // Q群367541038 KEY
return;
}

View File

@ -23,14 +23,9 @@ import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.BaseActivity;
import com.gh.base.OnListClickListener;
import com.gh.base.OnRequestCallBackListener;
import com.gh.base.ToolBarActivity;
import com.gh.base.fragment.WaitingDialogFragment;
import com.gh.common.im.ImManager;
import com.gh.common.util.AdHelper;
@ -78,6 +73,10 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -92,7 +91,7 @@ import static com.gh.gamecenter.SuggestSelectActivity.SUGGEST_TYPE_REQUEST;
/**
* Created by khy on 2017/3/31.
*/
public class SuggestionActivity extends BaseActivity implements OnRequestCallBackListener<Object>, OnListClickListener {
public class SuggestionActivity extends ToolBarActivity implements OnRequestCallBackListener<Object>, OnListClickListener {
@BindView(R.id.suggest_content_et)
EditText mSuggestContentEt;
@ -188,6 +187,13 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
context.startActivity(intent);
}
public static Intent getIntent(Context context, SuggestType suggestType, String hint) {
Intent intent = new Intent(context, SuggestionActivity.class);
intent.putExtra(EntranceUtils.KEY_SUGGESTTYPE, suggestType);
intent.putExtra(EntranceUtils.KEY_HIDE_SUGGEST_HINT, hint);
return intent;
}
@Override
protected int getLayoutId() {
return R.layout.activity_suggest;
@ -502,7 +508,7 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
if (mPlatformContainer.getVisibility() == View.VISIBLE &&
TextUtils.isEmpty(mPlatformEt.getText().toString())) {
toast("请填写版本");
toast("请填写游戏平台");
return;
}
@ -718,12 +724,14 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
postDialog.dismissAllowingStateLoss();
}
setResult(SUGGEST_TYPE_REQUEST);
if (mHideHint.equals("APP闪退")) {
/*if (mHideHint.equals("APP闪退")) {
showKefuReportDialog();
} else {
toast("感谢您的反馈!");
finish();
}
}*/
toast("感谢您的反馈!");
finish();
}
@Override

View File

@ -10,8 +10,14 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.gh.base.BaseActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.gh.base.OnRequestCallBackListener;
import com.gh.base.ToolBarActivity;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.TextHelper;
import com.gh.common.util.UrlFilterUtils;
@ -27,11 +33,6 @@ import com.lightgame.utils.Utils;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -41,7 +42,7 @@ import io.reactivex.schedulers.Schedulers;
* Created by khy on 24/05/17.
*/
public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.OnRefreshListener, OnRequestCallBackListener {
public class ToolBoxActivity extends ToolBarActivity implements SwipeRefreshLayout.OnRefreshListener, OnRequestCallBackListener {
@BindView(R.id.et_search)
public EditText searchEt;

View File

@ -5,12 +5,16 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.gh.common.constant.Constants;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.entity.NewsEntity;
import com.gh.gamecenter.entity.ToolBoxEntity;
import com.halo.assistant.fragment.WebFragment;
import java.net.URLEncoder;
import java.util.Locale;
import androidx.annotation.NonNull;
/**
@ -56,6 +60,7 @@ public class WebActivity extends NormalActivity {
bundle.putString(EntranceUtils.KEY_URL, context.getString(R.string.privacy_policy_url));
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getUploadPolicyIntent(Context context) {
Bundle bundle = new Bundle();
@ -83,6 +88,38 @@ public class WebActivity extends NormalActivity {
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@SuppressWarnings("ConstantConditions")
public static Intent getBindWechatIntent(Context context) {
String url;
if (("internal").equals(BuildConfig.FLAVOR)) {
url = Constants.WECHAT_BIND_ADDRESS_DEV;
} else {
url = Constants.WECHAT_BIND_ADDRESS;
}
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_URL, url);
bundle.putBoolean(WebFragment.KEY_IS_BIND_WECHAT, true);
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@SuppressWarnings("ConstantConditions")
public static Intent getBadgeCenterIntent(Context context, String userId, String name, String icon) {
String url;
if (("internal").equals(BuildConfig.FLAVOR)) {
url = Constants.BADGE_ADDRESS_DEV;
} else {
url = Constants.BADGE_ADDRESS;
}
url = String.format(Locale.CHINA, "%s?user_id=%s&name=%s&icon=%s", url, userId, name, URLEncoder.encode(icon));
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_URL, url);
bundle.putBoolean(WebFragment.KEY_IS_BADGE_CENTER, true);
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getIntentByNews(Context context, ConcernEntity concernEntity, String entrance) {
Bundle bundle = new Bundle();

View File

@ -9,6 +9,8 @@ import com.gh.common.constant.ItemViewType;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CommentUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.TextHelper;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
@ -159,6 +161,12 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (parent != null && !TextUtils.isEmpty(parent.getUser().getName())) {
holder.quoteContainer.setVisibility(View.VISIBLE);
holder.quoteAuthorTv.setText(String.format("@%s", parent.getUser().getName()));
if (parent.getUser().getBadge() != null) {
holder.quoteAuthorBadgeSdv.setVisibility(View.VISIBLE);
ImageUtils.display(holder.quoteAuthorBadgeSdv, parent.getUser().getBadge().getIcon());
} else {
holder.quoteAuthorBadgeSdv.setVisibility(View.GONE);
}
String content;
if (parent.getActive()) {
content = parent.getComment();
@ -185,7 +193,17 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.userBadgeSdv.setOnClickListener(v -> {
MtaHelper.onEvent("进入徽章墙_用户记录", "资讯文章-查看对话", commentEntity.getUser().getName() + "" + commentEntity.getUser().getId() + "");
MtaHelper.onEvent("徽章中心", "进入徽章中心", "资讯文章-查看对话");
DirectUtils.directToBadgeWall(mContext, commentEntity.getUser().getId(), commentEntity.getUser().getName(), commentEntity.getUser().getIcon());
});
holder.badgeNameTv.setOnClickListener(v -> holder.userBadgeSdv.performClick());
holder.quoteAuthorBadgeSdv.setOnClickListener(v -> {
MtaHelper.onEvent("进入徽章墙_用户记录", "资讯文章-查看对话", parent.getUser().getName() + "" + parent.getUser().getId() + "");
MtaHelper.onEvent("徽章中心", "进入徽章中心", "资讯文章-查看对话");
DirectUtils.directToBadgeWall(mContext, parent.getUser().getId(), parent.getUser().getName(), parent.getUser().getIcon());
});
if (commentEntity.getPriority() != 0) {
holder.commentBadge.setVisibility(View.VISIBLE);
} else {

View File

@ -18,6 +18,7 @@ import com.gh.common.util.DirectUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.NumberUtils;
import com.gh.common.util.StringUtils;
@ -363,6 +364,12 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (parent != null && !TextUtils.isEmpty(parent.getUser().getName())) {
holder.quoteContainer.setVisibility(View.VISIBLE);
holder.quoteAuthorTv.setText(String.format("@%s", parent.getUser().getName()));
if (parent.getUser().getBadge() != null) {
holder.quoteAuthorBadgeSdv.setVisibility(View.VISIBLE);
ImageUtils.display(holder.quoteAuthorBadgeSdv, parent.getUser().getBadge().getIcon());
} else {
holder.quoteAuthorBadgeSdv.setVisibility(View.GONE);
}
String content;
if (parent.getActive()) {
content = parent.getComment();
@ -411,6 +418,18 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
holder.userBadgeSdv.setOnClickListener(v -> {
MtaHelper.onEvent("进入徽章墙_用户记录", "资讯文章-评论列表", finalCommentEntity.getUser().getName() + "" + finalCommentEntity.getUser().getId() + "");
MtaHelper.onEvent("徽章中心", "进入徽章中心", "资讯文章-评论列表");
DirectUtils.directToBadgeWall(mContext, finalCommentEntity.getUser().getId(), finalCommentEntity.getUser().getName(), finalCommentEntity.getUser().getIcon());
});
holder.badgeNameTv.setOnClickListener(v -> holder.userBadgeSdv.performClick());
holder.quoteAuthorBadgeSdv.setOnClickListener(v -> {
MtaHelper.onEvent("进入徽章墙_用户记录", "资讯文章-评论列表", parent.getUser().getName() + "" + parent.getUser().getId() + "");
MtaHelper.onEvent("徽章中心", "进入徽章中心", "资讯文章-评论列表");
DirectUtils.directToBadgeWall(mContext, parent.getUser().getId(), parent.getUser().getName(), parent.getUser().getIcon());
});
if (commentEntity.getPriority() != 0) {
holder.commentBadge.setVisibility(View.VISIBLE);
} else {

View File

@ -44,6 +44,13 @@ public class CommentViewHolder extends BaseRecyclerViewHolder {
@BindView(R.id.comment_quote_content_tv)
public TextView quoteContentTv;
@BindView(R.id.sdv_user_badge)
public SimpleDraweeView userBadgeSdv;
@BindView(R.id.tv_badge_name)
public TextView badgeNameTv;
@BindView(R.id.sdv_quote_author_badge)
public SimpleDraweeView quoteAuthorBadgeSdv;
public CommentViewHolder(View itemView) {
super(itemView);
}

View File

@ -1,18 +0,0 @@
package com.gh.gamecenter.adapter.viewholder;
import com.gh.base.BaseRecyclerViewHolder;
import com.gh.gamecenter.databinding.GameHeadItemBinding;
/**
* Created by LGT on 2016/7/5.
*/
public class GameHeadViewHolder extends BaseRecyclerViewHolder {
public GameHeadItemBinding binding;
public GameHeadViewHolder(GameHeadItemBinding bind) {
super(bind.getRoot());
binding = bind;
}
}

View File

@ -0,0 +1,30 @@
package com.gh.gamecenter.adapter.viewholder
import android.text.TextUtils
import android.view.View
import com.gh.base.BaseRecyclerViewHolder
import com.gh.gamecenter.databinding.GameHeadItemBinding
import com.gh.gamecenter.entity.SubjectEntity
class GameHeadViewHolder(var binding: GameHeadItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
fun bindHead(subject: SubjectEntity) {
binding.subject = subject
binding.headPb.visibility = View.GONE
val text = if ("change" == subject.home) "换一批" else "全部 >"
binding.headMore.text = text
val showLine = (subject.data != null && TextUtils.isEmpty(subject.data!![0].image))
binding.headLineTop.visibility = if (showLine || subject.type == "column_collection") {
View.VISIBLE
} else View.GONE
if (text == "全部 >"
&& subject.data != null
&& subject.data!!.size >= subject.more!!
&& subject.type != "column_collection") {
binding.headMore.visibility = View.GONE
} else {
binding.headMore.visibility = View.VISIBLE
}
}
}

View File

@ -1,39 +0,0 @@
package com.gh.gamecenter.adapter.viewholder;
import android.view.View;
import android.widget.TextView;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.BaseRecyclerViewHolder;
import com.gh.gamecenter.R;
import com.gh.gamecenter.databinding.GameImageItemBinding;
import butterknife.BindView;
/**
* Created by LGT on 2016/7/5.
*/
public class GameImageViewHolder extends BaseRecyclerViewHolder {
@BindView(R.id.game_image_icon)
public SimpleDraweeView image;
@BindView(R.id.game_image_line)
public View line;
@BindView(R.id.game_des)
public TextView gameDes;
public GameImageItemBinding binding;
public GameImageViewHolder(GameImageItemBinding bind) {
super(bind.getRoot());
this.binding = bind;
}
public GameImageViewHolder(View itemView) {
super(itemView);
}
}

View File

@ -0,0 +1,18 @@
package com.gh.gamecenter.adapter.viewholder
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.DisplayUtils
import com.gh.common.util.ImageUtils
import com.gh.gamecenter.databinding.GameImageItemBinding
import com.gh.gamecenter.entity.GameEntity
class GameImageViewHolder(var binding: GameImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
// 注意:专题详情的大图不能用此方法
fun bindImage(entity: GameEntity) {
binding.game = entity
val context = binding.root.context
val width = context.resources.displayMetrics.widthPixels - DisplayUtils.dip2px(context, 16F)
ImageUtils.display(binding.gameImageIcon, entity.image, width)
}
}

View File

@ -1,11 +1,10 @@
package com.gh.gamecenter.adapter.viewholder
import com.gh.base.BaseRecyclerViewHolder
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.databinding.GameColumnCollectionItemBinding
import com.gh.gamecenter.databinding.PersonalHomeRatingBinding
import com.gh.gamecenter.databinding.SearchGameFooterBinding
class SearchGameFooterViewHolder(val binding: SearchGameFooterBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class PersonalHomeRatingViewHolder(val binding: PersonalHomeRatingBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class GameImageSlideViewHolder(val binding: GameImageSlideItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class GameVerticalSlideViewHolder(val binding: GameVerticalSlideItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class GameColumnCollectionViewHolder(val binding: GameColumnCollectionListBinding) : BaseRecyclerViewHolder<Any>(binding.root)
class GameColumnCollectionItemViewHolder(val binding: GameColumnCollectionItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)

View File

@ -0,0 +1,27 @@
package com.gh.gamecenter.amway
import android.os.Bundle
import com.gh.base.BaseActivity
import com.gh.common.util.DisplayUtils
import com.gh.gamecenter.R
/**
* 安利墙页面
*/
class AmwayActivity : BaseActivity() {
override fun getLayoutId(): Int {
return R.layout.activity_amway
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DisplayUtils.transparentStatusBar(this)
val containerFragment = AmwayFragment().with(intent.extras)
// 若 placeholder 外层为 RelativeLayout 的话,会出现莫名的偏移
supportFragmentManager.beginTransaction().replace(R.id.placeholder, containerFragment).commitAllowingStateLoss()
}
}

View File

@ -0,0 +1,239 @@
package com.gh.gamecenter.amway
import android.content.Context
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.LoadType
import com.gh.gamecenter.databinding.AmwayCommentItemBinding
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.game.GameAndPosition
import com.gh.gamecenter.game.vertical.GameVerticalAdapter
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
import com.gh.gamecenter.home.LegacyHomeFragmentAdapterAssistant
import com.gh.gamecenter.home.slide.HomeSlideListAdapter
import com.halo.assistant.fragment.game.GamePluginAdapter
import com.lightgame.download.DownloadEntity
import java.util.*
import java.util.regex.Pattern
class AmwayAdapter(context: Context, private var mViewModel: AmwayViewModel, private var mLayoutManager: RecyclerView.LayoutManager) : ListAdapter<AmwayListItemData>(context) {
private val mLegacyHomeFragmentAdapterAssistant by lazy {
LegacyHomeFragmentAdapterAssistant(mContext, this, mLayoutInflater, true, LegacyHomeFragmentAdapterAssistant.OuterType.AMWAY)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_AMWAY_COMMENT -> AmwayCommentViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.amway_comment_item, parent, false))
ItemViewType.ITEM_FOOTER -> FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
else -> mLegacyHomeFragmentAdapterAssistant.createLegacyViewHolder(parent, viewType)
}
}
override fun setListData(updateData: MutableList<AmwayListItemData>?) {
if (updateData == null) {
super.setListData(updateData)
} else {
val brandNewList = mutableListOf<AmwayListItemData>()
for (item in updateData) {
brandNewList.add(item.copy())
}
super.setListData(updateData)
}
}
override fun areItemsTheSame(oldItem: AmwayListItemData?, newItem: AmwayListItemData?) = oldItem == newItem
override fun areContentsTheSame(oldItem: AmwayListItemData?, newItem: AmwayListItemData?): Boolean {
return (oldItem?.amwayCommentItem?.comment?.me?.isVoted != newItem?.amwayCommentItem?.comment?.me?.isVoted)
}
override fun getItemCount(): Int {
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is AmwayCommentViewHolder -> {
mEntityList[position].amwayCommentItem?.let {
holder.bindComment(it, mEntityList[position].blockPosition, mViewModel)
}
}
is FooterViewHolder -> {
holder.initItemPadding()
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
holder.hint.setTextColor(ContextCompat.getColor(mContext, R.color.text_B3B3B3))
val lp = holder.itemView.layoutParams as RecyclerView.LayoutParams
lp.height = DisplayUtils.dip2px(48F)
lp.width = ViewGroup.LayoutParams.MATCH_PARENT
holder.itemView.layoutParams = lp
holder.itemView.setOnClickListener {
if (mIsNetworkError) {
mViewModel.load(LoadType.RETRY)
}
}
}
else -> mLegacyHomeFragmentAdapterAssistant.bindLegacyViewHolder(holder, mEntityList[position], position)
}
}
override fun getItemViewType(position: Int): Int {
return if (position == itemCount - 1) {
ItemViewType.ITEM_FOOTER
} else {
val item = mEntityList[position]
when {
item.amwayCommentItem != null -> ITEM_AMWAY_COMMENT
else -> mLegacyHomeFragmentAdapterAssistant.getLegacyItemType(item)
}
}
}
fun getGameEntityByPackage(packageName: String): List<GameAndPosition> {
val positionList = ArrayList<GameAndPosition>()
val positionMap = mViewModel.positionAndPackageMap
for (key in positionMap.keys) {
if (key.contains(packageName)) {
val position = positionMap[key]!!
if (position >= mEntityList.size) return arrayListOf()
val itemData = mEntityList[position]
mLegacyHomeFragmentAdapterAssistant.getLegacyGameEntityByPackage(positionList, itemData, packageName, position)
}
}
return positionList
}
fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
val data = getGameEntityByPackage(status.packageName)
for (gameAndPosition in data) {
if (gameAndPosition.entity != null && gameAndPosition.entity.name == status.name) {
gameAndPosition.entity.getEntryMap().remove(status.platform)
}
notifyChildItem(gameAndPosition.position)
}
}
fun notifyChildItem(position: Int) {
if (getItemViewType(position) == ItemViewType.VERTICAL_SLIDE_ITEM
|| getItemViewType(position) == ItemViewType.GAME_PLUGIN) {
val view = mLayoutManager.findViewByPosition(position)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView?.adapter?.notifyDataSetChanged()
} else {
notifyItemChanged(position)
}
}
fun notifyItemByDownload(download: DownloadEntity) {
val data = getGameEntityByPackage(download.packageName)
for (gameAndPosition in data) {
if (gameAndPosition.entity != null && gameAndPosition.entity.name == download.name) {
val entryMap = gameAndPosition.entity.getEntryMap()
entryMap[download.platform] = download
}
if (getItemViewType(gameAndPosition.position) == ItemViewType.VERTICAL_SLIDE_ITEM ||
getItemViewType(gameAndPosition.position) == ItemViewType.GAME_PLUGIN) {
val view = mLayoutManager.findViewByPosition(gameAndPosition.position)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_view)
when (val adapter = recyclerView?.adapter) {
is GameVerticalAdapter -> adapter.notifyItemByDownload(download)
is GamePluginAdapter -> adapter.notifyItemByDownload(download)
is HomeSlideListAdapter -> adapter.notifyItemByDownload(download)
}
} else {
notifyItemChanged(gameAndPosition.position)
}
}
}
class AmwayCommentViewHolder(var binding: AmwayCommentItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindComment(amway: AmwayCommentEntity, blockPosition: Int, viewModel: AmwayViewModel) {
val context = binding.root.context
binding.amway = amway
val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(amway.comment.content)
if (m.find()) {
val contents = TextHelper.getCommentLabelSpannableStringBuilder(amway.comment.content, "\n", true)
binding.amwayContentTv.setTextWithHighlightedTextWrappedInsideWrapper(contents, copyClickedText = true)
} else {
binding.amwayContentTv.setTextWithHighlightedTextWrappedInsideWrapper(amway.comment.content, copyClickedText = true)
}
binding.gameContainer.setOnClickListener {
DirectUtils.directToGameDetail(context, amway.game.id, "(安利墙)")
MtaHelper.onEvent("安利墙", "点击", "评论${blockPosition}_${amway.game.name}_游戏")
}
amway.game.tag?.let {
val tags = it.take(3)
val tagString = StringBuilder()
for (i in tags.indices) {
tagString.append(tags[i].name)
if (i != tags.size - 1) tagString.append("/")
}
binding.tagTv.text = tagString
}
binding.commentContainer.setOnClickListener {
val intent = RatingReplyActivity.getIntent(context, amway.game.id, amway.comment, false, "(安利墙)", "")
SyncDataBetweenPageHelper.startActivityForResult(binding.root.context, intent, RatingFragment.RATING_REPLAY_REQUEST, adapterPosition)
MtaHelper.onEvent("安利墙", "点击", "评论${blockPosition}_${amway.game.name}_评论")
}
binding.userIconContainer.setOnClickListener {
DirectUtils.directToHomeActivity(context, amway.comment.user.id, "(安利墙)", "")
}
if (amway.comment.me.isVoted) {
binding.likeIv.setImageResource(R.drawable.ic_amway_liked)
binding.likeCountTv.setOnClickListener { binding.likeIv.performClick() }
binding.likeIv.setOnClickListener {
debounceActionWithInterval(binding.likeIv.id, 1000L) {
binding.likeIv.context.ifLogin("安利墙") {
viewModel.undoLikeAmwayComment(amway.game.id, amway.comment.id)
MtaHelper.onEvent("安利墙", "点击", "评论${blockPosition}_${amway.game.name}_取消点赞")
}
}
}
} else {
binding.likeIv.setImageResource(R.drawable.ic_amway_like)
binding.likeCountTv.setOnClickListener { binding.likeIv.performClick() }
binding.likeIv.setOnClickListener {
debounceActionWithInterval(binding.likeIv.id, 1000L) {
binding.likeIv.context.ifLogin("安利墙") {
viewModel.likeAmwayComment(amway.game.id, amway.comment.id)
MtaHelper.onEvent("安利墙", "点击", "评论${blockPosition}_${amway.game.name}_点赞")
}
}
}
}
ImageUtils.display(binding.sdvUserBadge, amway.comment.user.badge?.icon)
binding.sdvUserBadge.goneIf(amway.comment.user.badge == null)
binding.sdvUserBadge.setOnClickListener {
MtaHelper.onEvent("进入徽章墙_用户记录", "安利墙", "${amway.comment.user.name}${amway.comment.user.id}")
MtaHelper.onEvent("徽章中心", "进入徽章中心", "安利墙")
DirectUtils.directToBadgeWall(context, amway.comment.user.id, amway.comment.user.name, amway.comment.user.icon)
}
}
}
companion object {
const val ITEM_AMWAY_COMMENT = 222
}
}

View File

@ -0,0 +1,198 @@
package com.gh.gamecenter.amway
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import com.ethanhua.skeleton.Skeleton
import com.gh.common.TimeElapsedHelper
import com.gh.common.util.*
import com.gh.common.view.VerticalItemDecoration
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.amway.search.AmwaySearchActivity
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.gh.gamecenter.personal.PersonalFragment
import com.google.android.material.appbar.AppBarLayout
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import kotlinx.android.synthetic.main.fragment_amway.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs
class AmwayFragment : ListFragment<AmwayListItemData, AmwayViewModel>() {
private lateinit var mViewModel: AmwayViewModel
private val mElapsedHelper by lazy { TimeElapsedHelper() }
private var mAdapter: AmwayAdapter? = null
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
mAdapter?.notifyItemByDownload(downloadEntity)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel.fixedTopAmwayId = arguments?.getString(EntranceUtils.KEY_ID)
mViewModel.initData()
}
override fun getLayoutId() = R.layout.fragment_amway
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if ((requestCode == RatingFragment.RATING_REPLAY_REQUEST || requestCode == RatingFragment.RATING_PATCH_REQUEST)
&& resultCode == Activity.RESULT_OK) {
data?.getParcelableExtra<RatingComment>(RatingComment::class.java.simpleName)?.let {
mViewModel.handleResultUpdate(it)
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
// [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
(toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin = insets.systemWindowInsetTop
insets.consumeSystemWindowInsets()
}
val collapsingTrigger = 66F.dip2px() + DisplayUtils.getStatusBarHeight(context?.resources)
toolbar.setNavigationOnClickListener { requireActivity().finish() }
collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
collapsingToolbar.scrimShownAction = {
DisplayUtils.setLightStatusBar(requireActivity(), it)
if (it) {
titleTv.alpha = 1F
titleTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.black))
toolbar.navigationIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_bar_back)
} else {
titleTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
toolbar.navigationIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_toolbar_back_white)
}
}
mListRefresh?.setProgressViewOffset(false, 0, 118F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources))
titleTv.setOnClickListener {
if (ClickUtils.isFastDoubleClick(titleTv.id, 300)) {
scrollToTop()
}
}
appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
val absOffset = abs(verticalOffset)
val invisibleOffset = DisplayUtils.dip2px(30F)
if (absOffset <= invisibleOffset) {
titleTv.alpha = 1 - (absOffset.toFloat() / invisibleOffset)
} else {
titleTv.alpha = 0F
}
mListRefresh?.isEnabled = absOffset <= 2
})
mListRefresh?.setOnRefreshListener {
MtaHelper.onEvent("安利墙", "刷新")
onLoadRefresh()
}
fab.setOnClickListener {
MtaHelper.onEvent("发表评论", "进入", "上墙")
ifLogin("安利墙") {
startActivity(AmwaySearchActivity.getIntent(requireContext()))
}
}
mSkeletonScreen = Skeleton.bind(skeletonPlaceholder).shimmer(false).load(R.layout.fragment_amway_skeleton).show()
}
override fun provideListViewModel(): AmwayViewModel {
mViewModel = viewModelProvider()
return mViewModel
}
override fun getItemDecoration() = VerticalItemDecoration(context, 12F, false)
override fun provideListAdapter(): ListAdapter<*> {
if (mAdapter == null) {
mAdapter = AmwayAdapter(requireContext(), mViewModel, mLayoutManager)
}
return mAdapter!!
}
override fun isAutomaticLoad() = false
override fun onPause() {
super.onPause()
DownloadManager.getInstance(context).removeObserver(dataWatcher)
mElapsedHelper.pauseCounting()
MtaHelper.onEventWithTime("安利墙", mElapsedHelper.elapsedTime, "浏览")
}
override fun onResume() {
if (isEverPause) mAdapter?.notifyDataSetChanged()
super.onResume()
DownloadManager.getInstance(context).addObserver(dataWatcher)
mElapsedHelper.resetCounting()
mElapsedHelper.resumeCounting()
}
private fun scrollToTop() {
val firstItemPosition = mLayoutManager.findFirstVisibleItemPosition()
if (firstItemPosition >= 10) {
mListRv.scrollToPosition(6)
}
mListRv.smoothScrollToPosition(0)
appbar.setExpanded(true)
}
//下载被删除事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
if ("delete" == status.status) {
mAdapter?.notifyItemAndRemoveDownload(status)
}
}
//安装、卸载事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
val data = mAdapter?.getGameEntityByPackage(busFour.packageName) ?: arrayListOf()
for (gameAndPosition in data) {
mAdapter?.notifyChildItem(gameAndPosition.position)
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
if ("Refresh" == reuse.type) {
mAdapter?.notifyDataSetChanged()
} else if (reuse.type == PersonalFragment.LOGIN_TAG) { // 登入
scrollToTop()
mViewModel.initData(false)
}
}
}

View File

@ -0,0 +1,6 @@
package com.gh.gamecenter.amway
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.home.LegacyHomeItemData
data class AmwayListItemData(var amwayCommentItem: AmwayCommentEntity? = null) : LegacyHomeItemData()

View File

@ -0,0 +1,45 @@
package com.gh.gamecenter.amway
import android.os.Bundle
import android.view.View
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.normal.NormalFragment
import kotlinx.android.synthetic.main.fragment_amway_success.*
class AmwaySuccessFragment : NormalFragment() {
private var mGameEntity: GameEntity? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mGameEntity = arguments?.get(EntranceUtils.KEY_DATA) as GameEntity?
}
override fun getLayoutId(): Int {
return R.layout.fragment_amway_success
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setNavigationTitle("安利墙")
checkCommentBtn.setOnClickListener {
GameDetailActivity.startGameDetailCommentActivity(requireContext(), mGameEntity, "安利墙")
}
checkAmwayBtn.setOnClickListener {
requireActivity().finish()
}
commentRuleTv.setOnClickListener {
startActivity(WebActivity.getCommentRulesIntent(requireContext()))
}
}
}

View File

@ -0,0 +1,294 @@
package com.gh.gamecenter.amway
import android.annotation.SuppressLint
import android.app.Application
import com.gh.common.util.ErrorHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.baselist.LoadType
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.home.LegacyHomeItemData
import com.gh.gamecenter.home.LegacyHomeSubjectTransformer
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.SingleEmitter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
import kotlin.random.Random
class AmwayViewModel(application: Application) : ListViewModel<AmwayCommentEntity, AmwayListItemData>(application) {
var fixedTopAmwayId: String? = null
// 置顶安利
private var mFixedTopAmway: AmwayCommentEntity? = null
private var mAmwaySubjectList = arrayListOf<SubjectEntity>()
private var mFixedAmwayCommentList = arrayListOf<AmwayCommentEntity>()
private var mCachedFixedAmwayCommentList = arrayListOf<AmwayCommentEntity>()
private var mReuseCachedFixedAmwayList = false
var positionAndPackageMap = HashMap<String, Int>() // key: packageName + position, value: position
/**
* [dumpOldData] 是否丢弃旧置顶安利列表,默认为 true
*/
fun initData(dumpOldData: Boolean = true) {
if (!fixedTopAmwayId.isNullOrEmpty()) {
getFixedTopAmway()
} else {
getFixedAmwayList(dumpOldData)
}
}
@SuppressLint("CheckResult")
private fun getFixedTopAmway() {
RetrofitManager.getInstance(getApplication()).api
.getAmwayDetail(fixedTopAmwayId)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<AmwayCommentEntity>() {
override fun onSuccess(data: AmwayCommentEntity) {
mFixedTopAmway = data
getFixedAmwayList(true)
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
getFixedAmwayList(true)
}
})
}
@SuppressLint("CheckResult")
private fun getFixedAmwayList(dumpOldData: Boolean,
emitter: SingleEmitter<MutableList<AmwayCommentEntity>>? = null) {
RetrofitManager.getInstance(getApplication()).api
.getAmwayCommentList(1, 100)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<List<AmwayCommentEntity>>() {
override fun onSuccess(data: List<AmwayCommentEntity>) {
updateFixedAmwayCommentList(ArrayList(data), dumpOldData)
getAmwaySubjectList(emitter)
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
mLoadStatusLiveData.postValue(LoadStatus.INIT_FAILED)
}
})
}
@SuppressLint("CheckResult")
private fun getAmwaySubjectList(emitter: SingleEmitter<MutableList<AmwayCommentEntity>>? = null) {
RetrofitManager.getInstance(getApplication()).api
.amwaySubjectList
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<SubjectEntity>>() {
override fun onSuccess(data: List<SubjectEntity>) {
mAmwaySubjectList = ArrayList(data)
load(LoadType.REFRESH)
emitter?.onSuccess(getRandomItems())
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
mLoadStatusLiveData.postValue(LoadStatus.INIT_FAILED)
}
})
}
override fun provideDataObservable(page: Int): Observable<MutableList<AmwayCommentEntity>>? = null
override fun provideDataSingle(page: Int): Single<MutableList<AmwayCommentEntity>> {
return if (page == 1) {
getRandomDataSingle()
} else {
// 因为用了前100条数据作为随机的数据所以后面的页数从6开始
RetrofitManager.getInstance(getApplication()).api.getAmwayCommentList(page + 4, 20)
}
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) { list ->
val subjectListCopy = LinkedList(mAmwaySubjectList)
var subjectPosition = 0
val itemDataList = arrayListOf<AmwayListItemData>()
for (i in list.indices) {
// 在位置 3, 6, 9 穿插专题数据
if (subjectListCopy.isNotEmpty()
&& (i != 0 && i % 2 == 0)) {
LegacyHomeSubjectTransformer.transform(
itemDataList as ArrayList<LegacyHomeItemData>,
subjectListCopy.poll(),
subjectPosition++,
{ AmwayListItemData() },
{ addGamePositionAndPackage(itemDataList.size - 1, it) }
)
}
itemDataList.add(AmwayListItemData(amwayCommentItem = list[i]).apply { blockPosition = i + 1 })
}
mResultLiveData.postValue(itemDataList)
}
}
private fun updateFixedAmwayCommentList(newList: ArrayList<AmwayCommentEntity>, dumpOldData: Boolean) {
if (dumpOldData || mFixedAmwayCommentList.isEmpty()) {
mFixedAmwayCommentList = newList
} else {
mReuseCachedFixedAmwayList = true
for (newAmwayComment in newList) {
for (oldAmwayComment in mFixedAmwayCommentList) {
if (newAmwayComment.id == oldAmwayComment.id) {
oldAmwayComment.comment = newAmwayComment.comment
break
}
}
}
}
}
private fun addGamePositionAndPackage(position: Int, game: GameEntity) {
var packages = ""
for (apkEntity in game.getApk()) {
packages += apkEntity.packageName
}
positionAndPackageMap[packages + (position)] = position
game.gameLocation = GameEntity.GameLocation.INDEX
game.setEntryMap(DownloadManager.getInstance(getApplication()).getEntryMap(game.name))
}
fun handleResultUpdate(comment: RatingComment) {
updateAmwayCommentLikeCount(commentId = comment.id, isLiked = comment.me.isVoted, updatedLikeCount = comment.vote)
}
fun likeAmwayComment(gameId: String, commentId: String) {
RetrofitManager.getInstance(getApplication()).api
.voteGameComment(gameId, commentId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
updateAmwayCommentLikeCount(commentId, increaseCount = true, isLiked = true)
}
override fun onFailure(e: HttpException?) {
ErrorHelper.handleError(getApplication(), e?.response()?.errorBody()?.string())
}
})
}
fun undoLikeAmwayComment(gameId: String, commentId: String) {
RetrofitManager.getInstance(getApplication()).api
.unvoteGameComment(gameId, commentId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
updateAmwayCommentLikeCount(commentId, decreaseCount = true, isLiked = false)
}
override fun onFailure(e: HttpException?) {
ErrorHelper.handleError(getApplication(), e?.response()?.errorBody()?.string())
}
})
}
private fun updateAmwayCommentLikeCount(commentId: String,
increaseCount: Boolean = false,
decreaseCount: Boolean = false,
isLiked: Boolean = false,
updatedLikeCount: Int = -1) {
mResultLiveData.value?.let {
for ((i, item) in it.withIndex()) {
if (item.amwayCommentItem != null) {
val amwayComment = item.amwayCommentItem!!
if (amwayComment.comment.id == commentId) {
if (increaseCount) {
amwayComment.comment.me.isVoted = true
amwayComment.comment.vote++
}
if (decreaseCount) {
amwayComment.comment.me.isVoted = false
amwayComment.comment.vote--
}
if (updatedLikeCount != -1) {
amwayComment.comment.me.isVoted = isLiked
amwayComment.comment.vote = updatedLikeCount
}
it[i] = AmwayListItemData(amwayCommentItem = amwayComment)
break
}
}
}
mResultLiveData.postValue(it)
}
}
private fun getRandomDataSingle(): Single<MutableList<AmwayCommentEntity>> {
return Single.create {
if (mFixedAmwayCommentList.size == 0) {
getFixedAmwayList(dumpOldData = true, emitter = it)
} else if (mReuseCachedFixedAmwayList && mCachedFixedAmwayCommentList.isNotEmpty()) {
it.onSuccess(mCachedFixedAmwayCommentList)
mReuseCachedFixedAmwayList = false
} else {
it.onSuccess(getRandomItems())
}
}
}
private fun getRandomItems(): ArrayList<AmwayCommentEntity> {
val randomItemsList = arrayListOf<AmwayCommentEntity>()
val fixedAmwayListCopy = arrayListOf<AmwayCommentEntity>().apply { addAll(mFixedAmwayCommentList) }
val gameIdSet = HashSet<String>()
// 置顶(仅第一次加载)
mFixedTopAmway?.let {
randomItemsList.add(it)
gameIdSet.add(it.game.id)
mFixedTopAmway = null
}
while (randomItemsList.size < 20 && fixedAmwayListCopy.size != 0) {
val randomPosition = Random.nextInt(fixedAmwayListCopy.size)
val randomItem = fixedAmwayListCopy[randomPosition]
if (!gameIdSet.contains(randomItem.game.id)) {
gameIdSet.add(randomItem.game.id)
randomItemsList.add(randomItem)
}
fixedAmwayListCopy.removeAt(randomPosition)
}
mCachedFixedAmwayCommentList = randomItemsList
return randomItemsList
}
}

View File

@ -0,0 +1,85 @@
package com.gh.gamecenter.amway.search
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import com.gh.common.util.viewModelProvider
import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.search.SearchDefaultFragment
import kotlinx.android.synthetic.main.toolbar_search.*
class AmwaySearchActivity : SearchActivity() {
private lateinit var mViewModel: AmwaySearchViewModel
private val mSearchHistoryDao by lazy { AmwaySearchDao() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewModel = viewModelProvider()
}
override fun search(type: SearchType, key: String?) {
mSearchType = type
mIsAutoSearchDisabled = true
when (type) {
SearchType.AUTO -> {
mSearchKey = key
updateDisplayType(DisplayType.GAME_DIGEST)
mViewModel.getSearchResult(mSearchKey!!)
}
SearchType.HISTORY -> {
mSearchKey = key
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
mViewModel.getSearchResult(mSearchKey!!)
updateDisplayType(DisplayType.GAME_DETAIL)
}
else -> {
val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
mViewModel.getSearchResult(mSearchKey!!)
mSearchHistoryDao.add(mSearchKey!!)
updateDisplayType(DisplayType.GAME_DETAIL)
} else {
toast("请先输入游戏名再搜索~")
}
}
}
}
mIsAutoSearchDisabled = false
}
override fun updateDisplayType(type: DisplayType) {
val transaction = supportFragmentManager.beginTransaction()
when (type) {
DisplayType.DEFAULT -> {
transaction.replace(R.id.search_result, AmwaySearchDefaultFragment(), SearchDefaultFragment::class.java.simpleName)
}
else -> {
val fragment = supportFragmentManager.findFragmentByTag(AmwaySearchListFragment::class.java.simpleName)
?: AmwaySearchListFragment()
transaction.replace(R.id.search_result, fragment, AmwaySearchListFragment::class.java.simpleName)
}
}
mDisplayType = type
transaction.commitAllowingStateLoss()
}
companion object {
fun getIntent(context: Context): Intent {
val intent = Intent(context, AmwaySearchActivity::class.java)
return intent
}
}
}

View File

@ -0,0 +1,29 @@
package com.gh.gamecenter.amway.search
import android.content.Context
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.entity.GameEntity
class AmwaySearchAdapter(context: Context, val mViewModel: AmwaySearchViewModel) : ListAdapter<GameEntity>(context) {
fun setData(listData: List<GameEntity>) {
setListData(listData)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return AmwaySearchViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.amway_search_item, parent, false), mViewModel)
}
override fun getItemCount(): Int {
return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as AmwaySearchViewHolder).bindView(mEntityList[position])
}
}

View File

@ -0,0 +1,43 @@
package com.gh.gamecenter.amway.search
import com.gh.common.util.SPUtils
class AmwaySearchDao {
fun add(keyword: String) {
val originString = SPUtils.getString(SP_KEY)
if (originString.isEmpty()) {
SPUtils.setString(SP_KEY, keyword)
} else {
getAll()?.let {
if (it.contains(keyword)) {
it.remove(keyword)
}
it.add(0, keyword)
val builder = StringBuilder()
for ((index, key) in it.withIndex()) {
builder.append(key)
if (index != it.size - 1) {
builder.append(SEARCH_KEY_DIVIDER)
}
}
SPUtils.setString(SP_KEY, builder.toString())
}
}
}
fun getAll(): ArrayList<String>? {
val list = SPUtils.getString(SP_KEY).split(SEARCH_KEY_DIVIDER)
return if (list.size == 1 && list[0].isEmpty()) null else ArrayList(list)
}
fun deleteAll() {
SPUtils.setString(SP_KEY, "")
}
companion object {
const val SP_KEY = "amway_key"
const val SEARCH_KEY_DIVIDER = "<-||->"
}
}

View File

@ -0,0 +1,81 @@
package com.gh.gamecenter.amway.search
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.DialogUtils
import com.gh.common.util.observeNonNull
import com.gh.common.util.viewModelProviderFromParent
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.search.SearchDefaultFragment
import com.lightgame.utils.Util_System_Keyboard
import kotlinx.android.synthetic.main.fragment_amway_search_default.*
import org.greenrobot.eventbus.EventBus
class AmwaySearchDefaultFragment : SearchDefaultFragment() {
private lateinit var mSearchDao: AmwaySearchDao
private lateinit var mViewModel: AmwaySearchViewModel
override fun getLayoutId(): Int {
return R.layout.fragment_amway_search_default
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mViewModel = viewModelProviderFromParent()
mViewModel.playedGames.observeNonNull(this) {
mBinding.isExistHotSearch = it.isNotEmpty()
mBinding.hotList.run {
layoutManager = LinearLayoutManager(context)
adapter = AmwaySearchAdapter(context, mViewModel).apply { setData(it) }
}
updateNoPlayedGameHint()
}
}
override fun initDao() {
mSearchDao = AmwaySearchDao()
mHistoryList = mSearchDao.getAll()
}
override fun initView() {
mBinding = FragmentSearchDefaultBinding.bind(mCachedView.findViewById(R.id.searchContent))
mBinding.isExistHistory = mHistoryList?.isNotEmpty()
mBinding.hotTitle.text = "最近玩过"
mBinding.historyFlexContainer.setLimitHeight(mHistoryFlexMaxHeight)
createFlexContent(mBinding.historyFlex, mHistoryList, true, clickListener = {
val key = mHistoryList!![it]
mSearchDao.add(key)
EventBus.getDefault().post(EBSearch("history", key))
Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
})
mBinding.historyClear.setOnClickListener {
DialogUtils.showWarningDialog(activity, "清空记录", "确定清空历史搜索记录?") {
mSearchDao.deleteAll()
mBinding.isExistHistory = false
updateNoPlayedGameHint()
}
}
}
private fun updateNoPlayedGameHint() {
if (mSearchDao.getAll() != null && mSearchDao.getAll()?.size != 0) {
noDataContainer.visibility = View.GONE
return
}
if (mViewModel.playedGames.value == null || mViewModel.playedGames.value?.size == 0) {
noDataContainer.visibility = View.VISIBLE
} else {
noDataContainer.visibility = View.GONE
}
}
}

View File

@ -0,0 +1,99 @@
package com.gh.gamecenter.amway.search
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.observeNonNull
import com.gh.common.util.viewModelProviderFromParent
import com.gh.gamecenter.R
import com.gh.gamecenter.SuggestionActivity
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.normal.NormalFragment
import com.gh.gamecenter.suggest.SuggestType
import kotlinx.android.synthetic.main.fragment_amway_search.*
class AmwaySearchListFragment : NormalFragment() {
private lateinit var mAdapter: AmwaySearchAdapter
private lateinit var mViewModel: AmwaySearchViewModel
override fun getLayoutId(): Int {
return R.layout.fragment_amway_search
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mViewModel = viewModelProviderFromParent()
mAdapter = AmwaySearchAdapter(requireContext(), mViewModel)
recyclerView.adapter = mAdapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
noDataBtn.setOnClickListener {
SuggestionActivity.startSuggestionActivity(requireContext(), SuggestType.gameCollect, "求游戏:")
}
errorContainer.setOnClickListener {
mViewModel.retrySearch()
}
mViewModel.searchGames.observeNonNull(this) {
mAdapter.setData(it)
}
mViewModel.loadStatus.observeNonNull(this) {
when (it) {
LoadStatus.INIT_LOADING -> {
hideError()
showLoading()
hideNoDataHint()
}
LoadStatus.INIT_LOADED -> {
hideError()
hideLoading()
hideNoDataHint()
}
LoadStatus.INIT_FAILED -> {
hideLoading()
hideNoDataHint()
showError()
}
LoadStatus.INIT_EMPTY -> {
showNoDataHint()
hideError()
hideLoading()
}
else -> {
// do nothing
}
}
}
}
private fun showLoading() {
loadingContainer.visibility = View.VISIBLE
}
private fun hideLoading() {
loadingContainer.visibility = View.GONE
}
private fun showNoDataHint() {
noDataContainer.visibility = View.VISIBLE
}
private fun hideNoDataHint() {
noDataContainer.visibility = View.GONE
}
private fun showError() {
errorContainer.visibility = View.VISIBLE
}
private fun hideError() {
errorContainer.visibility = View.GONE
}
}

View File

@ -0,0 +1,68 @@
package com.gh.gamecenter.amway.search
import android.app.Activity
import android.graphics.Typeface
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.*
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.AmwaySearchItemBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_Keyboard
import com.lightgame.utils.Utils
import java.lang.ref.WeakReference
class AmwaySearchViewHolder(var binding: AmwaySearchItemBinding, val mViewModel: AmwaySearchViewModel) : RecyclerView.ViewHolder(binding.root) {
fun bindView(gameEntity: GameEntity) {
binding.game = gameEntity
binding.addIv.goneIf(!gameEntity.showComment)
binding.hintTv.goneIf(gameEntity.showComment)
if (gameEntity.showComment) {
binding.nameTv.setTextColor(ContextCompat.getColor(binding.root.context, R.color.text_333333))
binding.nameTv.setTypeface(binding.nameTv.typeface, Typeface.BOLD)
} else {
binding.nameTv.setTextColor(ContextCompat.getColor(binding.root.context, R.color.text_999999))
binding.nameTv.setTypeface(binding.nameTv.typeface, Typeface.NORMAL)
}
binding.root.setOnClickListener {
val activity = (binding.root.context) as Activity
Util_System_Keyboard.hideSoftKeyboardByIBinder(binding.root.context, binding.root.windowToken)
if (gameEntity.showComment) {
val callback = object : SimpleCallback<Boolean> {
override fun onCallback(arg: Boolean) {
if (arg) {
// 已评论过此游戏
GameDetailActivity.startGameDetailCommentActivity(binding.root.context, gameEntity, "安利墙")
} else {
val installPackageName = mViewModel.canUserCommentThisGame(gameEntity)
if (gameEntity.directComment || !installPackageName.isNullOrEmpty()) {
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(activity, object : EmptyCallback {
override fun onCallback() {
MtaHelper.onEvent("发表评论", "进入", "选中游戏_${gameEntity.name}")
val intent = RatingEditActivity.getIntent(binding.root.context, gameEntity, 0.0F, installPackageName, true)
activity.startActivity(intent)
activity.finish()
}
})
} else {
Utils.toast(activity, "安装游戏后才能评论哦")
}
}
}
}
CommentUtils.isUserCommentedOnThisGame(gameEntity.id, WeakReference(callback))
} else {
Utils.toast(HaloApp.getInstance().application, "该游戏暂不支持发表评论哦")
}
}
}
}

View File

@ -0,0 +1,104 @@
package com.gh.gamecenter.amway.search
import android.annotation.SuppressLint
import android.app.Application
import android.text.TextUtils
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.gh.common.constant.Config
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
class AmwaySearchViewModel(application: Application) : AndroidViewModel(application) {
private var mTempSearchKey = ""
var loadStatus = MutableLiveData<LoadStatus>()
var playedGames = MutableLiveData<List<GameEntity>>()
var searchGames = MutableLiveData<List<GameEntity>>()
init {
getPlayedGames()
}
fun retrySearch() {
if (mTempSearchKey.isNotEmpty()) {
getSearchResult(mTempSearchKey)
}
}
fun getSearchResult(searchKey: String) {
mTempSearchKey = searchKey
loadStatus.postValue(LoadStatus.INIT_LOADING)
RetrofitManager
.getInstance(getApplication()).api
.getSearchGame(Config.API_HOST + "games:search?keyword=" + searchKey + "&view=anliwall")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<GameEntity>>() {
override fun onResponse(response: List<GameEntity>?) {
super.onResponse(response)
mTempSearchKey = ""
if (response != null && response.isNotEmpty()) {
loadStatus.postValue(LoadStatus.INIT_LOADED)
} else {
loadStatus.postValue(LoadStatus.INIT_EMPTY)
}
searchGames.postValue(response)
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
loadStatus.postValue(LoadStatus.INIT_FAILED)
}
})
}
@SuppressLint("CheckResult")
fun getPlayedGames() {
RetrofitManager.getInstance(getApplication())
.api
.getPlayedGames(UserManager.getInstance().userId, 1, Utils.getTime(getApplication()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<GameEntity>>() {
override fun onSuccess(data: List<GameEntity>) {
val sortedList = data.sortedBy { !it.showComment }
playedGames.postValue(sortedList.take(5))
}
})
}
fun canUserCommentThisGame(gameEntity: GameEntity): String? {
val packageNameList = ArrayList<String>()
for (apk in gameEntity.getApk()) {
val packageName = apk.packageName
if (!TextUtils.isEmpty(packageName)
// 过滤黑名单包名
&& !PackageHelper.commentPackageNameBlackList.contains(packageName)
&& !PackageHelper.downloadPackageNameBlackList.contains(packageName)) {
packageNameList.add(packageName)
}
}
for (packageName in packageNameList) {
if (PackageHelper.localPackageNameSet.contains(packageName)) {
return packageName
}
}
return null
}
}

View File

@ -0,0 +1,72 @@
package com.gh.gamecenter.baselist
import android.annotation.SuppressLint
import android.content.Context
import android.os.AsyncTask
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.lightgame.adapter.BaseRecyclerAdapter
abstract class DiffUtilAdapter<DataType>(context: Context) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
protected var mDataList = ArrayList<DataType>()
@SuppressLint("StaticFieldLeak")
fun submitList(updateData: List<DataType>?) {
if (updateData.isNullOrEmpty()) {
mDataList.clear()
notifyDataSetChanged()
return
}
if (mDataList.size > updateData.size) {
mDataList = ArrayList(updateData)
notifyDataSetChanged()
return
}
object : AsyncTask<Void, Void, DiffUtil.DiffResult>() {
override fun doInBackground(vararg voids: Void): DiffUtil.DiffResult {
return DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return mDataList.size
}
override fun getNewListSize(): Int {
return updateData.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
if (oldItemPosition >= mDataList.size) return false
if (newItemPosition >= updateData.size) return false
val oldItem = mDataList[oldItemPosition]
val newItem = updateData[newItemPosition]
return areItemsTheSame(oldItem, newItem)
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
if (oldItemPosition >= mDataList.size) return false
if (newItemPosition >= updateData.size) return false
val oldItem = mDataList[oldItemPosition]
val newItem = updateData[newItemPosition]
return areContentsTheSame(oldItem, newItem)
}
})
}
override fun onPostExecute(diffResult: DiffUtil.DiffResult) {
mDataList = ArrayList(updateData)
diffResult.dispatchUpdatesTo(this@DiffUtilAdapter)
}
}.execute()
}
protected open fun areItemsTheSame(oldItem: DataType, newItem: DataType): Boolean {
return oldItem == newItem
}
protected open fun areContentsTheSame(oldItem: DataType, newItem: DataType): Boolean {
return oldItem == newItem
}
}

View File

@ -12,7 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.gh.base.BaseActivity;
import com.gh.base.ToolBarActivity;
import com.gh.common.view.FixLinearLayoutManager;
import com.gh.common.view.VerticalItemDecoration;
import com.gh.gamecenter.R;
@ -27,7 +27,7 @@ import io.reactivex.Observable;
import io.reactivex.Single;
public abstract class ListActivity<T, VM extends BaseListViewModel /* 该泛型位置对应getViewModelClass */>
extends BaseActivity
extends ToolBarActivity
implements Observer<List<T>>,
SwipeRefreshLayout.OnRefreshListener,
OnDataObservable {

View File

@ -1,19 +1,17 @@
package com.gh.gamecenter.download;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Message;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
@ -28,8 +26,8 @@ import com.gh.gamecenter.R;
import com.gh.gamecenter.eventbus.EBDownloadChanged;
import com.gh.gamecenter.eventbus.EBMiPush;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.eventbus.EBUISwitch;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadConfig;
@ -202,15 +200,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
mNoDataSkip.setVisibility(View.GONE);
mNoDataSkipHintTv.setText("暂无下载");
mNoDataSkipBtn.setText("去首页看看");
mNoDataSkipBtn.setOnClickListener(v -> {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(intent);
mNoDataSkipBtn.postDelayed(() ->
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 0)),
300);
});
mNoDataSkipBtn.setOnClickListener(v -> MainActivity.skipToMainActivity(getActivity(), MainWrapperFragment.INDEX_HOME));
mDownloadmanagerRv.setHasFixedSize(true);
adapter = new GameDownloadFragmentAdapter(getActivity(), mNoDataSkip, url);

View File

@ -1,29 +1,25 @@
package com.gh.gamecenter.download;
import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@ -76,14 +72,7 @@ public class GameUpdateFragment extends BaseFragment {
mGameUpdateNoDataSkip.setVisibility(View.GONE);
mNoDataHintTv.setText("暂无更新");
mNoDataHintBtn.setText("去首页看看");
mNoDataHintBtn.setOnClickListener(v -> {
Intent intent1 = new Intent(getActivity(), MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(intent1);
mNoDataHintBtn.postDelayed(() -> {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 0));
}, 300);
});
mNoDataHintBtn.setOnClickListener(v -> MainActivity.skipToMainActivity(getActivity(), MainWrapperFragment.INDEX_HOME));
mGameUpdateRv.setHasFixedSize(true);
mGameUpdateRv.setLayoutManager(new LinearLayoutManager(getActivity()));

View File

@ -22,13 +22,12 @@ import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.GameInstall
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.normal.NormalFragment
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -77,8 +76,7 @@ class InstalledGameFragment : NormalFragment(), OnRequestCallBackListener<Any> {
mNoDataSkipHint.text = "暂无游戏"
mNoDataSkipBtn.text = "查看精品推荐"
mNoDataSkipBtn.setOnClickListener {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 0))
requireActivity().finish()
MainActivity.skipToMainActivity(getActivity(), MainWrapperFragment.INDEX_HOME)
}
mInstallRv.layoutManager = LinearLayoutManager(requireContext())

View File

@ -0,0 +1,24 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class AmwayCommentEntity(
@SerializedName("_id")
var id: String,
var game: Game,
var comment: RatingComment,
var time: Long) : Parcelable {
@Parcelize
data class Game(
@SerializedName("_id")
var id: String,
var icon: String,
var name: String,
@SerializedName(value="tag", alternate=["tag_style"])
var tag: List<TagStyleEntity>? = arrayListOf(),
var star: Float) : Parcelable
}

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@ -9,6 +10,11 @@ data class ArticleCommentParent(val user: User = User(),
val comment: String = "") : Parcelable
@Parcelize
data class User(val name: String = "") : Parcelable
data class User(
@SerializedName("_id")
val id: String = "",
val name: String = "",
val icon: String = "",
val badge: Badge? = null) : Parcelable

View File

@ -0,0 +1,16 @@
package com.gh.gamecenter.entity
import androidx.room.TypeConverter
import com.google.gson.Gson
class BadgeConverter {
@TypeConverter
fun toBadge(badge: Badge?): String? {
return Gson().toJson(badge)
}
@TypeConverter
fun fromBadge(badge: String?): Badge? {
return Gson().fromJson(badge, Badge::class.java)
}
}

View File

@ -0,0 +1,13 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
data class BadgeEntity(
@SerializedName(value = "_id")
var id: String = "",
var expire: Int = 0,
var icon: String = "",
var name: String = "", //获取时间
var time: Int = 0, //有效期0代表无限期
val wear: Boolean = false //是否佩戴
)

View File

@ -1,11 +1,17 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class CommentParentEntity(var user: UserEntity? = null,
var content: String? = null,
var name: String? = null,
var comment: String? = null,
var active: Boolean = true) : Parcelable
data class CommentParentEntity(
var icon: String? = "",
@SerializedName("_id")
var id: String? = "",
var user: UserEntity? = null,
var content: String? = null,
var name: String? = null,
var comment: String? = null,
var active: Boolean = true,
var badge: Badge? = null) : Parcelable

View File

@ -13,6 +13,7 @@ data class ErrorEntity(var code: Int? = 0,
var gameId: String = "",
@SerializedName("game_name")
var gameName: String = "",
var nickname: String = "",
// post question
@SerializedName("question_id")

View File

@ -9,7 +9,8 @@ data class FollowersOrFansEntity(
val name: String = "",
val count: Count = Count(),
val me: MeEntity = MeEntity(),
val auth: Auth = Auth()) {
val auth: Auth = Auth(),
val badge: Badge? = null) {
data class Count(
val vote: Int = 0,

View File

@ -5,4 +5,5 @@ import com.google.gson.annotations.SerializedName
class GameColumnCollection(@SerializedName("_id")
val id: String = "",
val name: String = "",
val style: String = "")
// 取值为 "1-1" 或 "1-2" 或 "top" 相应地代表 1行1个 或 1行2个 或 排行榜
val style: String = "" )

View File

@ -126,12 +126,29 @@ data class GameEntity(
@SerializedName("rating_open")
var isRatingOpen: Boolean = false,
// 分类,取值有 online (网络游戏) 和 local (单机游戏)
@SerializedName("show_comment")
var showComment: Boolean = false, // 游戏评论是否打开
// 分类,取值有 online (网络游戏) , local (单机游戏) welfare (福利游戏)
var category: String? = "",
// 7天下载量
val download: Int = 0,
// subject -> imageSlide
val games: List<GameEntity>? = null) : Parcelable {
val games: List<GameEntity>? = null,
//首页设置
@SerializedName("home_setting")
val homeSetting: HomeSetting = HomeSetting(),
// 游戏评分
val star: Float = 10F,
// 游戏评分数量
@SerializedName("comment_count")
val commentCount: Int = 0,
// 是否支持不安装直接评论
@SerializedName("direct_comment")
var directComment: Boolean = false,
// xxx人想玩
val visit: Int = 0) : Parcelable {
@IgnoredOnParcel
private var entryMap: androidx.collection.ArrayMap<String, DownloadEntity>? = androidx.collection.ArrayMap()
@ -219,17 +236,12 @@ data class GameEntity(
/**
* 游戏所属类型
* 网络游戏category 为 online 且 tag 不含福利版的游戏
* 网络游戏category 为 online 的游戏
* 单机游戏category 为 local 的游戏
* 福利游戏:tag 包含福利版的游戏
* 福利游戏:category 为 welfare 的游戏
*/
private fun isOnlineGame(): Boolean {
return if (tag.isNullOrEmpty()) {
category.equals("online")
} else {
category.equals("online") && !tag!!.contains("福利版")
}
return category.equals("online")
}
private fun isLocalGame(): Boolean {
@ -237,11 +249,7 @@ data class GameEntity(
}
private fun isWelfareGame(): Boolean {
return if (tag.isNullOrEmpty()) {
false
} else {
tag!!.contains("福利版")
}
return category.equals("welfare")
}
fun clone(): GameEntity {

View File

@ -0,0 +1,16 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
data class HomeContent(@SerializedName("link_type")
val linkType: String = "",
@SerializedName("link_id")
val linkId: String = "",
@SerializedName("link_text")
val linkText: String = "",
@SerializedName("link_game")
val linkGame: GameEntity? = null,
@SerializedName("link_column")
val linkColumn: SubjectEntity? = null,
@SerializedName("link_top_game_comment")
val linkTopGameComment: List<AmwayCommentEntity>? = null)

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