Compare commits

...

601 Commits

Author SHA1 Message Date
045dea265d 3.7.1-game tinker base 2019-12-20 10:09:36 +08:00
998cf70723 游戏库图标增加占位符/预加载
升级fresco库
对DiffUtilAdapter DiffUtil 进行 try catch 处理
2019-12-19 16:33:49 +08:00
eb112b358e tinker base 3.7.1-game-tab 2019-12-18 17:24:33 +08:00
b860ab912a 修改游戏库显示逻辑 2019-12-18 16:30:15 +08:00
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
baa22ae9c9 3.7.0 tinker base 2019-10-30 16:39:42 +08:00
dba3854e40 设置 largeHeap=true 以分配尽量大的内存预防OOM 2019-10-30 16:16:02 +08:00
1f06810592 修复游戏详情页 toolbar 滑动造成的 卡顿/OOM 问题 2019-10-30 16:00:16 +08:00
2861e8cfee 修复专题合集分页问题 2019-10-30 14:03:02 +08:00
9269548d64 V3.7.1游戏详情评分优化UI 2019-10-30 11:59:06 +08:00
712399e9da 3.7.0 tinker base 2019-10-29 18:07:15 +08:00
1654d36126 工具箱顶部返回按钮调整为点击关闭页面 https://gitlab.ghzs.com/pm/halo-app-issues/issues/686 2019-10-29 10:55:00 +08:00
245e113d76 修复视频相关分页问题 2019-10-28 18:12:13 +08:00
8b35993e99 修复纵向专题存在头图时显示异常问题 2019-10-28 16:00:36 +08:00
3dcaf7b50e 修改视频合集UI 2019-10-25 17:19:56 +08:00
58d4b5e612 列表刷新问题 2019-10-25 16:34:14 +08:00
caf0852f28 修改首页游戏/板块的列表刷新方式(防止列表刷新抖动)
部分页面捕获由于列表刷新导致的闪退问题
2019-10-25 16:19:02 +08:00
558fe249ac Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-25 11:50:26 +08:00
20b0c83fc0 首页社区引导提示UI适配 2019-10-25 11:50:19 +08:00
0c3020f7b3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-25 11:39:51 +08:00
fce10714ae 20191025测试补充 3 https://gitlab.ghzs.com/pm/halo-app-issues/issues/674 2019-10-25 11:39:43 +08:00
8055856dd7 修复个人主页某些区域无法滑动的问题 2019-10-25 10:04:46 +08:00
a8c540f122 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-25 09:49:12 +08:00
ccf117656a 横向游戏列表的游戏名称换行时自动补全 2019-10-25 09:49:06 +08:00
6b5cf36957 修复应用内网页跳转闪退的问题 2019-10-24 18:23:00 +08:00
201f0317a2 修复 MTA 字段统计问题 2019-10-24 18:15:32 +08:00
ea9bb99afa 完成3.7.0(1022测试汇总)(11~14) https://gitlab.ghzs.com/pm/halo-app-issues/issues/674 2019-10-24 18:11:31 +08:00
51609dea83 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-24 18:07:36 +08:00
d9788434f3 修改bufferPoint的问题、游戏详情页面图标 2019-10-24 18:07:31 +08:00
b0d433b5c8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-24 15:30:47 +08:00
df3dd297c1 光环助手V3.7.0 RELEASE(20191022-1830)测试汇总(7.8.9.10.15) https://gitlab.ghzs.com/pm/halo-app-issues/issues/674 2019-10-24 15:30:39 +08:00
1a9ee5e3cb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-24 10:35:45 +08:00
a22da040e0 光环助手V3.7.0 RELEASE(20191022-1830)测试汇总(3,4,5) https://gitlab.ghzs.com/pm/halo-app-issues/issues/674 2019-10-24 10:35:39 +08:00
4c0ee93826 修复 MTA 视频播放统计问题 2019-10-24 10:24:03 +08:00
759a22fc52 修复 chucker 返回体没有格式化的问题 2019-10-24 09:15:30 +08:00
066b667bd8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-23 17:48:35 +08:00
91e5e4f53b 链接跳转如果没有目标页面,则默认跳转至首页 2019-10-23 17:48:27 +08:00
7cfd1a9c7d 修改视频播放布局 2019-10-23 15:54:55 +08:00
ed78421d9b 修改视频播放布局 2019-10-23 15:42:01 +08:00
0e85be5dc6 视频详情播放优化 2019-10-23 14:51:49 +08:00
23721ad189 视频上传,视频类型使用真实的视频类型(使用MimeType获取) 2019-10-22 18:24:28 +08:00
50c7f6514e 弹窗偏移 2019-10-22 17:27:41 +08:00
7818370d7e Merge remote-tracking branch 'origin/dev' into dev 2019-10-21 23:49:51 +08:00
2f05256103 播放完立马刷新游戏详情顶部视频封面图 2019-10-21 23:49:34 +08:00
ed1dc14bc5 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 23:40:26 +08:00
ae2b0e9d7e 修改视频上传文案 2019-10-21 23:39:11 +08:00
b9d23115c6 还原启动页的权限申请 2019-10-21 23:33:24 +08:00
c72da10e56 修复游戏详情页顶部视频全屏播放完以后没有封面图的问题,修复游戏详情顶部视频无网络有缓存时会弹错误toast的问题 2019-10-21 23:19:51 +08:00
a4f4b0c3f9 视频投稿优化 2019-10-21 22:54:32 +08:00
5c0a51be73 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-10-21 22:52:51 +08:00
069b6d7df6 上传优化 2019-10-21 22:51:31 +08:00
fea7aee20b Merge remote-tracking branch 'origin/dev' into dev 2019-10-21 22:44:58 +08:00
26dd26d7c0 修复资讯文章评论内容点击效果失效的问题 2019-10-21 22:44:48 +08:00
4e06147b82 去除toast生命周期限制 2019-10-21 22:16:52 +08:00
1065abcd44 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 22:06:52 +08:00
cf5e40788b 视频上传修改toast文案 2019-10-21 22:06:43 +08:00
93ff2651c4 Merge remote-tracking branch 'origin/dev' into dev 2019-10-21 21:49:50 +08:00
de9689c1a2 webview 支持 scheme 为 ghzhushou 的超链接 2019-10-21 21:49:40 +08:00
24379be99d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 21:25:08 +08:00
75bec6e967 光环助手V3.7.0 RELEASE(20191021-1000)视频测试汇总 (1.2.3.4.5.12.13.14.15) https://gitlab.ghzs.com/pm/halo-app-issues/issues/672 2019-10-21 21:24:56 +08:00
c3eb5f8d08 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 21:24:34 +08:00
13c1866fa2 点击评论内容无反应 2019-10-21 21:24:29 +08:00
4ab8a5b7bb 微调 UI 2019-10-21 21:22:00 +08:00
821434bd7c 光环助手V3.7.0 DEV(20191021-0955)前端测试汇总(5,10)https://gitlab.ghzs.com/pm/halo-app-issues/issues/673 2019-10-21 21:20:09 +08:00
ab3d29d449 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 20:37:12 +08:00
1ee5a1d110 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt
2019-10-21 20:37:07 +08:00
19910ab0a8 调整分享视频的图片尺寸 https://gitlab.ghzs.com/pm/halo-app-issues/issues/672 2019-10-21 20:36:31 +08:00
727f513431 光环助手V3.7.0 DEV(20191019-1830)视频测试汇总(3,5,6) https://gitlab.ghzs.com/pm/halo-app-issues/issues/671 2019-10-21 20:35:43 +08:00
5eac22f0be 修复游戏详情页多次进入/退出全屏以后出现的异常问题 2019-10-21 20:34:16 +08:00
360efccf4c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 19:38:09 +08:00
57ac0a0bb9 社区选择图片页面只显示图片内容
开服表优化
2019-10-21 19:38:03 +08:00
80c2e34460 调整开服表曝光的来源 2019-10-21 18:09:46 +08:00
78e652ea27 Merge remote-tracking branch 'origin/dev' into dev 2019-10-21 17:49:35 +08:00
fc7d36ac22 补充3.7.0 MTA遗漏事件 https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-21 17:49:26 +08:00
1a4e4fedb6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 17:38:13 +08:00
5ff7c58503 光环助手V3.7.0 DEV(20191019-1830)视频测试汇总(12) https://gitlab.ghzs.com/pm/halo-app-issues/issues/671 2019-10-21 17:38:08 +08:00
25488e9100 完成开服表的 MTA 统计 https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-21 17:35:12 +08:00
d4bf86f717 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 17:28:44 +08:00
1cd463968e 视频上传相关优化 2019-10-21 17:28:37 +08:00
6388941e81 完成3.7.0(1019测试汇总)(1~2, 17~19, 23~27) https://gitlab.ghzs.com/pm/halo-app-issues/issues/671 2019-10-21 16:54:39 +08:00
48dd87ce26 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 16:42:41 +08:00
76643aae59 光环助手V3.7.0 DEV(20191019-1820)前端测试汇总(2.3.4.5.6.7.13.14)https://gitlab.ghzs.com/pm/halo-app-issues/issues/670 2019-10-21 16:42:24 +08:00
86c9c077bf 3.7.0 DEV(20191019-1830)(4、7-11、13-16、29)https://gitlab.ghzs.com/pm/halo-app-issues/issues/671 2019-10-21 16:37:01 +08:00
6510e620ba 完成3.7.0(1820测试汇总)(9,10,16~18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/670 2019-10-21 12:35:17 +08:00
7d2149ad23 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-21 10:50:13 +08:00
87b3c35ba2 视频详情缓存失败,点重试视频从失败位置播放 2019-10-21 10:50:08 +08:00
f7fdadd4f4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-20 17:47:15 +08:00
d6ef599b08 光环助手V3.7.0 DEV(20191017-2125)前端测试汇总(7.8.9) https://gitlab.ghzs.com/pm/halo-app-issues/issues/669 2019-10-20 17:47:06 +08:00
4b7a5ad049 视频详情游戏信息逻辑修改 2019-10-20 16:18:52 +08:00
6f3ad4bec4 游戏详情开服表相关修改 2019-10-20 14:46:16 +08:00
87047fe38d 光环助手V3.7.0 DEV(20191017-2125)前端测试汇总(12、13)https://gitlab.ghzs.com/pm/halo-app-issues/issues/669 2019-10-20 10:28:44 +08:00
5627cd9ca2 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/kaifu/refactor/GameServersContentFragment.java
2019-10-20 10:14:06 +08:00
0bfab3ba9c 删除总开服表旧代码
总开服表增加时间栏悬挂
2019-10-20 10:12:29 +08:00
10b692bb2b 曝光区分开测表和开服表 2019-10-19 18:22:24 +08:00
663c415a57 调整隐私弹窗样式 2019-10-19 18:03:11 +08:00
5f60126333 完成MTA数据统计需求(1019测试问题) https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-19 17:04:29 +08:00
986b99479d 完成光环助手3.7.0(1017测试汇总)(1~2, 17~19) https://gitlab.ghzs.com/pm/halo-app-issues/issues/669 2019-10-19 16:33:50 +08:00
cbbf4b71c2 完成权限弹窗优化(三) https://gitlab.ghzs.com/pm/halo-app-issues/issues/668 2019-10-19 11:49:21 +08:00
4398bea8d4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-18 18:30:18 +08:00
e85ac755ae 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总(20)https://gitlab.ghzs.com/pm/halo-app-issues/issues/666 2019-10-18 18:30:12 +08:00
fa2f91cb24 捕获空指针异常 2019-10-18 18:27:43 +08:00
ff30c8d288 修复游戏详情页页面重建会闪退的问题 2019-10-18 18:17:55 +08:00
fd5807d404 社区用户引导提示UI修改 2019-10-18 17:46:01 +08:00
719133a636 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-18 17:33:18 +08:00
5650f65214 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总1(18.22)https://gitlab.ghzs.com/pm/halo-app-issues/issues/667 2019-10-18 17:33:12 +08:00
7bc4c8e661 Base64 图片增加保存后缀 2019-10-18 14:53:38 +08:00
48c7d94edc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-18 11:38:09 +08:00
2d63db64b2 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总(9-17)https://gitlab.ghzs.com/pm/halo-app-issues/issues/667 2019-10-18 11:38:04 +08:00
3a26750e15 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-18 11:23:34 +08:00
517bd63ac0 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总1(1.2.3.4.5.6.7.8)https://gitlab.ghzs.com/pm/halo-app-issues/issues/667 2019-10-18 11:23:28 +08:00
ef77fca3bb 修复消息中心的闪退问题 2019-10-18 11:11:32 +08:00
dde7ed096a 查看图片支持 BASE64 图片 2019-10-18 10:59:13 +08:00
834db84d43 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-17 21:02:58 +08:00
93e81879fd 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总1(20.21.23.24.25)https://gitlab.ghzs.com/pm/halo-app-issues/issues/667 2019-10-17 21:02:47 +08:00
9263805bb4 隐藏我的关注和我的预约的游戏大小 2019-10-17 21:01:44 +08:00
5467df5850 完成视频测试汇总(18, 19) https://gitlab.ghzs.com/pm/halo-app-issues/issues/666 2019-10-17 20:38:33 +08:00
02836a2dee 修复覆盖安装问题 2019-10-17 19:29:37 +08:00
9747ff1056 修复覆盖安装闪退问题 2019-10-17 18:25:50 +08:00
ce38932e86 光环助手V3.7.0 DEV(20191015-1100)视频测试汇总(一、二)https://gitlab.ghzs.com/pm/halo-app-issues/issues/666 2019-10-17 18:17:19 +08:00
fc76d98fbc 修复撰写社区文章无法显示默认标签问题 2019-10-17 15:25:16 +08:00
4a4f1b86df Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/common/util/ErrorHelper.kt
2019-10-17 15:05:24 +08:00
6f75f212b8 修复由于禁言数据always_block字段缺失造成的闪退问题 2019-10-17 15:03:45 +08:00
1051d46a79 完成视频详情汇总(16, 17) https://gitlab.ghzs.com/pm/halo-app-issues/issues/666 2019-10-17 14:50:12 +08:00
41bb08d899 处理闪退问题 2019-10-17 11:50:08 +08:00
afef9847b1 处理一些闪退问题 2019-10-17 11:28:58 +08:00
2fe83bcf14 新增供 HTML5 调用的方法 2019-10-17 11:03:11 +08:00
8529980040 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-17 10:30:16 +08:00
fbf11eff3d 修改首页专题UI 2019-10-17 10:30:06 +08:00
1d0e8505f6 适配首页/板块的竖屏滑动专题的曝光统计 2019-10-15 18:26:10 +08:00
332f63e823 调整文案 2019-10-15 18:25:15 +08:00
f5062d554e 修复首页游戏多个竖屏滑动专题闪退问题
竖屏滑动专题适配头图
2019-10-15 17:31:24 +08:00
5d6f3f249b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-15 14:23:56 +08:00
f6e524ca14 数据库AnswerEntity表增加字段 2019-10-15 14:23:50 +08:00
f5768ee8ae 完成我的游戏-玩过&关注&预约页面优化(20191014测试) https://gitlab.ghzs.com/pm/halo-app-issues/issues/612 2019-10-15 14:22:20 +08:00
53df43b5a8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-15 14:17:35 +08:00
817004f96d 开服表修改 2019-10-15 14:17:27 +08:00
e54262a320 调整跳转至视频详情的视频列表排序 2019-10-15 11:52:34 +08:00
26ab8355fd 修改游戏上传协议文案 2019-10-15 11:06:10 +08:00
633b5532e2 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
#	app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt
2019-10-15 10:19:44 +08:00
68809149c5 光环助手V3.7.0-游戏视频功能-前端5(问答相关)(20191014测试汇总(1.2.4.5))https://gitlab.ghzs.com/pm/halo-app-issues/issues/626 2019-10-15 10:16:27 +08:00
5d8d65f5b5 捕抓空指针异常 2019-10-15 09:44:27 +08:00
d29122af52 完成 Loghub 进入问答上报 https://gitlab.ghzs.com/pm/halo-app-issues/issues/661 2019-10-14 20:57:04 +08:00
53898a0465 调整评论详情关闭下载的按钮UI 2019-10-14 20:41:44 +08:00
9038a41301 微调个人主页UI https://gitlab.ghzs.com/pm/halo-app-issues/issues/640 2019-10-14 20:08:17 +08:00
52349dc043 完成3.7数据统计需求(MTA) https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-14 19:59:57 +08:00
26eca76036 问答社区首页UI优化 (1014测试问题)https://gitlab.ghzs.com/pm/halo-app-issues/issues/610 2019-10-14 17:42:25 +08:00
7deb934b5a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-14 17:05:33 +08:00
b8e02f1ab9 update LGLibrary version 2019-10-14 17:04:56 +08:00
07b2cf3d95 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-14 16:54:36 +08:00
0f06b1e401 修改游戏介绍文字 2019-10-14 16:54:28 +08:00
432553d90b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-14 16:51:36 +08:00
8a51187f01 修复问答-选择问答专区 游戏名字 和 “当前选择” 显示异常问题 2019-10-14 16:51:27 +08:00
c63a1a1fd2 光环前端优化汇总(2019年10月第3周)(2~4,7~10) https://gitlab.ghzs.com/pm/halo-app-issues/issues/664 2019-10-14 16:49:52 +08:00
ab03b4d88e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-14 16:47:29 +08:00
bcce233795 光环助手V3.7.0-开服表功能优化(20191014测试) https://gitlab.ghzs.com/pm/halo-app-issues/issues/628 2019-10-14 16:47:19 +08:00
fe77112ca6 修改反射获取bufferPoint导致的NoSuchFieldException问题 2019-10-14 14:17:21 +08:00
e3a4dbbbb3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/qa/all/AskAllFragment.kt
2019-10-14 10:12:16 +08:00
4a19e7beed 社区相关UI修改 2019-10-14 10:09:07 +08:00
6b6ed81c4a 升级gsyVideo、解决视频详情不能播放问题 2019-10-14 09:56:02 +08:00
d69717d08d Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-10-14 09:34:27 +08:00
e8e43a28d2 完成部分3.7数据统计需求(MTA)(7~10) https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-14 09:33:47 +08:00
03a89a1553 完成部分视频测试汇总(游戏详情)(7~10) https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-12 18:29:02 +08:00
71eb06ba2c 修改缓冲未完成循环播放问题 2019-10-12 18:00:27 +08:00
4e7a73a450 光环助手V3.7.0-开服表功能优化(20191012测试)https://gitlab.ghzs.com/pm/halo-app-issues/issues/628 2019-10-12 17:42:02 +08:00
a893303517 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-12 15:42:44 +08:00
4ccb5fe7f2 对接社区文章详情和回答详情的视频跳转 2019-10-12 15:42:32 +08:00
21f3ff57bc Merge remote-tracking branch 'origin/dev' into dev 2019-10-12 14:38:36 +08:00
d07d743de9 用户评分点击游戏跳转到游戏详情不再锁定评论tab https://gitlab.ghzs.com/pm/halo-app-issues/issues/650 2019-10-12 14:38:23 +08:00
6c41b1cb9f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-12 11:24:01 +08:00
1d5206fa8d 光环助手V3.7.0 DEV(20190927-1830)视频详情(测试汇总)(6、7)https://gitlab.ghzs.com/pm/halo-app-issues/issues/659#note_30652 2019-10-12 11:23:54 +08:00
d2d7a84446 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2019-10-12 09:36:52 +08:00
91218c90fb 调整文案 2019-10-12 09:36:39 +08:00
1db3872cbb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-12 09:36:21 +08:00
766aca3708 撰写文章文案修改 2019-10-12 09:36:09 +08:00
04a05a4017 完成部分3.7数据统计需求(MTA)(1~6) https://gitlab.ghzs.com/pm/halo-app-issues/issues/660 2019-10-11 18:25:41 +08:00
a46cee919f 完成个人主页改版(第一期)(1011测试问题) https://gitlab.ghzs.com/pm/halo-app-issues/issues/640 2019-10-11 18:18:31 +08:00
f2877e36a6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-11 17:04:05 +08:00
c8056c5ba9 调整 选择问答专区
UI
2019-10-11 17:03:54 +08:00
1eb95269e8 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-11 16:31:14 +08:00
23906131ec 光环助手V3.7.0 DEV(20190927-1830)视频详情(测试汇总)(5、8、9、10-15)https://gitlab.ghzs.com/pm/halo-app-issues/issues/659 2019-10-11 16:31:09 +08:00
23ca0bfb6f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-11 16:29:34 +08:00
8c055620d0 光环助手V3.7.0-开服表功能优化(20191011测试) https://gitlab.ghzs.com/pm/halo-app-issues/issues/628 2019-10-11 16:29:29 +08:00
ead2d66295 更改个人主页和游戏详情-评论的展开选项按钮状态 https://gitlab.ghzs.com/pm/halo-app-issues/issues/640 2019-10-11 11:48:10 +08:00
39b9cce4d8 完成视频测试汇总(游戏详情)(9~18) https://gitlab.ghzs.com/pm/halo-app-issues/issues/662 2019-10-11 11:09:29 +08:00
3567909675 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-11 10:32:50 +08:00
d79cc1499f 修复提交视频后无法及时刷新草稿箱问题 2019-10-11 10:32:39 +08:00
9674515171 完成我的游戏-玩过&关注&预约页面优化 20191010测试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/612 2019-10-10 18:29:20 +08:00
2ee39c249c 视频专题优化 2019-10-10 18:09:57 +08:00
2ae6829a65 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-10 17:40:41 +08:00
9c9fb54932 跳转社区问答专区UI 2019-10-10 17:40:27 +08:00
713cb287bb 修改竖直滚动播放视频 2019-10-10 16:20:15 +08:00
b47805cbbf 竖直滚动播放视频 2019-10-10 15:26:35 +08:00
6aa5c7cd74 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/video/detail/VideoDetailContainerFragment.kt
2019-10-10 11:48:23 +08:00
97da1506dd 竖直滚动播放视频 2019-10-10 11:44:35 +08:00
ed193f99a4 修复视频详情的一些显示问题 2019-10-10 11:38:48 +08:00
96f86ff0eb 微调社区搜索UI 2019-10-09 18:27:00 +08:00
f2bcb18688 社区搜索适配视频缩略图 2019-10-09 18:06:06 +08:00
b5f7d78a26 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-09 17:14:55 +08:00
08cdab0f50 光环助手V3.7.0-游戏详情评论优化(20191009测试汇总:3.4.5.6.7) https://gitlab.ghzs.com/pm/halo-app-issues/issues/634 2019-10-09 17:14:38 +08:00
2a2f5b089d 修改20191008测试bug https://gitlab.ghzs.com/pm/halo-app-issues/issues/652 2019-10-09 17:06:55 +08:00
a21ceabfdf 微调个人主页UI 2019-10-09 17:02:15 +08:00
fe4dc13b84 完成3.7.0前端优化汇总(2019年9月第3周)(5,6) https://gitlab.ghzs.com/pm/halo-app-issues/issues/650 2019-10-09 16:51:46 +08:00
70730e8628 基本完成光环助手V3.7.0-个人主页改版(第一期) https://gitlab.ghzs.com/pm/halo-app-issues/issues/640 2019-10-09 16:04:20 +08:00
adceb92796 tabIndicator 支持自定义颜色 2019-10-09 14:31:16 +08:00
55336f6be4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-08 16:43:43 +08:00
25663d114a fix window.NativeCallBack.isNativeBuildDebug not function 2019-10-08 16:43:24 +08:00
d80592fbb7 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-08 15:47:36 +08:00
7fab331b90 光环助手V3.7.0-问答社区相关(9-12) 2019-10-08 15:46:17 +08:00
6c5c43d595 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-10-08 15:18:06 +08:00
1b49aaa6fc 微调视频相关UI/字体颜色 2019-10-08 15:17:54 +08:00
ed1725f9cc 光环助手V3.7.0-问答社区相关(13) 2019-10-08 11:21:37 +08:00
8d5cc4e983 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/values/colors.xml
2019-10-08 10:14:19 +08:00
8a03017ccd 问题/回答/文章详情页面标题靠左 2019-10-08 10:14:01 +08:00
884d5d81f9 视频上传添加失败重试操作 2019-10-07 17:58:24 +08:00
95be563b43 光环助手V3.7.0 DEV(20190918-1830)视频上传(测试汇总)(2.3.7.8.9.10.11.13.15.16.18.19.20.21) https://gitlab.ghzs.com/pm/halo-app-issues/issues/657 2019-10-07 16:09:03 +08:00
6ae6a4e14a 光环助手V3.7.0-游戏视频功能-前端5(问答相关)(2)https://gitlab.ghzs.com/pm/halo-app-issues/issues/626 2019-10-06 17:35:06 +08:00
9b069a97d1 修改游戏评论“精彩评论”显示规则
修复游戏评论回复点赞消息中心红点显示异常问题
2019-10-06 10:31:57 +08:00
25f217217d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev
# Conflicts:
#	app/src/main/res/values/colors.xml
2019-09-30 18:33:58 +08:00
322f4fd268 修改问题详情/回答详情UI(15.16) https://gitlab.ghzs.com/pm/halo-app-issues/issues/650#note_30101 2019-09-30 18:33:14 +08:00
da55afb712 完成"社区提问相关功能强化"测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/618 2019-09-30 17:22:58 +08:00
5788052262 Merge remote-tracking branch 'origin/dev' into dev 2019-09-30 16:14:32 +08:00
4a56da6f2e 上传游戏(已完成) 2019-09-30 16:14:10 +08:00
770543fea5 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-30 16:09:16 +08:00
ed83feb112 评分相关的评论支持文本复制功能 2019-09-30 16:09:01 +08:00
223f264972 完成"光环助手V3.7.0-新增游戏下载状态" https://gitlab.ghzs.com/pm/halo-app-issues/issues/649 2019-09-30 10:33:37 +08:00
6c6f9f63f6 游戏投稿UI 2019-09-29 17:10:27 +08:00
58f761862f 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-09-29 17:08:20 +08:00
3a45de8eb3 问答选择社区页面UI更改 2019-09-29 17:07:24 +08:00
9a0ffb29e0 完成基础的新增游戏下载状态的处理逻辑,暂缺设计图 https://gitlab.ghzs.com/pm/halo-app-issues/issues/649 2019-09-29 16:09:06 +08:00
1d62818348 完成"我的游戏-玩过&关注&预约页面优化"测试问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/612#note_29333 2019-09-29 14:27:26 +08:00
5be789d100 fix RichEditor keyboard not working 2019-09-29 11:45:39 +08:00
7dd79bd4bb 专题合集优化 2019-09-29 09:56:58 +08:00
d0b6ee897c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-28 10:29:26 +08:00
2f03656869 问答相关的UI更改 2019-09-28 10:28:46 +08:00
5ac51c84b7 还原开服表和分类的下载入口传递的代码,与旧版本保持一致 2019-09-27 18:17:14 +08:00
ce71384dd9 完善通知提示弹窗 2019-09-27 18:12:35 +08:00
2a7db59e6b 补充今日头条SDK激活步骤 2019-09-27 18:11:52 +08:00
e561c13f28 完成引导强化系统“通知管理”功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/635 2019-09-27 18:03:38 +08:00
12981bd7ff 正式包数据接口切换到 3.7 2019-09-27 14:35:39 +08:00
208250d030 正式包数据接口切换到 3.7 2019-09-27 14:28:50 +08:00
d4598ac96f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-27 11:02:39 +08:00
293451e527 光环助手V3.7.0-新增 专题合集 功能(前端) https://gitlab.ghzs.com/pm/halo-app-issues/issues/645 2019-09-27 11:02:14 +08:00
fe19c84049 基本完成光环助手V3.7.0-游戏视频功能-前端4 https://gitlab.ghzs.com/pm/halo-app-issues/issues/625 2019-09-27 09:55:37 +08:00
7e0d5c3416 首页游戏横向item游戏名字适配 2019-09-26 14:53:36 +08:00
319fe2f556 完成游戏详情页游戏视频基本的滚动效果,细节功能待完善 https://gitlab.ghzs.com/pm/halo-app-issues/issues/625 2019-09-25 18:29:37 +08:00
6f6bffdeb7 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-09-25 16:30:00 +08:00
7c6271d4e9 修复总开服表下载刷新问题 2019-09-25 16:29:12 +08:00
5d3f082771 Merge remote-tracking branch 'origin/dev' into dev 2019-09-25 15:54:43 +08:00
abf6935653 去掉评论弹窗的状态栏变色 2019-09-25 15:54:19 +08:00
6eecad6bb6 游戏详情开服表优化(只要曾经设置过开服信息就显示) 2019-09-25 15:54:08 +08:00
12cea1f263 remove community hint dialog background 2019-09-24 16:56:35 +08:00
3150a182e6 问答社区首页UI优化(0918测试) https://gitlab.ghzs.com/pm/halo-app-issues/issues/610 2019-09-24 16:54:27 +08:00
56160193a9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-23 19:30:21 +08:00
859470aabf 总开服表重构 https://gitlab.ghzs.com/pm/halo-app-issues/issues/628 2019-09-23 19:30:07 +08:00
ad2dc5ac4b 修复点击游戏详情默认选中动态tab的问题 2019-09-23 18:16:56 +08:00
d32816aa65 预约按钮读取下载补充文字 2019-09-20 14:15:53 +08:00
64e99338b0 发表的内容支持复制文本功能(游戏评分部分未完成) https://gitlab.ghzs.com/pm/halo-app-issues/issues/651 2019-09-20 11:57:53 +08:00
88bcb2883c 修复跳转视频详情播放顺序错乱的问题 2019-09-20 11:03:42 +08:00
a70520f04f 修复首页竖屏滑动类型刷新问题 2019-09-20 10:27:37 +08:00
09521ec26a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-19 18:20:55 +08:00
f5b8049dd7 游戏专题优化(前端)(竖屏滑动类型刷新问题未解决) https://gitlab.ghzs.com/pm/halo-app-issues/issues/643 2019-09-19 18:20:46 +08:00
fe230d647a 补充编译带请求日志的脚本 2019-09-19 10:12:47 +08:00
33daa22e49 debug 模式增加网络请求 inspector 方便调试 2019-09-19 09:42:11 +08:00
80965dcbc9 隐藏我的游戏的大小 2019-09-18 18:29:31 +08:00
89f0cfb6a7 捕抓隐私弹窗异常 2019-09-18 18:15:39 +08:00
89884d4cd7 移除旧视频模块,整理游戏详情页代码 2019-09-18 17:54:46 +08:00
e9590f81be 完成插件跳转助手工具箱需求 https://gitlab.ghzs.com/pm/halo-app-issues/issues/636 2019-09-18 15:01:17 +08:00
83159e4153 更新广点通 SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/454 2019-09-18 11:30:06 +08:00
21dc20dff1 完成社区提问相关功能强化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/618 2019-09-18 11:12:34 +08:00
3ec6526aa4 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-18 09:53:43 +08:00
ba918b9144 删除WEB页面视频播放代码
优化插入视频后与图片的交互
优化插入视频页面
2019-09-18 09:53:30 +08:00
3a63d049dc 将列表的 skeleton 相关代码移动到基类 2019-09-17 11:01:57 +08:00
13011804ab 完成社区提问相关功能强化(1,2) https://gitlab.ghzs.com/pm/halo-app-issues/issues/618 2019-09-16 18:00:22 +08:00
1e2e621055 完成视频详情消息中心部分 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-16 16:09:24 +08:00
f53c3ff8ae 完成视频详情播放失败重试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-16 11:42:00 +08:00
b30e60dfde 完成视频详情移动网络弹窗功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-11 18:27:49 +08:00
34ac30cdfe 完成视频评论部分功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-11 17:22:57 +08:00
8bd30d1a0f 富文本编辑框增加插入视频功能 2019-09-11 14:45:51 +08:00
cbc575fcd0 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-09-10 17:23:34 +08:00
9720812714 光环助手V3.7.0-游戏视频功能-前端2(视频入口1) https://gitlab.ghzs.com/pm/halo-app-issues/issues/616 2019-09-10 17:22:41 +08:00
b9a8f3217f 完成视频详情页的点赞、收藏和分享功能 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-10 15:50:13 +08:00
cb812d2d6c 引入WEB视频相关的JS/CSS代码 2019-09-10 10:28:03 +08:00
572b35c4dc 修改游戏详情开服表月份切换问题 2019-09-10 10:02:01 +08:00
043486a53f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-09 18:34:36 +08:00
df68f8fb9c 光环前端需求汇总(2019年8月)(3.6.7.9)https://gitlab.ghzs.com/pm/halo-app-issues/issues/633 2019-09-09 18:34:20 +08:00
ee146b20e5 完成还十分粗糙的视频详情显示界面 2019-09-09 18:19:40 +08:00
936ca7d4ba change field name 2019-09-09 17:57:36 +08:00
57e37419cf 光环助手V3.7.0-游戏详情评论优化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/634 2019-09-09 17:19:04 +08:00
86934a789e 对接从WEB页面跳转至视频详情 2019-09-09 14:35:35 +08:00
9552d3ac25 禁止低版本设备使用视频投稿功能 2019-09-09 11:10:40 +08:00
9782e2a615 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-06 18:15:40 +08:00
7b8f5dfc5b 个人主页增加我的视频 2019-09-06 18:15:31 +08:00
f3fd311d70 修复开服表和分类的下载入口传递问题 2019-09-06 18:10:11 +08:00
5e7e71f6cc 修复 MTA移动网络下载 网络类型显示错误的问题 2019-09-06 16:10:58 +08:00
6cc4178cb3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-09-06 14:16:29 +08:00
49be7e9d12 修复上传格式缺失和视频链接错误问题 2019-09-06 14:16:19 +08:00
8f50626a3d Merge remote-tracking branch 'origin/dev' into dev 2019-09-05 20:43:42 +08:00
89cfd1a8ba 完成简单的视频操作逻辑 https://gitlab.ghzs.com/pm/halo-app-issues/issues/617 2019-09-05 20:43:27 +08:00
2e9ec0bde0 调整代码位置,修改视频封面上传路径 2019-09-05 18:34:37 +08:00
b77491e91e 修复上传错误无法回调问题 2019-09-05 18:17:36 +08:00
65b84b0e4a Matisse add apply filter 2019-09-05 17:00:13 +08:00
e9cb8fcde8 视频草稿增加删除操作
优化视频上传页面交互
2019-09-05 16:05:30 +08:00
aa04f67f43 优化视频上传 2019-09-05 10:48:23 +08:00
3710a2b729 视频上传增加草稿保存提示弹窗 2019-09-04 20:14:35 +08:00
96cadd05f1 完善存草稿,投稿操作
完善已投稿,草稿箱页面
增加草稿修改操作
2019-09-04 17:53:11 +08:00
114f014091 打包脚本开始打包前先释放上次打包占用的资源 2019-09-03 20:50:00 +08:00
960c596db8 完成我的游戏-玩过&关注&预约页面优化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/612 2019-09-03 20:22:41 +08:00
fe6ebd8aa7 完成新增 我的游戏-玩过 页面 2019-09-02 18:29:57 +08:00
f121b04e66 修复可能的下载闪退问题 2019-09-02 18:29:14 +08:00
4724b809dd 上传视频页面增加分类,标签,存草稿,投稿等操作 2019-08-31 17:17:35 +08:00
5353581cf1 上传视频相关 2019-08-31 11:23:02 +08:00
68f60db4c0 上传视频相关 2019-08-30 18:20:03 +08:00
e90e514f8b 修复提交评分game_version字段丢失问题
整理视频上传相关
2019-08-29 16:34:41 +08:00
6ab04cf056 完善视频上传、视频投稿页面交互逻辑 2019-08-29 11:33:29 +08:00
219270b10d 新增视频投稿、上传视频页面
新增阿里云上传框架
完成部分上传相关逻辑
2019-08-28 19:41:15 +08:00
b070998a73 修复激活数据的上传问题 2019-08-26 17:10:02 +08:00
14e3edf5dd 修复列表滑动闪退问题 2019-08-26 14:27:25 +08:00
bb604b3922 尝试修复后台下载的闪退问题 2019-08-26 11:33:26 +08:00
f43f8e9fb1 修复在5.0以下设备的分dex问题 2019-08-23 18:27:13 +08:00
9c4c5badcd Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-08-22 14:42:00 +08:00
e511d48667 消息中心支持删除操作 2019-08-22 14:41:34 +08:00
8f6ddfef06 修复可能的后台下载闪退问题 2019-08-21 18:08:39 +08:00
2b9e0b167e 未读消息提示改为显示实际数值 2019-08-21 11:46:37 +08:00
cb874dc77a 新增首页社区引导提示以及修改一些重构遗留的BUG 2019-08-21 10:04:24 +08:00
b561cbc8f7 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-08-20 16:33:38 +08:00
f252e004b2 重构首页问答 2019-08-20 16:32:40 +08:00
177c027bf7 在用户选择上传头像前添加存储权限检查 2019-08-19 18:25:43 +08:00
cc386bfe48 回答详情点击问题标题/摘要跳转至问题详情 2019-08-16 17:49:06 +08:00
1254dd7209 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-08-16 17:29:12 +08:00
3054ad8471 首页问答增加一些动画交互 2019-08-16 17:28:54 +08:00
a3cfa69174 移除旧版本分类页面无用代码 2019-08-16 15:23:36 +08:00
82b32da523 删除快传功能残留资源文件 2019-08-16 15:20:54 +08:00
91a1ffe113 完成游戏详情页问题反馈整体优化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/606 2019-08-15 16:59:48 +08:00
d3b6b81e64 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-08-15 14:17:13 +08:00
a2b61a8447 增加问题邀请禁言 2019-08-15 14:17:01 +08:00
cd6c9ca460 修复动态获取权限时可能出现的闪退问题 2019-08-15 09:27:32 +08:00
49a189d19f Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-08-14 18:21:18 +08:00
d972b94ce8 我的游戏-已安装列表移到下载管理 2019-08-14 18:21:07 +08:00
0a552fd378 完成问答社区前端优化汇总(14) https://gitlab.ghzs.com/pm/halo-app-issues/issues/609 2019-08-14 18:08:15 +08:00
3538a629cb 问答社区前端优化汇总(2.3.4.5.6.7.8.10) https://gitlab.ghzs.com/pm/halo-app-issues/issues/609 2019-08-14 16:06:29 +08:00
ef1652c4f4 光环助手V3.7.0-游戏评分&评分回复优化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/607 2019-08-13 15:27:33 +08:00
9d5250294c 游戏插件化/更新,过滤同包名,只显示7天下载最高的一个 2019-08-12 17:16:25 +08:00
8e2aab5dbe Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2019-08-12 15:53:01 +08:00
75d6267f68 相关页面ToolBar增加Download Menu
下载管理游戏下载为空且更新不为空,则直接定位到游戏更新Tab
2019-08-12 15:52:48 +08:00
63bbee19a4 更新 TalkingData SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/602 2019-08-09 17:39:35 +08:00
67f78c2f95 版本号升级到 3.7.0 2019-08-09 17:38:22 +08:00
f558954d22 移除快传相关代码 2019-08-09 14:43:43 +08:00
896 changed files with 38665 additions and 21585 deletions

View File

@ -90,6 +90,8 @@ android {
buildConfigField "String", "EXPOSURE_REPO", "\"test\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
multiDexKeepProguard file("tinker_multidexkeep.pro")
}
release {
debuggable false
@ -100,6 +102,8 @@ android {
buildConfigField "String", "EXPOSURE_REPO", "\"exposure\""
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
multiDexKeepProguard file("tinker_multidexkeep.pro")
}
}
@ -193,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}"
@ -235,10 +240,10 @@ dependencies {
// bugly with tinker support
implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
implementation "pub.devrel:easypermissions:${easypermissions}"
implementation 'com.google.android:flexbox:1.1.0'
implementation "pub.devrel:easypermissions:${easypermissions}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.contrarywind:Android-PickerView:4.1.3'
@ -251,9 +256,14 @@ dependencies {
implementation "top.zibin:Luban:${luban}"
implementation "com.squareup.picasso:picasso:${picasso}"
// for video streaming
implementation "cn.jzvd:jiaozivideoplayer:${jiaoziVideoView}"
implementation "com.danikula:videocache:${videoCache}"
implementation "com.shuyu:gsyVideoPlayer-java:$gsyVideo"
implementation "com.shuyu:gsyVideoPlayer-armv7a:$gsyVideo"
implementation "com.shuyu:gsyVideoPlayer-x86:$gsyVideo"
implementation "com.github.wendux:DSBridge-Android:$dsBridge"
implementation "android.arch.work:work-runtime:${workManager}"
@ -266,6 +276,13 @@ dependencies {
implementation "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.3.1"
implementation 'com.walkud.rom.checker:RomChecker:1.0.0'
debugImplementation "com.github.nichbar.chucker:library:$chucker"
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
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.

Binary file not shown.

View File

@ -225,4 +225,19 @@
-keep class com.qq.gdt.action.** {*;}
### AndroidX
-keep class androidx.core.app.CoreComponentFactory { *; }
-keep class androidx.core.app.CoreComponentFactory { *; }
#阿里云上传
-keep class com.alibaba.sdk.android.oss.** { *; }
-dontwarn okio.**
-dontwarn org.apache.commons.codec.binary.**
#视频相关
-keep class com.shuyu.gsyvideoplayer.video.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.video.**
-keep class com.shuyu.gsyvideoplayer.video.base.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.video.base.**
-keep class com.shuyu.gsyvideoplayer.utils.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.utils.**
-keep class tv.danmaku.ijk.** { *; }
-dontwarn tv.danmaku.ijk.**

View File

@ -1,504 +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,
com.shuyu.gsyvideoplayer.lib,
com.shuyu.gsyvideoplayer.armv7a,
com.shuyu.gsyvideoplayer.x86,
com.shuyu.gsy.base,
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"
tools:targetApi = "n" >
android:name="com.halo.assistant.TinkerApp"
android:allowBackup="true"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:largeHeap="true"
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.ShareGhWfifActivity"
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.kuaichuan.view.KcSelectGameActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.ChooseReceiverActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.ReceiverWaitingActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.FileSenderActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.FileReceiverActivity"
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" />
<activity
android:name = "com.gh.gamecenter.KaiFuActivity"
android:screenOrientation = "portrait" />
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.kaifu.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.kaifu.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.PersonalHomeActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.CollectionActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.answer.PersonalAnswerActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.question.PersonalQuestionActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.UserInfoEditActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name = "com.gh.gamecenter.qa.article.edit.ArticleEditActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.search.AskSearchActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.MyArticleActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.draft.ArticleDraftActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.article.detail.ArticleDetailActivity"
android:screenOrientation = "portrait" />
android:name=".qa.answer.fold.AnswerFoldActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateVisible" />
android:name="com.gh.gamecenter.ConcernInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryDetailActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.InfoActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.questions.edit.manager.HistoryActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageKeFuActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.select.CommunitiesSelectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.GameActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.subject.CommunitySubjectActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.MessageVoteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation = "portrait" />
android:name=".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.FileShareActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.myqa.MyAskActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.column.order.AskTabOrderActivity"
android:screenOrientation="portrait" />
<activity
android:name = "com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity"
android:screenOrientation = "portrait" />
android:name="com.gh.gamecenter.qa.questions.edit.QuestionEditActivity"
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" />
android:name="com.gh.gamecenter.servers.add.AddKaiFuActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<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.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" />
<activity
android:name="com.gh.gamecenter.video.upload.view.UploadVideoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.editor.VideoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.mygame.PlayedGameActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.servers.GameServersActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.game.upload.GameSubmissionActivity"
android:screenOrientation="portrait" />
<activity
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.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>

View File

@ -1,69 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<title>光环助手</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
body {
font: 100%/1.0 'Microsoft YaHei','Helvetica Neue',Helvetica,Arial,sans-serif;
background-color: #fff;
margin: 0;
padding: 0;
}
header {
}
article {
width:100%;
max-width:720px;
clear: both;
margin: 0 auto;
margin-top: 20%;
text-align: center;
margin-bottom:20%;
}
.title{margin-top: 4%;font-size:1.7em;color:#191919;text-align:center;}
.info{margin-top: 18%;font-size:1.0em;color:#191919;line-height:1.3em;}
.download {text-align: center;}
.download a{font-size:1.8em;padding:0.2em; text-align:center;color:#ffffff;margin: 0 auto;width:56%;background-color:#2999f9;border-radius:8px; text-decoration:none;display:block;line-height:1.8em;}
@media only screen and (min-width: 1080px) {
article {
width:100%;
max-width:720px;
clear: both;
margin: 0 auto;
margin-top: 5%;
text-align: center;
margin-bottom:20%;
}
}
</style>
</head>
<body>
<header>
</header>
<article>
<img src="http://192.168.43.1:3100/image/gh_icon.png" width="28%">
<p class="title">光环助手</p>
<br class="info">乐于分享的人是最帅的^_^ </p>
<div class="download">
<a href="http://192.168.43.1:3100/download/ghzs.apk">免流量下载</a>
</div>
<p class="title"><font color="#9A9A9A" size="3em">仅限安卓系统 </font></p>
</article>
</body>
</html>

View File

@ -4,12 +4,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body>
<div id="editor" contenteditable="false"></div>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="video.min.js"></script>
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>

View File

@ -229,7 +229,7 @@ RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
var img = imgs[i];
var imageClassName = img.className;
// console.log(imageClassName)
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("?") > 0) continue;
// console.log(i)
var tbImg
@ -268,7 +268,7 @@ RE.replaceAllDfImage = function(imgRuleFlag, gifRuleFlag) {
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
i--;
@ -294,7 +294,7 @@ RE.hideShowBigPic = function() {
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf(",thumbnail") > 0 && img.src.indexOf(".gif") == -1) {
j++;
}
@ -305,7 +305,7 @@ RE.hideShowBigPic = function() {
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
break;
@ -319,7 +319,7 @@ RE.replaceDfImageByUrl = function(imgUrl, imgRuleFlag, gifRuleFlag) {
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link" || img.className == "poster") continue;
if (img.src.indexOf(imgUrl) != -1) {
img.style.cssText = "max-width: 100%; display:block; margin:8px auto; height: auto;"
if(img.src.indexOf(".gif") > 0) {
@ -337,7 +337,7 @@ RE.ImageClickListener = function() {
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link") continue;
if (imageClassName == "image-link"|| img.className == "poster") continue;
window.imagelistener.imageArr(img.src);
img.onclick = function() {
window.imagelistener.imageClick(this.src);

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,13 @@
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;
@ -18,12 +19,14 @@ import com.gh.common.util.PackageUtils;
import com.gh.common.util.RunningUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.StringUtils;
import com.gh.common.util.TeaHelper;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.LoginActivity;
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;
@ -31,12 +34,9 @@ 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 butterknife.ButterKnife;
@ -44,17 +44,29 @@ 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) {
@ -83,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);
@ -121,26 +117,26 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
super.onDestroy();
}
@Override
protected boolean onNavigationIconClicked() {
onBackPressed();
return true;
}
public void toast(String msg) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
Utils.toast(this, msg);
Utils.toast(this, msg);
}
public void toast(int msg) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
toast(getString(msg));
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 {
@ -150,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 {
@ -179,34 +173,35 @@ 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);
}
}
}
@Override
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);
}
@ -221,7 +216,27 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
}
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 当前页面名称
* @return 完整的链式入口名称
*/
public static String mergeEntranceAndPath(String entrance, String path) {
if (TextUtils.isEmpty(entrance) && TextUtils.isEmpty(path)) return "";
if (TextUtils.isEmpty(entrance) && !TextUtils.isEmpty(path)) {
@ -232,4 +247,5 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
}
return StringUtils.buildString(entrance, "+(", path, ")");
}
}

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

@ -10,12 +10,15 @@ import android.text.TextUtils
import android.view.View
import android.webkit.JavascriptInterface
import butterknife.OnClick
import com.gh.common.util.DialogUtils
import com.gh.common.view.RichEditor
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.MyVideoEntity
import com.gh.gamecenter.qa.editor.GameActivity
import com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity
import com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity
import com.gh.gamecenter.qa.editor.VideoActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.qa.entity.EditorInsertEntity
@ -24,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)
@ -49,6 +52,7 @@ abstract class BaseRichEditorActivity : BaseActivity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
DialogUtils.fixWebViewKeyboardNotWorking(this)
if (resultCode != Activity.RESULT_OK) return
var insertData: EditorInsertEntity? = null
when (requestCode) {
@ -64,6 +68,11 @@ abstract class BaseRichEditorActivity : BaseActivity() {
val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
if (game != null) insertData = EditorInsertEntity.transform(game)
}
INSERT_VIDEO_CODE -> {
val video = data?.getParcelableExtra<MyVideoEntity>(MyVideoEntity::class.java.simpleName)
if (video != null) mRichEditor.insertCustomVideo(video)
return
}
}
mRichEditor.insertCustomStyleLink(insertData)
@ -84,7 +93,7 @@ abstract class BaseRichEditorActivity : BaseActivity() {
R.id.editor_paragraph_h1, R.id.editor_paragraph_h2, R.id.editor_paragraph_h3,
R.id.editor_paragraph_h4, R.id.editor_font_container, R.id.editor_paragraph_container,
R.id.editor_paragraph_quote, R.id.editor_link_answer, R.id.editor_link_article,
R.id.editor_link_game)
R.id.editor_link_game, R.id.editor_link_video)
fun onRichClick(view: View) {
when (view.id) {
R.id.editor_font -> {
@ -173,7 +182,10 @@ abstract class BaseRichEditorActivity : BaseActivity() {
startActivityForResult(InsertArticleWrapperActivity.getIntent(this), INSERT_ARTICLE_CODE)
}
R.id.editor_link_game -> {
startActivityForResult(GameActivity.getIntent(this), INSERT_GAME_CODE)
startActivityForResult(GameActivity.getIntent(this, "插入游戏"), INSERT_GAME_CODE)
}
R.id.editor_link_video -> {
startActivityForResult(VideoActivity.getIntent(this), INSERT_VIDEO_CODE)
}
}
}
@ -232,5 +244,6 @@ abstract class BaseRichEditorActivity : BaseActivity() {
const val INSERT_ANSWER_CODE = 411
const val INSERT_ARTICLE_CODE = 412
const val INSERT_GAME_CODE = 413
const val INSERT_VIDEO_CODE = 414
}
}

View File

@ -1,154 +0,0 @@
package com.gh.base;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.normal.ToolbarController;
import com.lightgame.BaseAppCompatActivity;
import com.lightgame.OnTitleClickListener;
import java.util.List;
/**
* Created by csheng on 15-10-12.
*/
public abstract class BaseToolBarActivity extends BaseAppCompatActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
private Toolbar mToolbar;
private TextView mTitleTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initToolbar();
}
private void initToolbar() {
mToolbar = findViewById(R.id.normal_toolbar);
mTitleTv = findViewById(R.id.normal_title);
if (mToolbar != null) {
// setSupportActionBar(mToolbar); // 替换actionBar后 toolBar无法控制
mToolbar.setNavigationIcon(provideNavigationIcon());
mToolbar.setNavigationOnClickListener(view -> onBackPressed());
mTitleTv.setOnClickListener(view -> {
final List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
for (Fragment fragment : fragmentList) {
if (fragment instanceof OnTitleClickListener) {
((OnTitleClickListener) fragment).onTitleClick();
}
}
});
}
}
@DrawableRes
public int provideNavigationIcon() {
return R.drawable.ic_bar_back; // default navigation icon
}
@Override
public void setNavigationTitle(String title) {
if (mTitleTv != null) mTitleTv.setText(title);
}
@Override
public void setNavigationTitle(@StringRes int res) {
setNavigationTitle(getString(res));
}
/**
* 重写此方法以将标题靠左显示
*/
public boolean showToolbarAtLeft() {
return false;
}
@Override
public void setToolbarMenu(int res) {
if (mToolbar == null) return;
mToolbar.inflateMenu(res);
mToolbar.setOnMenuItemClickListener(this);
Menu menu = mToolbar.getMenu();
for (int i = 0; i < menu.size(); i++) {
MenuItem menuItem = menu.getItem(i);
// menu设置actionLayout后无法捕捉点击事件以icon为tag如果icon is null 手动设置menuItem点击事件
if (menuItem != null && menuItem.getIcon() == null) {
if (menuItem.getActionView() != null) {
menuItem.getActionView().setOnClickListener((v) -> this.onMenuItemClick(menuItem));
}
}
}
// 限制标题实际宽度 防止标题挡住toolbar menu按钮
if (menu.size() > 2 && mTitleTv != null) {
ViewGroup.LayoutParams layoutParams = mTitleTv.getLayoutParams();
if (layoutParams instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layoutParams;
if (showToolbarAtLeft()) {
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
params.setMargins(DisplayUtils.dip2px(55), 0, DisplayUtils.dip2px(48 * menu.size()), 0);
} else {
params.setMargins(DisplayUtils.dip2px(90), 0, DisplayUtils.dip2px(90), 0);
}
mTitleTv.setLayoutParams(params);
}
} else {
if (showToolbarAtLeft()) {
ViewGroup.LayoutParams layoutParams = mTitleTv.getLayoutParams();
if (layoutParams instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layoutParams;
params.addRule(RelativeLayout.CENTER_VERTICAL);
params.setMargins(DisplayUtils.dip2px(55), 0, DisplayUtils.dip2px(48 * menu.size()), 0);
mTitleTv.setLayoutParams(params);
}
}
}
}
@Override
public MenuItem getMenuItem(int res) {
if (mToolbar == null) return null; //后续页面做好判断
return mToolbar.getMenu().findItem(res);
}
public void clearMenu() {
if (mToolbar != null) {
mToolbar.getMenu().clear();
}
}
public Menu getMenu() {
return mToolbar.getMenu();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
return onNavigationIconClicked();
}
return super.onOptionsItemSelected(item);
}
protected abstract boolean onNavigationIconClicked();
}

View File

@ -1,55 +0,0 @@
package com.gh.base;
import android.content.Context;
import android.os.Bundle;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.GameDetailActivity;
import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.subject.SubjectActivity;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;
import org.json.JSONException;
import org.json.JSONObject;
public class GHUmengNotificationClickHandler extends UmengNotificationClickHandler {
@Override
public void launchApp(Context context, UMessage uMessage) {
// super.launchApp(context, uMessage);
try {
String content = uMessage.extra.get(EntranceUtils.KEY_DATA);
JSONObject response = new JSONObject(content);
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG);
String type = response.getString(EntranceUtils.KEY_TYPE);
String target = response.getString(EntranceUtils.KEY_TARGET);
switch (type) {
case EntranceUtils.HOST_ARTICLE:
bundle.putString(EntranceUtils.KEY_TO, NewsDetailActivity.class.getSimpleName());
bundle.putString(EntranceUtils.KEY_NEWSID, target);
break;
case EntranceUtils.HOST_GAME:
bundle.putString(EntranceUtils.KEY_TO, GameDetailActivity.class.getSimpleName());
bundle.putString(EntranceUtils.KEY_GAMEID, target);
break;
case EntranceUtils.HOST_COLUMN:
bundle.putString(EntranceUtils.KEY_TO, SubjectActivity.class.getName());
bundle.putString(EntranceUtils.KEY_ID, target);
break;
case EntranceUtils.HOST_WEB:
bundle.putString(EntranceUtils.KEY_TO, WebActivity.class.getSimpleName());
bundle.putString(EntranceUtils.KEY_URL, target);
break;
}
EntranceUtils.jumpActivity(context, bundle);
} catch (JSONException e) {
e.printStackTrace();
}
}
}

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

@ -0,0 +1,245 @@
package com.gh.base;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.MtaHelper;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
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.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;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
/**
* 需要用到工具栏的页面使用
* <p>
* 特殊页面请参考{@link BaseActivity}
*/
public abstract class ToolBarActivity extends BaseActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
@Nullable
private PackageViewModel mPackageViewModel;
protected Toolbar mToolbar;
protected TextView mTitleTv;
@Nullable
private TextView mDownloadCountHint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarDarkMode(true, this);
initToolbar();
if (showDownloadMenu()) {
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
mPackageViewModel.getFilterSameUpdateLiveData().observe(this, this::updateDownloadCountHint);
}
}
// 小米沉浸式黑色字体
@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);
if (mToolbar != null) {
// setSupportActionBar(mToolbar); // 替换actionBar后 toolBar无法控制
mToolbar.setNavigationIcon(provideNavigationIcon());
mToolbar.setNavigationOnClickListener(provideNavigationItemClickListener());
if (mTitleTv != null) {
mTitleTv.setOnClickListener(view -> {
final List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
for (Fragment fragment : fragmentList) {
if (fragment instanceof OnTitleClickListener) {
((OnTitleClickListener) fragment).onTitleClick();
}
}
});
}
}
}
@DrawableRes
public int provideNavigationIcon() {
return R.drawable.ic_bar_back; // default navigation icon
}
@Override
public void setNavigationTitle(String title) {
if (mTitleTv != null) mTitleTv.setText(title);
}
@Override
public void setNavigationTitle(@StringRes int res) {
setNavigationTitle(getString(res));
}
/**
* 重写此方法以将标题靠左显示
*/
public boolean showToolbarAtLeft() {
return false;
}
@Override
public void setToolbarMenu(int res) {
if (mToolbar == null) return;
mToolbar.inflateMenu(res);
mToolbar.setOnMenuItemClickListener(this);
if (showDownloadMenu()) {
createDownloadMenu(res);
}
Menu menu = mToolbar.getMenu();
for (int i = 0; i < menu.size(); i++) {
MenuItem menuItem = menu.getItem(i);
// menu设置actionLayout后无法捕捉点击事件以icon为tag如果icon is null 手动设置menuItem点击事件
if (menuItem != null && menuItem.getIcon() == null) {
if (menuItem.getActionView() != null) {
menuItem.getActionView().setOnClickListener((v) -> this.onMenuItemClick(menuItem));
}
}
}
// 限制标题实际宽度 防止标题挡住toolbar menu按钮
if (menu.size() > 2 && mTitleTv != null) {
ViewGroup.LayoutParams layoutParams = mTitleTv.getLayoutParams();
if (layoutParams instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layoutParams;
if (showToolbarAtLeft()) {
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
params.setMargins(DisplayUtils.dip2px(55), 0, DisplayUtils.dip2px(48 * menu.size()), 0);
} else {
params.setMargins(DisplayUtils.dip2px(90), 0, DisplayUtils.dip2px(90), 0);
}
mTitleTv.setLayoutParams(params);
}
} else {
if (showToolbarAtLeft()) {
ViewGroup.LayoutParams layoutParams = mTitleTv.getLayoutParams();
if (layoutParams instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layoutParams;
params.addRule(RelativeLayout.CENTER_VERTICAL);
params.setMargins(DisplayUtils.dip2px(55), 0, DisplayUtils.dip2px(48 * menu.size()), 0);
mTitleTv.setLayoutParams(params);
}
}
}
}
private void createDownloadMenu(int res) {
if (res != R.menu.menu_download) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_download, mToolbar.getMenu());
}
if (mPackageViewModel != null) {
updateDownloadCountHint(mPackageViewModel.getFilterSameUpdateLiveData().getValue());
}
View downloadMenuView = mToolbar.getMenu().findItem(R.id.menu_download).getActionView();
mDownloadCountHint = downloadMenuView.findViewById(R.id.menu_download_count_hint);
}
private void updateDownloadCountHint(List<GameUpdateEntity> updateList) {
if (mDownloadCountHint == null) return;
int count = DownloadManager.getInstance(getApplicationContext()).getDownloadOrUpdateCount(updateList);
if (count != 0) {
mDownloadCountHint.setVisibility(View.VISIBLE);
mDownloadCountHint.setText(String.valueOf(count));
} else {
mDownloadCountHint.setVisibility(View.GONE);
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBDownloadStatus status) {
if (showDownloadMenu() && mPackageViewModel != null) {
updateDownloadCountHint(mPackageViewModel.getFilterSameUpdateLiveData().getValue());
}
}
@Override
public MenuItem getMenuItem(int res) {
if (mToolbar == null) return null; //后续页面做好判断
return mToolbar.getMenu().findItem(res);
}
public void clearMenu() {
if (mToolbar != null) {
mToolbar.getMenu().clear();
}
}
public Menu getMenu() {
return mToolbar.getMenu();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_download) {
MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, mEntrance);
startActivity(intent);
}
return false;
}
protected View.OnClickListener provideNavigationItemClickListener() {
return view -> onBackPressed();
}
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

@ -181,13 +181,11 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
}
public void toast(@StringRes int res) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
toast(getString(res));
toast(getString(res));
}
public void toast(String msg) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
Utils.toast(getContext(), msg);
Utils.toast(getContext(), msg);
}
public void toastLong(@StringRes int msg) {

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

@ -0,0 +1,5 @@
package com.gh.common
object Base64ImageHolder {
var image: String = ""
}

View File

@ -0,0 +1,153 @@
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.*
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(var context: Context) {
@JavascriptInterface
fun isGhzs(msg: Any): String {
return "true"
}
@JavascriptInterface
fun toast(msg: Any) {
Utils.toast(HaloApp.getInstance().application, msg.toString())
}
@JavascriptInterface
fun logMtaEvent(event: Any) {
val mtaEvent = event.toString().toObject() ?: MtaEvent()
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) {
val imageEvent = event.toString().toObject() ?: ImageEvent()
val context = CurrentActivityHolder.getCurrentActivity()
context?.startActivity(ViewImageActivity.getViewImageIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
}
@JavascriptInterface
fun openBase64Image(event: Any) {
val context = CurrentActivityHolder.getCurrentActivity()
Base64ImageHolder.image = event.toString()
context?.startActivity(ViewImageActivity.getBase64ViewImageIntent(context, true))
}
@Keep
internal data class MtaEvent(var name: String = "", var key: String = "", var value: String = "")
@Keep
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
}

View File

@ -0,0 +1,116 @@
package com.gh.common
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.LibaoDetailActivity
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.subject.SubjectActivity
import com.lightgame.utils.Utils
object DefaultWebViewUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
Utils.log("url = " + uri.scheme!!)
val host = uri.host
val path = uri.path
var id = ""
if (!TextUtils.isEmpty(path)) {
id = path!!.substring(1)
}
val intent: Intent
when (host) {
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
"game" -> GameDetailActivity.startGameDetailActivity(context, id, entrance)
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
"libao" -> context.startActivity(LibaoDetailActivity.getIntentById(context, id, entrance))
"qq" -> try {
DirectUtils.directToQqConversation(context, id)
} catch (e: Exception) {
Utils.toast(context, "请检查是否已经安装手机QQ")
e.printStackTrace()
}
"qqqun" -> {
val key = uri.getQueryParameter("key")
if (!DirectUtils.directToQqGroup(context, key)) {
Utils.toast(context, "请检查是否已经安装手机QQ")
}
}
"inurl" -> {
intent = Intent(context, WebActivity::class.java)
intent.putExtra(EntranceUtils.KEY_URL, uri.getQueryParameter("url"))
context.startActivity(intent)
}
"outurl" -> {
intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse(uri.getQueryParameter("url"))
try {
context.startActivity(intent)
} catch (e: Exception) {
Utils.toast(context, "请检查是否已经安装手机浏览器")
e.printStackTrace()
}
}
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
"community" -> {
val community = CommunityEntity()
community.id = id
community.name = uri.getQueryParameter("name")
DirectUtils.directToCommunity(context, community)
}
"answer" -> DirectUtils.directToAnswerDetail(context, id, entrance, "文章链接")
"communities" -> {
// ghzhushou://communities/5a32405b2397ab000f688de3/articles/5c99d262c140b321564f04e3
var communityId = ""
var type = ""
var typeId = ""
val split = id.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (text in split) {
if (TextUtils.isEmpty(communityId)) {
communityId = text
continue
}
if (TextUtils.isEmpty(type)) {
type = text
continue
}
if (TextUtils.isEmpty(typeId)) {
typeId = text
}
}
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接")
}
}
else -> DialogUtils.showLowVersionDialog(context)
}
return true
}
return false
}
}

View File

@ -27,35 +27,36 @@ import org.json.JSONObject
object PushManager {
var deviceToken: String? = ""
var previousAlias: AliasEntity? = null
var application = HaloApp.getInstance().application
private var mPreviousAlias: AliasEntity? = null
private var mApplication = HaloApp.getInstance().application
const val SP_PUSH_ALIAS = "push_alias"
@JvmStatic
fun init(channel: String) {
//初始化友盟推送
UMConfigure.init(application,
UMConfigure.init(mApplication,
Config.UMENG_APPKEY, channel,
UMConfigure.DEVICE_TYPE_PHONE,
Config.UMENG_MESSAGE_SECRET)
// 注册小米、华为和魅族通道
MiPushRegistar.register(application, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
HuaWeiRegister.register(application)
MeizuRegister.register(application, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
HuaWeiRegister.register(mApplication)
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
//友盟推送
val pushAgent = PushAgent.getInstance(application)
val pushAgent = PushAgent.getInstance(mApplication)
pushAgent.onAppStart() // 开启App统计
//注册推送服务每次调用register方法都会回调该接口
registerDevice()
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(application).getString(SP_PUSH_ALIAS, "")
previousAlias = aliasInSp?.toObject()
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
mPreviousAlias = aliasInSp?.toObject()
if (previousAlias == null) {
if (mPreviousAlias == null) {
getAndSetAlias()
}
@ -64,7 +65,7 @@ object PushManager {
}
private fun registerDevice() {
PushAgent.getInstance(application).register(object : IUmengRegisterCallback {
PushAgent.getInstance(mApplication).register(object : IUmengRegisterCallback {
override fun onSuccess(dToken: String) {
//注册成功会返回device token
deviceToken = dToken
@ -100,7 +101,7 @@ object PushManager {
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
RetrofitManager.getInstance(application).api.getAlias(body)
RetrofitManager.getInstance(mApplication).api.getAlias(body)
.subscribeOn(Schedulers.io())
.subscribe(
{ setAlias(it) },
@ -110,11 +111,11 @@ object PushManager {
@JvmStatic
fun setAlias(alias: AliasEntity) {
val pushAgent = PushAgent.getInstance(application)
val pushAgent = PushAgent.getInstance(mApplication)
previousAlias = alias
PreferenceManager.getDefaultSharedPreferences(application).edit {
putString(SP_PUSH_ALIAS, previousAlias?.toJson())
mPreviousAlias = alias
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
putString(SP_PUSH_ALIAS, mPreviousAlias?.toJson())
}
pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->
@ -124,16 +125,16 @@ object PushManager {
@JvmStatic
fun deleteAlias() {
val pushAgent = PushAgent.getInstance(application)
val pushAgent = PushAgent.getInstance(mApplication)
previousAlias?.let {
mPreviousAlias?.let {
pushAgent.deleteAlias(it.alias, it.aliasType) { b, s ->
Utils.log("删除别名 $b + $s")
}
}
PreferenceManager.getDefaultSharedPreferences(application).edit {
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
putString(SP_PUSH_ALIAS, "")
}
previousAlias = null
mPreviousAlias = null
}
}

View File

@ -3,9 +3,10 @@ package com.gh.common.constant;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.SPUtils;
@ -54,6 +55,7 @@ public class Config {
public static final String FIX_ARTICLE_KEY = "isFixArticle";
public static final String FIX_COMMUNITY_KEY = "isFixCommunity";
public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个
public static boolean isShow() {
if (getPreferences().getBoolean(FIX_DOWNLOAD_KEY, false)) return true;

View File

@ -17,12 +17,24 @@ public class Constants {
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}$";
public static final String REGEX_ACCOUNT = "^[a-zA-Z_]\\w{5,17}$";
@ -31,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;
@ -50,4 +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; // 新闻头部布局
@ -28,6 +29,9 @@ public class ItemViewType {
public static final int ITEM_EMPTY = 20;
public static final int ASK_CONCERN = 21; // 问答精选 关注
public static final int RATING_ITEM = 22; // 问答精选 关注
public static final int IMAGE_SLIDE_ITEM = 23;
public static final int VERTICAL_SLIDE_ITEM = 24;
public static final int COLUMN_COLLECTION = 25;
/**
* 普通列表

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,6 +13,8 @@ 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;
@ -16,8 +22,11 @@ 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;
@ -28,10 +37,12 @@ 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;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
@ -40,10 +51,12 @@ import com.gh.gamecenter.databinding.KaifuAddItemBinding;
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.KaiFuCalendarEntity;
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;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
@ -76,7 +89,7 @@ public class BindingAdapters {
}
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
public static void addDetailKaiFuView(LinearLayout view, List<KaiFuCalendarEntity> list
public static void addDetailKaiFuView(LinearLayout view, List<ServerCalendarEntity> list
, OnViewClickListener listener, Boolean isReadyPatch) {
if (list == null) return;
view.removeAllViews();
@ -88,7 +101,7 @@ public class BindingAdapters {
if (i == 0) {
binding.setIsTitle(true);
} else {
KaiFuCalendarEntity serverEntity = list.get(i - 1);
ServerCalendarEntity serverEntity = list.get(i - 1);
binding.setEntity(serverEntity);
binding.getRoot().setOnClickListener(v -> {
listener.onClick(v, isReadyPatch != null && isReadyPatch ? serverEntity : null);
@ -117,7 +130,7 @@ public class BindingAdapters {
}
@BindingAdapter({"addKaiFuView", "clickListener"})
public static void addKaiFuView(LinearLayout view, List<KaiFuCalendarEntity> list, OnViewClickListener listener) {
public static void addKaiFuView(LinearLayout view, List<ServerCalendarEntity> list, OnViewClickListener listener) {
if (list == null) return;
view.removeAllViews();
view.addView(LayoutInflater.from(view.getContext()).inflate(R.layout.kaifu_add_item_title, null));
@ -306,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())
@ -318,9 +337,102 @@ 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()) {
progressBar.setText("暂无下载");
if (gameEntity.getApk().isEmpty() || gameEntity.getDownloadOffStatus() != null) {
String offStatus = gameEntity.getDownloadOffStatus();
if (offStatus != null && "dialog".equals(offStatus)) {
progressBar.setText("查看");
} else {
progressBar.setText("暂无");
}
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
} else {
String status = GameUtils.getDownloadBtnText(progressBar.getContext(), gameEntity, PluginLocation.only_game);
@ -375,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("更新")) {
@ -442,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);
@ -450,7 +531,8 @@ public class BindingAdapters {
apkEntity,
gameEntity,
method,
StringUtils.buildString("(我的光环:我的游戏)"), "我的光环-我的游戏:" + gameEntity.getName(),
entrance,
location + gameEntity.getName(),
isSubscribe,
downloadExposureEvent);
@ -487,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);
}
}
@ -505,4 +585,59 @@ public class BindingAdapters {
}
}
@BindingAdapter({"setCommunityImage", "setCommunityVideoImage"})
public static void setCommunityImage(SimpleDraweeView imageView, List<String> images, List<CommunityVideoEntity> videos) {
if (videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
ImageUtils.display(imageView, videoEntity.getPoster());
imageView.setVisibility(View.VISIBLE);
} else if (images.size() > 0) {
imageView.setVisibility(View.VISIBLE);
ImageUtils.display(imageView, images.get(0));
} else {
imageView.setVisibility(View.GONE);
}
}
@BindingAdapter({"setCommunityVideoDuration"})
public static void setCommunityVideoDuration(TextView mVideoDuration, List<CommunityVideoEntity> videos) {
if (videos != null && videos.size() > 0) {
CommunityVideoEntity videoEntity = videos.get(0);
mVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_80, 999F));
mVideoDuration.setText(videoEntity.getDuration());
mVideoDuration.setVisibility(View.VISIBLE);
} else {
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

@ -0,0 +1,62 @@
package com.gh.common.dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import com.gh.common.util.MtaHelper
import com.lightgame.dialog.BaseDialogFragment
import java.util.concurrent.atomic.AtomicBoolean
/**
* 对 dialog 操作进行 MTA 事件记录的 dialog fragment
*/
abstract class BaseTrackableDialogFragment : BaseDialogFragment() {
abstract fun getEvent(): String
abstract fun getKey(): String
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
private val mIsCanceledByClickOutsideOfDialog = AtomicBoolean(true)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (getEvent().isEmpty()) {
throw IllegalStateException("需要提供非空的 Event 来供 MTA 进行事件记录")
}
if (getKey().isEmpty()) {
throw IllegalStateException("需要提供非空的 Key 来供 MTA 进行事件记录")
}
onEvent("出现弹窗")
dialog?.setCanceledOnTouchOutside(true)
dialog?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
mIsCanceledByClickOutsideOfDialog.set(false)
onEvent("点击返回")
}
false
}
}
fun onEvent(value: String) {
if (trackWithBasicDeviceInfo()) {
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), value)
} else {
MtaHelper.onEvent(getEvent(), getKey(), value)
}
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
if (mIsCanceledByClickOutsideOfDialog.get()) {
onEvent("点击空白")
}
}
open fun trackWithBasicDeviceInfo() = false
}

View File

@ -0,0 +1,70 @@
package com.gh.common.dialog
import android.graphics.Paint
import android.os.Bundle
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import com.gh.common.util.DirectUtils
import com.gh.common.util.DisplayUtils
import com.gh.common.util.MtaHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import kotlinx.android.synthetic.main.dialog_game_off_service.*
// 游戏关闭下载弹窗
class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
private var mDialog: GameEntity.Dialog? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_game_off_service, null)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mDialog?.run {
titleTv.text = title
contentTv.text = HtmlCompat.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)
for (site in sites) {
val siteTv = TextView(context)
siteTv.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply {
topMargin = DisplayUtils.dip2px(12f)
}
siteTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
siteTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme))
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {
MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismiss()
}
container.addView(siteTv)
}
}
}
override fun getEvent(): String {
return "游戏下载状态按钮"
}
override fun getKey(): String {
return "查看详情弹窗"
}
companion object {
@JvmStatic
fun getInstance(dialog: GameEntity.Dialog) = GameOffServiceDialogFragment().apply {
mDialog = dialog
}
}
}

View File

@ -0,0 +1,90 @@
package com.gh.common.dialog
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.common.util.DisplayUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.PermissionHelper
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.NotificationHint
import kotlinx.android.synthetic.main.dialog_notification_hint.*
// 通知权限弹窗
class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
private var mNotificationHint: NotificationHint? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_notification_hint, null)
}
@Suppress("DEPRECATION")
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
titleTv.text = mNotificationHint?.title
contentContainer.removeAllViews()
for (item in mNotificationHint?.content!!) {
val tv = TextView(context)
tv.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
topMargin = if (contentContainer.childCount == 0) 0 else DisplayUtils.dip2px(12f)
}
tv.text = item
tv.setTextColor(Color.parseColor("#1383EB"))
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
contentContainer.addView(tv)
}
activateTv.setOnClickListener {
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
dismiss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//这种方案适用于 API 26, 即8.0含8.0)以上可以用
val intent = Intent()
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
startActivity(intent)
} else {
PermissionHelper.toPermissionSetting(requireActivity())
}
}
laterTv.setOnClickListener {
dismiss()
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击以后再说")
}
dialog?.setCanceledOnTouchOutside(true)
}
override fun getEvent(): String {
return "推送引导弹窗"
}
override fun getKey(): String {
return "引导弹窗"
}
override fun trackWithBasicDeviceInfo() = true
companion object {
@JvmStatic
fun getInstance(hint: NotificationHint) = NotificationHintDialogFragment().apply {
mNotificationHint = hint
}
}
}

View File

@ -22,12 +22,13 @@ import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.dialog.BaseDialogFragment
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
class ReserveDialogFragment : BaseDialogFragment() {
// 预约弹窗
class ReserveDialogFragment : BaseTrackableDialogFragment() {
@BindView(R.id.reserve_hint_tv)
lateinit var reserveHintTv: TextView
@ -61,6 +62,14 @@ class ReserveDialogFragment : BaseDialogFragment() {
return inflater.inflate(R.layout.dialog_reserve_game, null)
}
override fun getEvent(): String {
return "预约游戏"
}
override fun getKey(): String {
return "预约功能操作"
}
@Suppress("DEPRECATION")
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -75,14 +84,14 @@ class ReserveDialogFragment : BaseDialogFragment() {
mViewModel.reservation.observeNonNull(this) {
if (it.success) {
showSuccessDialog(it.withMobile)
showSuccessDialog(it.withMobile, it.boundWechat)
mSuccessCallback?.onSuccess()
}
}
dialog.setCanceledOnTouchOutside(true)
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
@ -90,13 +99,14 @@ class ReserveDialogFragment : BaseDialogFragment() {
val reservation = Config.getSettings()?.appointment
val dialogConfig = if (withMobile) reservation?.withMobile else reservation?.withoutMobile
reserveCompletedContentTv.text = Html.fromHtml(dialogConfig?.htmlContent)
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
customizableBtn.setOnClickListener {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
DirectUtils.directToLinkPage(
requireContext(),
dialogConfig!!.toLinkEntity(),
@ -114,6 +124,7 @@ class ReserveDialogFragment : BaseDialogFragment() {
fun onClick(view: View) {
when (view.id) {
R.id.reserve_without_mobile_btn -> {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击无手机号预约")
mViewModel.reserve(gameId = mGameId, gameName = mGameName)
}
@ -124,10 +135,12 @@ class ReserveDialogFragment : BaseDialogFragment() {
return
}
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
mViewModel.reserve(gameId = mGameId, gameName = mGameName, mobile = mobile)
}
R.id.close_btn -> {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
dismissAllowingStateLoss()
}
}
@ -164,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)
@ -176,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

@ -0,0 +1,47 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.KeyEvent
import com.gh.common.util.MtaHelper
import java.util.concurrent.atomic.AtomicBoolean
open class TrackableDialog(context: Context,
themeResId: Int,
private var mEvent: String,
private var mKey: String,
private var mCancelValue: String? = null,
private var mKeyBackValue: String? = null,
private var mLogShowEvent: Boolean = true)
: Dialog(context, themeResId) {
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
private val mIsCanceledByClickOutsideOfDialog = AtomicBoolean(true)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setOnCancelListener {
if (mIsCanceledByClickOutsideOfDialog.get()) {
MtaHelper.onEvent(mEvent, mKey, mCancelValue ?: "点击空白")
}
}
setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
mIsCanceledByClickOutsideOfDialog.set(false)
MtaHelper.onEvent(mEvent, mKey, mKeyBackValue ?: "点击返回")
}
false
}
}
override fun show() {
super.show()
if (mLogShowEvent) {
MtaHelper.onEvent(mEvent, mKey, "出现弹窗")
}
}
}

View File

@ -17,15 +17,15 @@ import com.gh.gamecenter.room.dao.GameDao
import com.gh.gamecenter.room.dao.NewsHistoryDao
import com.halo.assistant.HaloApp
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class], version = 3, exportSchema = false)
@TypeConverters(*[
CountConverter::class,
CommunityConverter::class,
TimeConverter::class,
AnswerUserConverter::class,
ThumbnailConverter::class,
TagStyleListConverter::class,
StringArrayListConverter::class])
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class], version = 4, exportSchema = false)
@TypeConverters(CountConverter::class,
CommunityConverter::class,
TimeConverter::class,
AnswerUserConverter::class,
ThumbnailConverter::class,
TagStyleListConverter::class,
StringArrayListConverter::class,
CommunityVideoConverter::class)
abstract class HistoryDatabase : RoomDatabase() {
@ -42,9 +42,17 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_3_4: Migration = object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE AnswerEntity add videos TEXT NOT NULL DEFAULT ''")
database.execSQL("Alter TABLE ArticleEntity add videos TEXT NOT NULL DEFAULT ''")
}
}
val instance by lazy {
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.build()
}
}

View File

@ -3,6 +3,7 @@ package com.gh.common.history
import com.gh.common.runOnIoThread
import com.gh.common.util.clearHtmlFormatCompletely
import com.gh.common.util.removeInsertedContent
import com.gh.common.util.removeVideoContent
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.HistoryGameEntity
import com.gh.gamecenter.entity.NewsEntity
@ -78,7 +79,11 @@ object HistoryHelper {
val articleEntity = ArticleEntity()
articleEntity.id = articleDetailEntity.id
articleEntity.brief = articleDetailEntity.content.removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex()," ")
articleEntity.brief = articleDetailEntity.content.
removeVideoContent().
removeInsertedContent().
clearHtmlFormatCompletely().
replace(" +".toRegex()," ")
articleEntity.count = articleDetailEntity.count
articleEntity.community = articleDetailEntity.community
articleEntity.time = articleDetailEntity.time
@ -99,7 +104,11 @@ object HistoryHelper {
answerEntity.vote = answerDetailEntity.vote
answerEntity.user = answerDetailEntity.user
answerEntity.orderTag = System.currentTimeMillis()
answerEntity.brief = answerDetailEntity.content.removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex(), " ")
answerEntity.brief = answerDetailEntity.content.
removeVideoContent().
removeInsertedContent().
clearHtmlFormatCompletely().
replace(" +".toRegex(), " ")
answerEntity.time = answerDetailEntity.time
return answerEntity

View File

@ -22,7 +22,7 @@ object ActivationHelper {
@JvmStatic
fun sendActivationInfo() {
// 能获取到 IMEI 并且之前没发送过激活信息才发
if (mHasSentActivatedInfo
if (!mHasSentActivatedInfo
&& Util_System_Phone_State.canGetImei(HaloApp.getInstance().application)) {
RetrofitManager.getInstance(HaloApp.getInstance().application)
.api.postActivationInfo()

View File

@ -1,9 +1,16 @@
package com.gh.common.util;
import android.text.TextUtils;
import androidx.annotation.Nullable;
public class ClassUtils {
@Nullable
public static Class<?> forName(String name) {
if (TextUtils.isEmpty(name)) return null;
if ("NewsActivity".equals(name)) {
name = "NewsDetailActivity";
} else if ("GameDetailsActivity".equals(name)) {

View File

@ -50,16 +50,30 @@ object CommentHelper {
listener = listener)
}
@JvmStatic
fun showVideoCommentOptions(context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
videoId: String,
listener: OnCommentCallBackListener?) {
showCommentOptions(context = context,
commentEntity = commentEntity,
showConversation = showConversation,
videoId = videoId,
listener = listener)
}
private fun showCommentOptions(context: Context,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String? = null,
communityId: String? = null,
answerId: String? = null,
videoId: String? = null,
listener: OnCommentCallBackListener? = null) {
val dialogOptions = ArrayList<String>()
if (commentEntity.me == null || !commentEntity.me?.isAnswerCommented!!) {
if (commentEntity.me == null || !commentEntity.me?.isCommentOwner!!) {
dialogOptions.add("回复")
}
@ -117,8 +131,10 @@ object CommentHelper {
if (answerId != null) {
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
} else {
} else if (articleId != null) {
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
} else {
PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
}
}
}
@ -128,9 +144,12 @@ object CommentHelper {
if (answerId != null) {
context.startActivity(CommentDetailActivity
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
} else {
} else if (articleId != null) {
context.startActivity(CommentDetailActivity
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
} else {
context.startActivity(CommentDetailActivity
.getVideoCommentIntent(context, commentEntity.id, videoId, null))
}
}
}
@ -154,7 +173,7 @@ object CommentHelper {
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.GUEST) {
dialogOptions.add(highlight)
if (me.moderatorPermissions.topAnswerComment > Permissions.REPORTER
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.REPORTER ) {
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.REPORTER) {
canHighlightCommentDirectly = true
}
}
@ -163,7 +182,7 @@ object CommentHelper {
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST) {
dialogOptions.add(hide)
if (me.moderatorPermissions.hideAnswerComment > Permissions.REPORTER
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.REPORTER ) {
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.REPORTER) {
canHideCommentDirectly = true
}
}
@ -187,7 +206,7 @@ object CommentHelper {
}
comment.me?.let {
if (it.isAnswerCommented) {
if (it.isCommentOwner) {
disabledOptions.add(highlight)
}
}
@ -201,7 +220,7 @@ object CommentHelper {
}
comment.me?.let { me ->
if (me.isAnswerCommented) {
if (me.isCommentOwner) {
Utils.toast(context, "不能置顶自己的评论")
return@showListDialog
}

View File

@ -1,10 +1,10 @@
package com.gh.common.util;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Color;
import androidx.core.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
@ -21,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 +39,10 @@ import java.util.Date;
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;
/**
@ -87,7 +97,7 @@ public class CommentUtils {
List<String> dialogType = new ArrayList<>();
if (commentEntity.getMe() == null || !commentEntity.getMe().isCommentOwn()) {
if (commentEntity.getMe() == null || !commentEntity.getMe().isCommentOwner()) {
dialogType.add("回复");
}
@ -259,9 +269,15 @@ public class CommentUtils {
});
}
public static void postVoteToAnswerComment(final Context context, String answerId, String articleId,
String articleCommunityId, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv, final OnVoteListener listener) {
public static void likeComment(final Context context,
String answerId,
String articleId,
String articleCommunityId,
String videoId,
final CommentEntity commentEntity,
final TextView commentLikeCountTv,
final ImageView commentLikeIv,
final OnVoteListener listener) {
String entrance = "回答详情-评论-点赞";
if (TextUtils.isEmpty(articleId)) {
@ -278,7 +294,7 @@ public class CommentUtils {
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
PostCommentUtils.voteAnswerComment(context, answerId, articleId, articleCommunityId, commentEntity.getId(),
PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
@ -289,7 +305,6 @@ public class CommentUtils {
@Override
public void postFailed(Throwable e) {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
@ -330,7 +345,7 @@ public class CommentUtils {
if (entity.getVote() == 0) {
holder.commentLikeCountTv.setVisibility(View.GONE);
} else { // 检查是否已点赞
if (userDataEntity != null && (userDataEntity.isCommentVoted() || userDataEntity.isAnswerCommentVoted())) {
if (userDataEntity != null && (userDataEntity.isCommentVoted())) {
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
holder.commentLikeIv.setImageResource(R.drawable.vote_icon_select);
}
@ -338,10 +353,20 @@ 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.isCommentOwn() && userInfo != null) {
if (entity.getMe() != null && entity.getMe().isAnswerOwn()) {
if (userDataEntity != null && userDataEntity.isCommentOwner() && userInfo != null) {
if (entity.getMe() != null && entity.getMe().isContentOwner()) {
holder.commentUserNameTv.setText(userInfo.getName() + "(作者)");
} else {
holder.commentUserNameTv.setText(userInfo.getName());
@ -353,7 +378,7 @@ public class CommentUtils {
}
ImageUtils.displayIcon(holder.commentUserIconDv, userInfo.getIcon());
} else {
if (entity.getMe() != null && entity.getMe().isAnswerOwn()) {
if (entity.getMe() != null && entity.getMe().isContentOwner()) {
holder.commentUserNameTv.setText(entity.getUser().getName() + "(作者)");
} else {
holder.commentUserNameTv.setText(entity.getUser().getName());
@ -371,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

@ -33,7 +33,11 @@ public class DetailDownloadUtils {
if (viewHolder.gameEntity.isReservable()) {
if (!ReservationRepository.thisGameHasBeenReserved(viewHolder.gameEntity.getId())) {
viewHolder.mDownloadPb.setText("预约《" + viewHolder.gameEntity.getName() + "");
if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》", viewHolder.gameEntity.getName()));
} else {
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》%s", viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
}
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.RESERVABLE);
} else {
viewHolder.mDownloadPb.setText("已预约《" + viewHolder.gameEntity.getName() + "");
@ -42,9 +46,14 @@ public class DetailDownloadUtils {
return;
}
if (viewHolder.gameEntity.getApk().isEmpty()) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "暂无下载" : viewHolder.downloadOffText);
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
if (viewHolder.gameEntity.getApk().isEmpty() || viewHolder.gameEntity.getDownloadOffStatus() != null) {
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "查看详情" : viewHolder.downloadOffText);
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE_WITH_HINT);
} else {
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "暂无下载" : viewHolder.downloadOffText);
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
}
} else {
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game);
switch (status) {

View File

@ -11,7 +11,7 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.gh.gamecenter.kuaichuan.WifiMgr;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Util_System_Phone_State;
import com.tencent.stat.StatConfig;
@ -164,7 +164,7 @@ public class DeviceUtils {
}
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络
return WifiMgr.getInstance(context).getCurrentIpAddress();
return getCurrentIpAddress();
}
} else {
//当前无网络连接,请在设置中打开网络
@ -266,4 +266,21 @@ public class DeviceUtils {
return memInfo.totalMem / (1024 * 1024);
}
// 只能获取WiFi的IpAddress
public static String getCurrentIpAddress() {
String ipAddress;
WifiManager wifiManager = (WifiManager) HaloApp.getInstance().
getApplication().
getApplicationContext().
getSystemService(Context.WIFI_SERVICE);
int address = wifiManager.getDhcpInfo().ipAddress;
ipAddress = ((address & 0xFF)
+ "." + ((address >> 8) & 0xFF)
+ "." + ((address >> 16) & 0xFF)
+ "." + ((address >> 24) & 0xFF));
return ipAddress;
}
}

View File

@ -0,0 +1,93 @@
package com.gh.common.util
import android.app.Dialog
import android.content.Context
import android.view.LayoutInflater
import android.view.Window
import android.widget.TextView
import com.gh.common.dialog.TrackableDialog
import com.gh.common.util.DialogUtils.checkDialogContext
import com.gh.gamecenter.R
object DialogHelper {
/**
* Material Design 风格弹窗
*
* @param context
* @param title 标题
* @param content 内容
* @param positiveText 确认按钮文本
* @param negativeText 取消按钮文本
* @param positiveClickCallback 确认按钮监听
* @param negativeClickCallback 取消按钮监听
* @param trackMtaEvent 是否记录出现、关闭弹窗MTA事件
* @param mtaEvent MTA 的事件名
* @param mtaKey MTA 的事件 Key
*/
fun showDialog(context: Context,
title: String,
content: CharSequence,
positiveText: String,
negativeText: String,
positiveClickCallback: (() -> Unit)? = null,
negativeClickCallback: (() -> Unit)? = null,
trackMtaEvent: Boolean = false,
mtaEvent: String = "",
mtaKey: String = ""): Dialog {
val solidContext = checkDialogContext(context)
val dialog = if (trackMtaEvent) {
TrackableDialog(solidContext, R.style.GhAlertDialog, mtaEvent, mtaKey)
} else {
Dialog(solidContext, R.style.GhAlertDialog)
}
val contentView = LayoutInflater.from(solidContext).inflate(R.layout.dialog_alert, null)
val contentTv = contentView.findViewById<TextView>(R.id.dialog_content)
val titleTv = contentView.findViewById<TextView>(R.id.dialog_title)
val negativeTv = contentView.findViewById<TextView>(R.id.dialog_negative)
val positiveTv = contentView.findViewById<TextView>(R.id.dialog_positive)
contentTv.text = content
titleTv.text = title
negativeTv.text = negativeText
positiveTv.text = positiveText
negativeTv.setOnClickListener {
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击" + negativeText)
negativeClickCallback?.invoke()
dialog.dismiss()
}
positiveTv.setOnClickListener {
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$positiveText")
positiveClickCallback?.invoke()
dialog.dismiss()
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(contentView)
dialog.show()
return dialog
}
/**
* For legacy java invocation
*/
@JvmStatic
fun showDialog(context: Context,
title: String,
content: CharSequence,
positiveText: String,
negativeText: String,
positiveClickCallback: EmptyCallback,
negativeClickCallback: EmptyCallback,
trackMtaEvent: Boolean = false,
mtaEvent: String = "",
mtaKey: String = ""): Dialog {
return showDialog(context, title, content, positiveText, negativeText, { positiveClickCallback.onCallback() }, { negativeClickCallback.onCallback() }, trackMtaEvent, mtaEvent, mtaKey)
}
}

View File

@ -5,11 +5,7 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Handler;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@ -17,37 +13,29 @@ import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import com.gh.common.view.DrawableView;
import com.gh.gamecenter.AboutActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.kuaichuan.WifiMgr;
import com.gh.gamecenter.kuaichuan.view.KcSelectGameActivity;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Utils;
import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
public class DialogUtils {
@ -65,161 +53,6 @@ public class DialogUtils {
return dialog;
}
// 快传成绩单
public static void showKuaiChuanResult(final Activity activity, Handler handler, int requestCode, final String picName) {
HaloApp.remove(KcSelectGameActivity.KEY_FILE_INFO);
List<Map<String, String>> mapList = (List<Map<String, String>>) HaloApp.get("sendData", true);
if (mapList == null || mapList.size() == 0) return;
WifiMgr.getInstance(activity).disconnectCurrentNetwork(); // 断开当前WiFi
int filesCount = mapList.size();
int filesSize = 0;
int sendTime = 0;
View view = View.inflate(activity, R.layout.dialog_kuaichuan, null);
final LinearLayout mShareLl = view.findViewById(R.id.kuaichuan_dialog_ll);
final LinearLayout mShareBottomLl = view.findViewById(R.id.kuaichuan_dialog_share_rl);
LinearLayout shareIconLl = view.findViewById(R.id.kuaichuan_icon_ll);
ImageView qrCode = view.findViewById(R.id.kuaichuan_qrcode);
TextView dateTv = view.findViewById(R.id.kuaichuan_dialog_date);
TextView countTv = view.findViewById(R.id.kuaichuan_send_count);
TextView sizeTv = view.findViewById(R.id.kuaichuan_send_size);
TextView speedTv = view.findViewById(R.id.kuaichuan_send_speed);
TextView timeCount = view.findViewById(R.id.kuaichuan_time_count);
TextView timeTv = view.findViewById(R.id.kuaichuan_time_tv);
TextView sendCountTv = view.findViewById(R.id.dialog_send_tv);
ImageView closeIv = view.findViewById(R.id.kuaichuan_dialog_colse);
final Dialog dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCanceledOnTouchOutside(false);
dialog.setContentView(view);
dialog.show();
Window dialogWindow = dialog.getWindow();
WindowManager m = activity.getWindowManager();
Display d = m.getDefaultDisplay();
if (dialogWindow != null) {
WindowManager.LayoutParams p = dialogWindow.getAttributes();
p.height = (int) (d.getHeight() * 0.82);
p.width = (int) (d.getWidth() * 0.80);
dialogWindow.setAttributes(p);
}
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日", Locale.getDefault());
dateTv.setText(format.format(new Date().getTime()));
for (Map<String, String> map : mapList) {
int size = Integer.parseInt(map.get("apkSize"));
int time = 10;
try {
time = Integer.parseInt(map.get("sendTime"));
} catch (Exception e) {
e.printStackTrace();
}
String apkPath = map.get("apkPath");
filesSize = filesSize + size;
sendTime = sendTime + time;
if (shareIconLl.getChildCount() >= 5) continue;
android.content.pm.PackageManager pm = activity.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(apkPath,
android.content.pm.PackageManager.GET_ACTIVITIES);
if (info != null) {
ApplicationInfo appInfo = info.applicationInfo;
appInfo.sourceDir = apkPath;
appInfo.publicSourceDir = apkPath;
Bitmap bitmap = BitmapUtils.drawableToBitmap(appInfo.loadIcon(pm), true);
ImageView imageView = new ImageView(activity);
imageView.setLayoutParams(new LinearLayout.LayoutParams(DisplayUtils.dip2px(activity, 25)
, DisplayUtils.dip2px(activity, 24)));
imageView.setImageBitmap(bitmap);
shareIconLl.addView(imageView);
}
}
if (requestCode == 0x170) { // 发送
qrCode.setImageResource(R.drawable.kc_qrcode_120);
sendCountTv.setText("成功传送游戏");
} else {
qrCode.setImageResource(R.drawable.kc_qrcode_110);
sendCountTv.setText("成功接收游戏");
}
double size = (((float) filesSize / 1024) / 1024);
String sizeName;
if (size > 1024) {
DecimalFormat df = new DecimalFormat("#.0");
sizeName = df.format(size / 1024) + "GB";
} else {
DecimalFormat df = new DecimalFormat("#.0");
sizeName = df.format(size) + "MB";
}
if (sendTime < 1000) { // 最少设置发送时间为1s为了简易计算
sendTime = 1000;
}
int i = (filesSize / 1024) / (sendTime / 1000);
String speed;
if (i >= 1000) {
float mSpeed = i / 1024f;
DecimalFormat df = new DecimalFormat("#.0");
String str = df.format(mSpeed);
if (str.length() > 4) {
str = str.substring(0, 4);
}
speed = str + "MB/s";
} else {
speed = i + "KB/s";
}
if (sendTime > 60000) {
timeCount.setText(String.valueOf(sendTime / 1000 / 60));
timeTv.setText("分钟传送完成");
} else {
timeCount.setText(String.valueOf(sendTime / 1000));
timeTv.setText("秒传送完成");
}
sizeTv.setText(sizeName);
speedTv.setText(speed);
countTv.setText(filesCount + "");
// 延迟操作,等待截图部分绘制完成
handler.postDelayed(() -> {
mShareLl.setDrawingCacheEnabled(true);
mShareLl.buildDrawingCache();
Bitmap drawingCache = mShareLl.getDrawingCache();
saveBitmap(drawingCache, activity, picName);
MessageShareUtils.getInstance(activity).showShareWindows(activity, mShareBottomLl, drawingCache, picName, 2);
mShareBottomLl.setVisibility(View.VISIBLE);
}, 200);
closeIv.setOnClickListener(v -> dialog.cancel());
}
public static void saveBitmap(Bitmap bm, Activity activity, String picName) {
File externalCacheDir = activity.getExternalCacheDir();
if (externalCacheDir == null) return;
File file = new File(externalCacheDir.getPath() + "/ShareImg");
if (!file.isDirectory()) {
file.delete();
file.mkdirs();
}
if (!file.exists()) {
file.mkdirs();
}
MessageShareUtils.getInstance(activity).writeBitmap(file.getPath(), picName, bm, false);
}
public static void showInstallHintDialog(Context context, final ConfirmListener cmListener) {
context = checkDialogContext(context);
@ -567,8 +400,6 @@ public class DialogUtils {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
/**
@ -589,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() {
@ -805,6 +636,29 @@ public class DialogUtils {
dialog.show();
}
public static void showLowSystemVersionDialog(Context context) {
final Context activityContext = checkDialogContext(context);
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_alert, null);
TextView contentTv = contentView.findViewById(R.id.dialog_content);
TextView titleTv = contentView.findViewById(R.id.dialog_title);
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
titleTv.setText("提示");
contentTv.setText("抱歉,您当前系统版本过低,暂不支持视频功能");
positiveTv.setText("我知道了");
positiveTv.setOnClickListener(view -> {
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
public static void showListDialog(Context context,
List<String> selectionList,
DialogInterface.OnClickListener onClickListener) {
@ -934,35 +788,36 @@ public class DialogUtils {
public static void showPrivacyPolicyDialog(Context context, String title, String content, EmptyCallback callback) {
final Context activityContext = checkDialogContext(context);
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
AtomicBoolean isCanceledByClickOutsideOfDialog = new AtomicBoolean(true);
String privacyPolicyContent;
String privacyPolicyTitle = (TextUtils.isEmpty(title)) ? "个人信息保护指引" : title;
if (TextUtils.isEmpty(content)) {
privacyPolicyContent = "你的个人信息安全对我们来说至关重要。一直以来,光环助手致力于为每位用户提供更安全的互联网环境" +
"。我们将依据《中华人民共和国网络安全法》、《信息安全技术个人信息安全规范》GB/T 35273-2017" +
"以及其他相关法律法规和技术规范来收集和使用你的个人信息,以帮助我们向你提供更优质的产品和服务。" +
"<br/>1.为帮助你浏览内容、互动交流、注册认证等,我们会收集部分必要的信息" +
"<br/>2.为提供上述服务,我们可能需要获取 IMEI号码、IMSI号码 等信息的读取权限" +
"<br/>3.以上获取个人信息的权限均不会默认开启,只有在运行相关功能或服务时才会明确提示授权,光环助手不会在未经你同意的情况下收集相关信息";
privacyPolicyContent = "光环助手致力于为每位用户提供更安全的互联网环境,我们将依据相关法律法规和技术规范来收集和使用你的个人信息。" +
"<br/>1.为帮助你浏览内容、互动交流、注册认证等,我们需要获取一些必要的信息,以实现完整的功能;" +
"<br/>2.日常使用中,我们可能需要开启 IMEI号码、IMSI号码、定位、相册 等信息的读取权限;" +
"<br/>3.以上信息的读取权限均不会默认开启,只有在运行相关功能或服务时才会明确提示授权,光环助手不会在未经你同意的情况下收集相关信息";
} else {
privacyPolicyContent = content;
}
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_privacy_policy, null);
TextView contentTv = contentView.findViewById(R.id.dialog_content);
TextView titleTv = contentView.findViewById(R.id.dialog_title);
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
TextView skipTv = contentView.findViewById(R.id.dialog_skip);
SpannableStringBuilder skipText = new SpannableStringBuilder("查看完整版的 隐私政策");
SpannableStringBuilder skipText = new SpannableStringBuilder("你可以查看完整版的 隐私政策");
skipText.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme));
ds.setColor(ContextCompat.getColor(activityContext, R.color.text_1383EB));
ds.setUnderlineText(false);
}
@ -989,12 +844,83 @@ public class DialogUtils {
dialog.setOnDismissListener(d -> {
callback.onCallback();
});
dialog.setOnCancelListener(cd -> {
if (isCanceledByClickOutsideOfDialog.get()) {
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
}
});
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
isCanceledByClickOutsideOfDialog.set(false);
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
}
return false;
});
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
try {
dialog.show();
} catch (Exception ignored) {
}
}
/**
* 特殊:目前只在提交问题错误返回时弹出
*/
public static Dialog showUploadDraftDialog(Context context,
final CancelListener clListener,
final ConfirmListener cmListener) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_video_upload_draft, null);
TextView negativeTv = contentView.findViewById(R.id.negative);
TextView positiveTv = contentView.findViewById(R.id.positive);
TextView content = contentView.findViewById(R.id.content);
positiveTv.setBackground(DrawableView.getOvalDrawable(R.color.text_f5f5f5, 999));
negativeTv.setBackground(DrawableView.getOvalDrawable(R.color.theme, 999));
content.setText(Html.fromHtml(context.getString(R.string.video_upload_draft_dialog_content)));
negativeTv.setOnClickListener(view -> {
if (clListener != null) {
clListener.onCancel();
}
dialog.dismiss();
});
positiveTv.setOnClickListener(view -> {
if (cmListener != null) {
cmListener.onConfirm();
}
dialog.dismiss();
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
return dialog;
}
public static Dialog fixWebViewKeyboardNotWorking(Activity activity) {
final Dialog dialog = new Dialog(activity, R.style.TransparentDialog);
View view = new View(activity);
view.setOnClickListener(v -> dialog.dismiss());
view.postDelayed(() -> {
if (!activity.isFinishing()) {
dialog.show();
dialog.dismiss();
}
}, 500);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
return dialog;
}
/**

View File

@ -3,6 +3,7 @@ package com.gh.common.util
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import com.gh.base.BaseActivity
@ -10,22 +11,29 @@ 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.qa.AskFragment
import com.gh.gamecenter.mygame.PlayedGameActivity
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
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
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.lightgame.utils.Util_System_ClipboardManager
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
@ -122,10 +130,27 @@ object DirectUtils {
display = linkEntity.display ?: Display())))
}
"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))
}
/**
* 跳转到新闻详情
*/
@ -135,7 +160,23 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
bundle.putString(KEY_NEWSID, id)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
/**
* 跳转至个人主页
*/
@JvmStatic
fun directToHomeActivity(context: Context, userId: String?, entrance: String? = null, path: String? = null) {
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)
}
/**
@ -148,7 +189,12 @@ object DirectUtils {
bundle.putString(KEY_TO, GameDetailActivity::class.java.simpleName)
bundle.putString(KEY_GAMEID, id)
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
// 跳转至用户玩过的游戏
fun directToPlayedGame(context: Context, userId: String, entrance: String = "", path: String = "") {
context.startActivity(PlayedGameActivity.getIntent(context, userId, entrance, path))
}
// 专栏
@ -159,7 +205,7 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
bundle.putParcelable(EntranceUtils.KEY_SUBJECT_DATA, subjectData)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
// 反馈
@ -171,7 +217,7 @@ object DirectUtils {
bundle.putString(KEY_CONTENT, content)
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
bundle.putSerializable(EntranceUtils.KEY_SUGGESTTYPE, SuggestType.gameQuestion)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
@JvmStatic
@ -179,7 +225,7 @@ object DirectUtils {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, DownloadManagerActivity.TAG)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
/**
@ -194,7 +240,7 @@ object DirectUtils {
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_PACKAGENAME, packageName)
bundle.putBoolean(KEY_AUTO_DOWNLOAD, true)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
}
@ -206,7 +252,17 @@ object DirectUtils {
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_PACKAGENAME, packageName)
bundle.putInt(BaseFragment_TabLayout.PAGE_INDEX, INDEX_UPDATE)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
@JvmStatic
fun directToToolbox(context: Context, gameId: String, toolboxUrl: String, entrance: String = ENTRANCE_BROWSER) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_TO, ToolBoxActivity::class.java.simpleName)
bundle.putString(KEY_GAMEID, gameId)
bundle.putString(KEY_URL, toolboxUrl)
jumpActivity(context, bundle)
}
@JvmStatic
@ -216,7 +272,7 @@ object DirectUtils {
bundle.putString(KEY_TO, AnswerDetailActivity::class.java.name)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_ANSWER_ID, id)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
@JvmStatic
@ -226,7 +282,7 @@ object DirectUtils {
bundle.putString(KEY_TO, QuestionsDetailActivity::class.java.name)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_QUESTIONS_ID, id)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
@JvmStatic
@ -235,7 +291,7 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, WebActivity::class.java.simpleName)
bundle.putString(EntranceUtils.KEY_URL, url)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
// 个人-系统消息
@ -244,7 +300,7 @@ object DirectUtils {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, MessageKeFuActivity::class.java.simpleName)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
@JvmStatic
@ -302,7 +358,7 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, LibaoDetailActivity::class.java.simpleName)
bundle.putString(EntranceUtils.KEY_ID, giftId)
EntranceUtils.jumpActivity(context, bundle)
jumpActivity(context, bundle)
}
/**
@ -319,8 +375,8 @@ object DirectUtils {
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 1))
EventBus.getDefault().post(EBReuse(AskFragment.EB_RETRY_PAGE))
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
}
}
@ -348,4 +404,45 @@ object DirectUtils {
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
jumpActivity(context, bundle)
}
/**
* @param fromLocation 可见 [VideoDetailContainerViewModel.Location]
*/
@JvmStatic
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, entrance: String? = null, path: String? = "") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, VideoDetailActivity::class.java.name)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_ID, videoId)
bundle.putString(KEY_LOCATION, fromLocation)
bundle.putBoolean(KEY_SHOW_COMMENT, showComment)
jumpActivity(context, bundle)
} else {
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

@ -1,12 +1,23 @@
package com.gh.common.util;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.halo.assistant.HaloApp;
public class DisplayUtils {
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import androidx.core.content.ContextCompat;
public class DisplayUtils {
/**
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
*/
@ -14,7 +25,7 @@ public class DisplayUtils {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dip
*/
@ -22,16 +33,19 @@ public class DisplayUtils {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
*/
public static int dip2px(float dpValue) {
final float scale = HaloApp.getInstance().getApplication().getResources().getDisplayMetrics().density;
final float scale = HaloApp.getInstance()
.getApplication()
.getResources()
.getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 将px值转换为sp值保证文字大小不变
*
@ -43,7 +57,7 @@ public class DisplayUtils {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值保证文字大小不变
*
@ -55,7 +69,7 @@ public class DisplayUtils {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
/**
* 获取状态栏的高度
*
@ -65,7 +79,7 @@ public class DisplayUtils {
public static int getStatusBarHeight(Resources resources) {
return getInternalDimensionSize(resources, "status_bar_height");
}
public static int getInternalDimensionSize(Resources res, String key) {
int result = 0;
int resourceId = res.getIdentifier(key, "dimen", "android");
@ -74,5 +88,107 @@ public class DisplayUtils {
}
return result;
}
public static void transparentStatusBar(Activity activity) {
//make full transparent statusBar
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}
if (Build.VERSION.SDK_INT >= 19) {
activity.getWindow()
.getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
public static void transparentStatusAndNavigation(Activity activity) {
//make full transparent statusBar
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
}
if (Build.VERSION.SDK_INT >= 19) {
activity.getWindow()
.getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);
}
}
private static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
public static void setLightStatusBar(Activity activity, boolean lightStatusBar) {
boolean isMIUI = setMIUIStatusBarStyle(activity, lightStatusBar);
if (!isMIUI) {
Window window = activity.getWindow();
View decor = window.getDecorView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (lightStatusBar) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
}
private static boolean setMIUIStatusBarStyle(Activity activity, boolean lightStatusBar) {
boolean result = false;
Window window = activity.getWindow();
if (window != null) {
Class clazz = window.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(window, lightStatusBar ? darkModeFlag : 0, darkModeFlag);//状态栏透明且黑色字体
result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && lightStatusBar) {
//开发版 7.7.13 及以后版本采用了系统API旧方法无效但不会报错所以两个方式都要加上
activity.getWindow()
.getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
} catch (Exception e) {
// do nothing
}
}
return result;
}
public static void setStatusBarColor(Activity activity, int color, boolean lightStatusBar) {
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(ContextCompat.getColor(activity,color));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setLightStatusBar(activity,lightStatusBar);
}
}
}

View File

@ -167,13 +167,21 @@ public class DownloadItemUtils {
return;
}
if (gameEntity.getApk() == null || gameEntity.getApk().isEmpty()) {
if (gameEntity.getApk().isEmpty() || gameEntity.getDownloadOffStatus() != null) {
holder.gameDes.setVisibility(View.VISIBLE);
holder.gameProgressbar.setVisibility(View.GONE);
holder.gameInfo.setVisibility(View.GONE);
holder.gameDownloadBtn.setBackgroundResource(R.drawable.news_detail_comment);
holder.gameDownloadBtn.setText("暂无");
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
String offStatus = gameEntity.getDownloadOffStatus();
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));
holder.gameDownloadBtn.setBackgroundResource(R.drawable.news_detail_comment);
}
holder.gameDownloadBtn.setClickable(false);
} else if (gameEntity.getApk().size() == 1) {
updateNormalItem(context, holder, gameEntity, isShowPlatform, pluginLocation);
@ -360,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,
@ -367,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, () -> {
@ -395,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);
};
// 启动不需要请求存储权限
@ -410,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

@ -3,7 +3,6 @@ package com.gh.common.util;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.NormalActivity;
@ -25,6 +24,7 @@ public class EntranceUtils {
public static final String KEY_URL = "url";
public static final String KEY_GAMENAME = "gameName";
public static final String HOST_ARTICLE = "article";
public static final String HOST_VIDEO = "video";
public static final String HOST_COMMUNITY_ARTICLE = "community_article";
public static final String HOST_COMMUNITY_COLUMN = "community_column";
public static final String HOST_GAME = "game";
@ -39,12 +39,14 @@ public class EntranceUtils {
public static final String HOST_SUGGESTION = "suggestion";
public static final String HOST_ANSWER = "answer";
public static final String HOST_QUESTION = "question";
public static final String HOST_TOOLBOX = "toolbox";
public static final String KEY_DATA = "data";
public static final String KEY_MESSAGE = "message";
public static final String KEY_MESSAGE_ID = "message_id";
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 = "(浏览器)";
@ -61,8 +63,10 @@ public class EntranceUtils {
public static final String KEY_VERSION = "version";
public static final String KEY_CONTENT = "content";
public static final String KEY_PLUGIN = "plugin";
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";
@ -83,6 +87,7 @@ public class EntranceUtils {
public static final String KEY_INVITE_SEARCH_KEY = "inviteSearchKey";
public static final String KEY_MESSAGE_TYPE = "messageType";
public static final String KEY_QUESTIONS_SEARCH_KEY = "questionsSearchKey";
public static final String KEY_SHOW_COMMENT = "showComment";
public static final String KEY_SHOW_ANSWER_COMMENT = "showAnswerComment";
public static final String KEY_RECOMMENDS_CONTENTS = "isRecommendsContents";
public static final String KEY_VERSION_UPDATE = "versionUpdate";
@ -113,6 +118,13 @@ public class EntranceUtils {
public static final String KEY_SKIP_GAME_COMMENT = "skipGameComment";
public static final String KEY_OPEN_PLATFORM_WINDOW = "openPlatformWindow";
public static final String KEY_OPEN_KEYBOARD = "openKeyboard";
public static final String KEY_PATH_VIDEO = "pathVideo";
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";
public static void jumpActivity(Context context, Bundle bundle) {
@ -121,18 +133,15 @@ public class EntranceUtils {
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(context))) {
// 应用正在运行,前台或后台
String to = bundle.getString(KEY_TO);
if (!TextUtils.isEmpty(to)) {
Class<?> clazz = ClassUtils.forName(to);
if (clazz != null) {
if (NormalFragment.class.isAssignableFrom(clazz)) { // 兼容NormalFragment
NormalActivity.startFragmentNewTask(context, (Class<? extends NormalFragment>) clazz, bundle);
} else {
Intent intent1 = new Intent(context, clazz);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.putExtras(bundle);
context.startActivity(intent1);
}
}
Class<?> clazz = ClassUtils.forName(to);
if (clazz == null) clazz = MainActivity.class;
if (NormalFragment.class.isAssignableFrom(clazz)) { // 兼容NormalFragment
NormalActivity.startFragmentNewTask(context, (Class<? extends NormalFragment>) clazz, bundle);
} else {
Intent intent1 = new Intent(context, clazz);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.putExtras(bundle);
context.startActivity(intent1);
}
} else {
// 应用未在运行

View File

@ -4,7 +4,6 @@ import android.content.Context
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.ErrorEntity
import com.halo.assistant.fragment.WebFragment
import com.lightgame.utils.Utils
/**
@ -86,6 +85,7 @@ object ErrorHelper {
403045,
403054,
403069,
403071,
403047 -> handleErrorWithCommunityBannedDialog(context, errorEntity)
403057,
@ -109,6 +109,10 @@ object ErrorHelper {
404001 -> Utils.toast(context, "请求的资源不存在")
403016 -> Utils.toast(context, "标签内容可能包含敏感信息,请修改后再提交")
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,
@ -130,8 +134,8 @@ object ErrorHelper {
}
}
private fun handleErrorWithCommentBannedDialog(context: Context, errorEntity: ErrorEntity) {
val bannedType = if (errorEntity.data?.alwaysBlock!!) {
private fun handleErrorWithCommentBannedDialog(context: Context, errorEntity: ErrorEntity?) {
val bannedType = if (errorEntity?.data?.alwaysBlock == true) {
""
} else {
"(非永久)"
@ -146,7 +150,7 @@ object ErrorHelper {
}
private fun handleErrorWithCommunityBannedDialog(context: Context, errorEntity: ErrorEntity) {
val bannedType = if (errorEntity.data?.alwaysBlock!!) {
val bannedType = if (errorEntity.data?.alwaysBlock == true) {
""
} else {
"(非永久)"
@ -154,7 +158,7 @@ object ErrorHelper {
val dialogContext = DialogUtils.checkDialogContext(context)
DialogUtils.showAlertDialog(dialogContext,
"提示",
"你因违反《问答版块规则》,已被禁言$bannedType如有疑问请联系客服QQ3467475980",
"你因违反《问答版块规则》,已被禁言$bannedType如有疑问请联系客服QQ1562479331",
"去看看", "关闭", {
dialogContext.startActivity(WebActivity.getCommunityRuleIntent(dialogContext))
}, null)

View File

@ -2,15 +2,26 @@ package com.gh.common.util
import android.content.ClipboardManager
import android.content.Context
import android.text.Editable
import android.text.Html
import android.text.Spanned
import android.text.TextWatcher
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.constant.Config
import com.gh.common.constant.Constants
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
@ -18,6 +29,7 @@ import com.lightgame.utils.Utils
import okhttp3.MediaType
import okhttp3.RequestBody
import java.net.URI
import kotlin.math.abs
/**
* 创建以 activity 为观察者上下文的 viewModel
@ -67,6 +79,43 @@ 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
*/
// 监听滚动距离
fun RecyclerView.doOnScrolledSpecificDistance(distanceX: Int = 0, distanceY: Int = 0, singleTimeEvent: Boolean = false, action: () -> Unit) {
val listener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if ((distanceX != 0 && abs(dx) > distanceX) || (distanceY != 0 && abs(dy) > distanceY)) {
action.invoke()
if (singleTimeEvent) {
removeOnScrollListener(this)
}
}
}
}
addOnScrollListener(listener)
}
/**
* View Extensions
*/
@ -86,6 +135,16 @@ fun View.goneIf(predicate: Boolean) {
}
}
fun View.addSelectableItemBackground() {
val outValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
setBackgroundResource(outValue.resourceId);
}
fun View.removeSelectableItemBackground() {
background = null
}
/**
* LiveData Extensions
*/
@ -161,16 +220,21 @@ inline fun tryWithDefaultCatch(action: (() -> Unit)) {
* String related
*/
fun String.fromHtml(): Spanned {
return Html.fromHtml(this)
return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
// 去掉文章/答案的插入内容
fun String.removeInsertedContent(): String {
val textRegex = "(?s)<div class=\"gh-internal-content content-right\".*?</div>"
return this.replace(textRegex.toRegex(), "")
}
// 去除视频相关文本
fun String.removeVideoContent(): String {
val videoRegex = "(?s)<div class=\"insert-video-container\".*?</div>"
return this.replace(videoRegex.toRegex(), "")
}
// 完全地清除所有 Html 格式
fun String.clearHtmlFormatCompletely(): String {
return Html.fromHtml(this).toString().replace('\n', 32.toChar())
@ -211,15 +275,23 @@ fun Float.dip2px(): Int {
return (this * scale + 0.5f).toInt()
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dip
*/
fun Float.px2dip(): Int {
val scale = HaloApp.getInstance().application.resources.displayMetrics.density
return (this / scale + 0.5f).toInt()
}
/**
* PopupWindow 自动适配方向
*/
fun PopupWindow.showAutoOrientation(anchorView: View) {
fun PopupWindow.showAutoOrientation(anchorView: View, distanceY: Int = 0) {
val windowPos = IntArray(2)
val anchorLoc = IntArray(2)
// 获取锚点View在屏幕上的左上角坐标位置
anchorView.getLocationOnScreen(anchorLoc)
val anchorHeight = anchorView.height
val anchorHeight = anchorView.height + distanceY
// 获取屏幕的高宽
val screenHeight = anchorView.context.resources.displayMetrics.heightPixels
val screenWidth = anchorView.context.resources.displayMetrics.widthPixels
@ -267,4 +339,96 @@ fun Fragment.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
action.invoke()
}
})
}
fun FragmentActivity.checkReadPhoneStateAndStoragePermissionBeforeAction(action: (() -> Unit)) {
PermissionHelper.checkReadPhoneStateAndStoragePermissionBeforeAction(this, object : EmptyCallback {
override fun onCallback() {
action.invoke()
}
})
}
fun FragmentActivity.checkReadPhoneStatePermissionBeforeAction(action: (() -> Unit)) {
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(this, object : EmptyCallback {
override fun onCallback() {
action.invoke()
}
})
}
fun FragmentActivity.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
PermissionHelper.checkStoragePermissionBeforeAction(this, object : EmptyCallback {
override fun onCallback() {
action.invoke()
}
})
}
/**
* TextView related.
*/
fun TextView.setTextWithHighlightedTextWrappedInsideWrapper(text: CharSequence,
wrapper: String = Constants.DEFAULT_TEXT_WRAPPER,
@ColorRes
highlightColorId: Int = R.color.theme,
copyClickedText: Boolean = false,
highlightedTextClickListener: (() -> Unit)? = null) {
TextHelper.highlightTextThatIsWrappedInsideWrapper(this, text, wrapper, highlightColorId, object : SimpleCallback<String> {
override fun onCallback(arg: String) {
if (copyClickedText) {
arg.copyTextAndToast("已复制:$arg")
}
highlightedTextClickListener?.invoke()
}
})
}
fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before: Int, count: Int) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
action.invoke(s ?: "", start, before, count)
}
})
}
fun Int.toColor(): Int {
return HaloApp.getInstance().application.resources.getColor(this)
}
fun Int.toResString(): String {
return HaloApp.getInstance().application.resources.getString(this)
}
fun Int.toSimpleCount(): String {
return NumberUtils.transSimpleCount(this)
}
/**
* Image related
*/
fun SimpleDraweeView.display(url: String) {
ImageUtils.display(this, url)
}
/**
* 测试用包裹
*/
inline fun debugOnly(f: () -> Unit) {
if (BuildConfig.DEBUG) {
f()
}
}
inline fun testChannelOnly(f: () -> Unit) {
if (HaloApp.getInstance().channel == Config.DEFAULT_CHANNEL) {
f()
}
}

View File

@ -147,6 +147,7 @@ public class GameUtils {
gameUpdateEntity.setTagStyle(gameEntity.getTagStyle());
gameUpdateEntity.setBrief(gameEntity.getBrief());
gameUpdateEntity.setPlugin(apkEntity.getPlugin());
gameUpdateEntity.setDownload(gameEntity.getDownload());
return gameUpdateEntity;
}

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,22 @@
package com.gh.common.util
import android.content.Context
import com.lightgame.utils.Utils
import com.zhihu.matisse.filter.ApplyFilter
import com.zhihu.matisse.internal.entity.Item
class GhMatisseVideoApplyFilter : ApplyFilter() {
override fun applyFiltering(context: Context, itemList: MutableList<Item>, callBack: OnApplyFilterCallBack) {
if (!NetworkUtils.isNetworkConnected(context)) {
Utils.toast(context, "网络异常,请检查手机网络状态")
} else if (!NetworkUtils.isWifiConnected(context)) {
DialogUtils.showAlertDialog(context, "提示",
"您当前正在使用移动网络上传视频,确定继续上传吗?",
"继续上传", "暂时不了",
DialogUtils.ConfirmListener { callBack.onApply() }, null)
} else {
callBack.onApply()
}
}
}

View File

@ -0,0 +1,27 @@
package com.gh.common.util
import android.content.Context
import com.zhihu.matisse.MimeType
import com.zhihu.matisse.filter.Filter
import com.zhihu.matisse.internal.entity.IncapableCause
import com.zhihu.matisse.internal.entity.Item
class GhMatisseVideoFilter : Filter() {
override fun constraintTypes(): MutableSet<MimeType> {
return MimeType.ofVideo()
}
override fun filter(context: Context, item: Item): IncapableCause? {
if (!needFiltering(context, item)) return null
if (item.mimeType != MimeType.MP4.toString()) {
return IncapableCause(IncapableCause.TOAST, "请把视频格式转换为Mp4后再上传")
}
if (item.size > 500 * 1024 * 1024) {
return IncapableCause(IncapableCause.TOAST, "视频大小限制为500M")
}
return null
}
}

View File

@ -1,6 +1,8 @@
package com.gh.common.util
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
/**
@ -14,11 +16,11 @@ object GsonUtils {
return gson.fromJson(json, t)
}
// @JvmStatic
// fun <T> fromJsonList(json: String): List<T> {
// val type = object : TypeToken<List<T>>() {}.type
// return gson.fromJson(json, type)
// }
@JvmStatic
fun <T> fromJsonList(json: JSONArray): List<T> {
val type = object : TypeToken<List<T>>() {}.type
return gson.fromJson(json.toString(), type)
}
@JvmStatic
fun toJson(any: Any?): String {

View File

@ -0,0 +1,33 @@
package com.gh.common.util
import com.gh.gamecenter.entity.Display
import com.gh.gamecenter.entity.SubjectRecommendEntity
object HomeBottomBarHelper {
private const val GAME_BAR_KEY = "game_bar_key"
@JvmStatic
fun getDefaultGameBarData(): SubjectRecommendEntity {
try {
val json = SPUtils.getString(GAME_BAR_KEY)
if (json.isNotEmpty()) {
return GsonUtils.fromJson(json, SubjectRecommendEntity::class.java)
}
} catch (ignore: Exception) {
}
return SubjectRecommendEntity(link = "5de21b5d75e6fa054f784882",
type = "block",
text = "游戏库",
name = "游戏库",
iconSelect = "https://resource.ghzs.com/image/game/library/entrance/5de3a2ac2ab874001c5ff0e9.png",
iconUnselect = "https://resource.ghzs.com/image/game/library/entrance/5de3a2b16b6b89001d48e779.png",
default = false,
display = Display())
}
@JvmStatic
fun updateDefaultGameBarData(data: SubjectRecommendEntity) {
SPUtils.setString(GAME_BAR_KEY, data.toJson())
}
}

View File

@ -23,13 +23,8 @@ import org.json.JSONObject;
* Created by khy on 2/01/18.
*/
public class LogUtils {
public static void uploadCommunityArticle(String tracers,
String articleId,
String articleTitle,
int readTime,
CommunityEntity community,
SpecialColumn specialColumn) {
public static void uploadCommunityArticle(String tracers, String articleId, String articleTitle, int readTime, CommunityEntity community, SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "community_article");
@ -53,10 +48,10 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void uploadDevice(LunchType launchType) {
JSONObject object = new JSONObject();
Application application = HaloApp.getInstance().getApplication();
@ -68,17 +63,11 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void uploadAnswerReadTime(String tracers,
int readTime,
String answerId,
Questions questions,
String communityId,
String CommunityName,
SpecialColumn specialColumn) {
public static void uploadAnswerReadTime(String tracers, int readTime, String answerId, Questions questions, String communityId, String CommunityName, SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "answer");
@ -103,16 +92,11 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void uploadQuestionReadTime(String tracers,
int readTime,
Questions questions,
String communityId,
String communityName,
SpecialColumn specialColumn) {
public static void uploadQuestionReadTime(String tracers, int readTime, Questions questions, String communityId, String communityName, SpecialColumn specialColumn) {
JSONObject object = new JSONObject();
try {
object.put("subject", "question");
@ -136,13 +120,13 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void uploadSearch(String searchKey) {
if (TextUtils.isEmpty(searchKey)) return;
JSONObject object = new JSONObject();
try {
object.put("community_id", UserManager.getInstance().getCommunity().getId());
@ -152,11 +136,11 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void communityRefresh(int dataCount, boolean manualRefresh) {
JSONObject object = new JSONObject();
try {
@ -168,10 +152,10 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void login(String loginStep, String loginType, String entrance) {
JSONObject object = new JSONObject();
try {
@ -182,15 +166,29 @@ public class LogUtils {
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
public static void qaAccess(String access, CommunityEntity communityEntity) {
JSONObject object = new JSONObject();
try {
object.put("subject", "qa_access");
object.put("access", access);
object.put("community_id", communityEntity.getId());
object.put("community_name", communityEntity.getName());
} catch (JSONException e) {
e.printStackTrace();
}
upload(object);
}
private static void upload(JSONObject object) {
if (BuildConfig.DEBUG) {
Utils.log("LogUtils->" + object.toString());
}
Context context = HaloApp.getInstance().getApplication();
try {
object.put("version", PackageUtils.getVersionName());
@ -201,12 +199,13 @@ public class LogUtils {
object.put("user_id", UserManager.getInstance().getUserId());
object.put("device_system", android.os.Build.VERSION.RELEASE);
object.put("device_model", android.os.Build.MODEL);
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance().getApplication()));
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance()
.getApplication()));
object.put("G_ID", UserManager.getInstance().getDeviceId());
} catch (JSONException e) {
e.printStackTrace();
}
// 暂时除了曝光外的数据都是扔到 community 这个库的,要是不是这个这个库的话这里要改一下
LogHubUtils.uploadLog(DeviceUtils.getIPAddress(context), object, "community");
}

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

@ -16,8 +16,10 @@ object MtaHelper {
val prop = Properties()
if (kv.size == 1) {
prop.setProperty(kv[0], "")
prop.setProperty(kv[0], kv[0])
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
return
}
for (i in kv.indices) {
@ -47,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

@ -67,12 +67,9 @@ public class NetworkUtils {
*/
public static boolean isMobileConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mMobileNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobileNetworkInfo != null) {
return mMobileNetworkInfo.isAvailable();
if (isNetworkConnected(context)) {
String network = DeviceUtils.getNetwork(context);
return !"WIFI".equals(network);
}
}
return false;
@ -127,41 +124,31 @@ public class NetworkUtils {
* @return 当前移动网络连接的类型信息
*/
public static String getMobileNetworkType(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info == null) return "unknown";
switch (info.getType()) {
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
return "unknown";
// Cellular Data2G
case TelephonyManager.NETWORK_TYPE_EDGE:
TelephonyManager mTelephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = mTelephonyManager.getNetworkType();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_IDEN:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "2G";
// Cellular Data3G
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "3G";
// Cellular Data4G
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
default:
return "unknown";
}
}
}

View File

@ -0,0 +1,29 @@
package com.gh.common.util
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import com.gh.common.constant.Constants
import com.gh.common.dialog.NotificationHintDialogFragment
import com.gh.gamecenter.entity.NotificationHint
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
object NotificationHelper {
@JvmStatic
fun showEnableNotificationDialogIfItsDisabled(activity: AppCompatActivity, notificationHint: NotificationHint) {
if (notificationIsEnable()) {
Utils.log("notification is enable")
} else {
NotificationHintDialogFragment.getInstance(notificationHint).show(activity.supportFragmentManager, "notification")
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_HINT, true)
}
}
@JvmStatic
fun notificationIsEnable(): Boolean {
val manager = NotificationManagerCompat.from(HaloApp.getInstance().application)
return manager.areNotificationsEnabled()
}
}

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

@ -72,6 +72,7 @@ public class PackageUtils {
updateEntity.setBrief(gameEntity.getBrief());
updateEntity.setTag(gameEntity.getTag());
updateEntity.setTagStyle(gameEntity.getTagStyle());
updateEntity.setDownload(gameEntity.getDownload());
updateList.add(updateEntity);
}
}

View File

@ -2,51 +2,96 @@ package com.gh.common.util
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.fragment.app.FragmentActivity
import com.tbruyelle.rxpermissions2.RxPermissions
object PermissionHelper {
@JvmStatic
fun requestReadPhoneStateAndStoragePermissionFromStartUp(context: Context) {
if (context is FragmentActivity) {
val rxPermission = RxPermissions(context)
var requestCount = 0
val permissionsStatusMap = hashMapOf<String, Boolean>()
permissionsStatusMap[Manifest.permission.READ_PHONE_STATE] = false
permissionsStatusMap[Manifest.permission.READ_EXTERNAL_STORAGE] = false
permissionsStatusMap[Manifest.permission.WRITE_EXTERNAL_STORAGE] = false
tryWithDefaultCatch {
rxPermission
.requestEach(Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe { permission ->
requestCount++
permissionsStatusMap[permission.name] = permission.granted
if (requestCount == 2) {
val hasReadPhoneStatePermission = permissionsStatusMap[Manifest.permission.READ_PHONE_STATE] == true
val hasReadStoragePermission = permissionsStatusMap[Manifest.permission.READ_EXTERNAL_STORAGE] == true
if (hasReadPhoneStatePermission && hasReadStoragePermission) {
MtaHelper.onEvent("授权情况", "启动授权", "都授权")
} else if (!hasReadPhoneStatePermission && !hasReadStoragePermission) {
MtaHelper.onEvent("授权情况", "启动授权", "都不授权")
} else if (hasReadPhoneStatePermission) {
MtaHelper.onEvent("授权情况", "启动授权", "只授权IMEI")
} else if (hasReadStoragePermission) {
MtaHelper.onEvent("授权情况", "启动授权", "只授权存储")
}
}
}
}
}
}
@SuppressLint("CheckResult")
@JvmStatic
fun checkStoragePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
if (context is FragmentActivity) {
val rxPermission = RxPermissions(context)
rxPermission
.requestEachCombined(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context,
"权限申请",
"光环助手需要存储权限,以保证能正常使用相关功能",
"重试",
"放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) },
null)
}
else -> {
DialogUtils.showPermissionDialog(context,
"权限申请",
"在设置-应用-光环助手-权限中开启存储权限,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
},
null)
tryWithDefaultCatch {
rxPermission
.requestEachCombined(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context,
"权限申请",
"光环助手需要存储权限,以保证能正常使用相关功能",
"重试",
"放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) },
null)
}
else -> {
DialogUtils.showPermissionDialog(context,
"权限申请",
"在设置-应用-光环助手-权限中开启存储权限,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
},
null)
}
}
}
}
}
}
}
@ -55,36 +100,39 @@ object PermissionHelper {
fun checkReadPhoneStateAndStoragePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
if (context is FragmentActivity) {
val rxPermission = RxPermissions(context)
rxPermission
.requestEachCombined(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
ActivationHelper.sendActivationInfo()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"光环助手需要获取存储权限和手机信息权限,以保证能正常使用相关功能", "重试", "放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) }, null)
}
else -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"在设置-应用-光环助手-权限中开启获取存储权限和手机信息,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
}, null)
tryWithDefaultCatch {
rxPermission
.requestEachCombined(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
ActivationHelper.sendActivationInfo()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"光环助手需要获取存储权限和手机信息权限,以保证能正常使用相关功能", "重试", "放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) }, null)
}
else -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"在设置-应用-光环助手-权限中开启获取存储权限和手机信息,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
}, null)
}
}
}
}
}
}
}
@ -93,35 +141,85 @@ object PermissionHelper {
fun checkReadPhoneStatePermissionBeforeAction(context: Context, emptyCallback: EmptyCallback) {
if (context is FragmentActivity) {
val rxPermission = RxPermissions(context)
rxPermission
.requestEachCombined(Manifest.permission.READ_PHONE_STATE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
ActivationHelper.sendActivationInfo()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"光环助手需要获取手机信息权限,以保证能正常使用相关功能", "重试", "放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) }, null)
}
else -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"在设置-应用-光环助手-权限中开启获取手机信息,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
}, null)
tryWithDefaultCatch {
rxPermission
.requestEachCombined(Manifest.permission.READ_PHONE_STATE)
.subscribe { permission ->
when {
permission.granted -> {
emptyCallback.onCallback()
ActivationHelper.sendActivationInfo()
}
permission.shouldShowRequestPermissionRationale -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"光环助手需要获取手机信息权限,以保证能正常使用相关功能", "重试", "放弃",
{ checkStoragePermissionBeforeAction(context, emptyCallback) }, null)
}
else -> {
DialogUtils.showPermissionDialog(context, "权限申请",
"在设置-应用-光环助手-权限中开启获取手机信息,以保证能正常使用相关功能",
"去设置",
"放弃",
{
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.getPackageName())
context.startActivity(intent)
}, null)
}
}
}
}
}
}
}
/**
* 跳转到权限设置
*
* @param activity
*/
fun toPermissionSetting(activity: Activity) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
toSystemConfig(activity)
} else {
try {
toApplicationInfo(activity)
} catch (e: Exception) {
e.printStackTrace()
toSystemConfig(activity)
}
}
}
/**
* 应用信息界面
*
* @param activity
*/
private fun toApplicationInfo(activity: Activity) {
val localIntent = Intent()
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
localIntent.data = Uri.fromParts("package", activity.packageName, null)
activity.startActivity(localIntent)
}
/**
* 系统设置界面
*
* @param activity
*/
private fun toSystemConfig(activity: Activity) {
try {
val intent = Intent(Settings.ACTION_SETTINGS)
activity.startActivity(intent)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -97,16 +97,23 @@ public class PostCommentUtils {
});
}
public static void voteAnswerComment(final Context context, final String answerId, String articleId, String articleCommunityId,
final String commentId, final PostCommentListener listener) {
public static void likeComment(final Context context,
final String answerId,
String articleId,
String articleCommunityId,
String videoId,
final String commentId,
final PostCommentListener listener) {
Observable<ResponseBody> observable;
if (!TextUtils.isEmpty(answerId)) {
observable = RetrofitManager.getInstance(context).getApi().postVoteAnswerComment(answerId, commentId);
} else {
} else if (!TextUtils.isEmpty(articleId)) {
observable = RetrofitManager.getInstance(context).getApi().postVoteCommunityArticleComment(articleCommunityId, articleId, commentId);
} else {
observable = RetrofitManager.getInstance(context).getApi().postVoteToVideo(videoId, commentId);
}
observable
.subscribeOn(Schedulers.io())
@ -215,6 +222,30 @@ public class PostCommentUtils {
});
}
public static void reportVideoComment(final Context context,
final String videoId,
final String commentId,
final String reportData,
final PostCommentListener listener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData);
RetrofitManager.getInstance(context).getApi()
.postVideoCommentReport(videoId, commentId, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(ResponseBody response) {
listener.postSuccess(null);
}
@Override
public void onFailure(HttpException e) {
listener.postFailed(e);
}
});
}
public interface PostCommentListener {
void postSuccess(JSONObject response);

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

@ -65,28 +65,32 @@ object ReservationHelper {
@JvmStatic
fun showDeleteReservationDialog(context: Context, emptyCallback: EmptyCallback) {
DialogUtils.showAlertDialog(
DialogHelper.showDialog(
context,
"删除预约",
"游戏已上线,你可以删除此预约记录,确定删除吗?",
"确定",
"取消",
{
emptyCallback.onCallback()
}, null)
"确定删除",
"暂不删除",
{ emptyCallback.onCallback() },
null,
trackMtaEvent = true,
mtaEvent = "预约游戏",
mtaKey = "删除预约弹窗")
}
@JvmStatic
fun showCancelReservationDialog(context: Context, emptyCallback: EmptyCallback) {
DialogUtils.showAlertDialog(
DialogHelper.showDialog(
context,
"取消预约",
"取消之后你将无法收到游戏上线的通知,确定取消预约吗?",
"确定取消",
"暂不取消",
{
emptyCallback.onCallback()
}, null)
{ emptyCallback.onCallback() },
null,
trackMtaEvent = true,
mtaEvent = "预约游戏",
mtaKey = "取消预约弹窗")
}

View File

@ -10,6 +10,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
@ -23,9 +24,6 @@ import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
@ -52,7 +50,10 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import static com.gh.common.util.GetLoginDataUtils.SCOPE;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
/**
* Created by khy on 2016/9/4.
@ -87,7 +88,8 @@ public class ShareUtils {
askInvite,
askNormal, // 问答问题/答案
shareGh,
communityArticle
communityArticle,
video
}
private String[] arrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "新浪微博", "短信", "复制链接", "取消"};
@ -120,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();
}
@ -221,6 +223,7 @@ public class ShareUtils {
mSummary += "(光环加速版)";
break;
case askNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
break;
@ -261,6 +264,7 @@ public class ShareUtils {
mSummary += "(光环加速版)";
break;
case askNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
break;
@ -289,6 +293,12 @@ public class ShareUtils {
ImageUtils.display(mContext, iconUrl, new BaseBitmapDataSubscriber() {
@Override
protected void onNewResultImpl(Bitmap bitmap) {
if (mShareType == ShareType.video) {
// 分享类型为视频时裁为正方形
int dimension = Math.min(bitmap.getWidth(), bitmap.getHeight());
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);
}
Bitmap compressBp = compressBitmap(bitmap);
if (mShareType == ShareType.askNormal || mShareType == ShareType.askInvite) {
msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true);
@ -362,6 +372,7 @@ public class ShareUtils {
mSummary += "(光环加速版)";
break;
case askNormal:
case video:
case communityArticle:
mTitle += " - 光环助手";
break;
@ -411,6 +422,7 @@ public class ShareUtils {
msg.title = mSummary;
break;
case askNormal:
case video:
case communityArticle:
msg.title = mTitle + " - 光环助手";
break;
@ -472,6 +484,7 @@ public class ShareUtils {
break;
case askInvite:
case askNormal:
case video:
case communityArticle:
smsBody = mTitle + " - 光环助手" + shareUrl;
break;

View File

@ -0,0 +1,5 @@
package com.gh.common.util
interface SimpleCallback<T> {
fun onCallback(arg: T)
}

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

@ -3,6 +3,7 @@ package com.gh.common.util
import android.content.Context
import com.ss.android.common.applog.TeaAgent
import com.ss.android.common.applog.TeaConfigBuilder
import com.ss.android.common.lib.EventUtils
/**
* 今日头条的激活统计 SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/567
@ -17,6 +18,19 @@ object TeaHelper {
.setAid(163824)
.createTeaConfig()
)
EventUtils.setRegister("mobile", true)
EventUtils.setPurchase(null, null, null, 0, null, null, true, 1)
}
@JvmStatic
fun onResume(context: Context) {
TeaAgent.onResume(context)
}
@JvmStatic
fun onPause(context: Context) {
TeaAgent.onPause(context)
}
}

View File

@ -1,10 +1,23 @@
package com.gh.common.util
import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.content.ClipboardManager
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
import java.util.*
import java.util.regex.Pattern
object TextHelper {
@ -49,6 +62,151 @@ object TextHelper {
}
}
@JvmStatic
fun highlightTextThatIsWrappedInsideWrapperByDefault(textView: TextView, text: String) {
textView.text = getHighlightedSpannableStringThatIsWrappedInsideWrapper(textView.context, text, "###", R.color.theme, object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = arg
Utils.toast(application, "已复制:$arg")
}
})
textView.movementMethod = CustomLinkMovementMethod.getInstance()
textView.highlightColor = Color.TRANSPARENT
}
@JvmStatic
fun highlightTextThatIsWrappedInsideWrapper(textView: TextView,
text: CharSequence,
wrapper: String,
@ColorRes
highlightColorId: Int,
highlightedTextClickListener: SimpleCallback<String>? = null) {
textView.text = getHighlightedSpannableStringThatIsWrappedInsideWrapper(textView.context, text, wrapper, highlightColorId, highlightedTextClickListener)
textView.movementMethod = CustomLinkMovementMethod.getInstance()
textView.highlightColor = Color.TRANSPARENT
}
@JvmStatic
fun getHighlightedSpannableStringThatIsWrappedInsideWrapper(
context: Context,
text: CharSequence,
wrapper: String = "###",
@ColorRes
highlightColorId: Int = R.color.theme,
highlightedTextClickListener: SimpleCallback<String>? = object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = arg
Utils.toast(application, "已复制:$arg")
}
}): SpannableStringBuilder {
var modifiedText = text
if (modifiedText.endsWith(wrapper)) {
// 若高亮符在最后一位就在后面加一个空格,避免整行都能点击
modifiedText = "$modifiedText "
}
val sBuilder = SpannableStringBuilder(modifiedText)
val wrapperTextLength = wrapper.length
val matcher = Pattern.compile("$wrapper(.+?)$wrapper", Pattern.DOTALL).matcher(modifiedText)
val pair = TreeMap<Int, Int>()
while (matcher.find()) {
// 保存起始位置和结束位置
pair[matcher.start(1)] = matcher.end(1)
sBuilder.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(context, highlightColorId)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val tv = widget as TextView
val s = tv.text as Spanned
val start = s.getSpanStart(this)
val end = s.getSpanEnd(this)
highlightedTextClickListener?.onCallback(s.substring(start, end))
}
}, matcher.start(1), matcher.end(1), 0)
}
// 反转 pair
val reversePair = pair.descendingMap()
// 找到
for (key in reversePair.keys) {
val end = reversePair[key]
end?.let {
sBuilder.replace(end, end + wrapperTextLength, "")
sBuilder.replace(key - wrapperTextLength, key, "")
}
}
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

@ -1,9 +1,11 @@
package com.gh.common.util;
import androidx.collection.ArrayMap;
import android.text.TextUtils;
import com.gh.common.constant.Constants;
import com.gh.gamecenter.BuildConfig;
import com.halo.assistant.HaloApp;
import java.util.regex.Pattern;
@ -42,7 +44,7 @@ public class TimestampUtils {
*/
public static String addTimestamp(String url) {
if ("GH_REFRESH".equals(HaloApp.getInstance().getChannel())) {
if (BuildConfig.DEBUG || "GH_REFRESH".equals(HaloApp.getInstance().getChannel())) {
if (TextUtils.isEmpty(url)) {
return url;
}

View File

@ -27,7 +27,9 @@ object UploadImageUtils {
question,
answer,
suggestion,
icon
icon,
poster,
game_upload
}
// 不处理图片,只是单纯的上传
@ -179,6 +181,77 @@ object UploadImageUtils {
return subscription
}
/**
* 上传图片,每成功一个就回调
*/
@SuppressLint("CheckResult")
fun uploadImageListOneByOne(type: UploadType, imgs: List<String>, compressGif: Boolean, listener: OnUploadImageListCountListener):Disposable?{
var subscription: Disposable? = null
Observable.create(ObservableOnSubscribe<Map<String, String>> {
//val compressList = compressImageList(imgs, compressGif)
for (img in imgs) {
if (subscription?.isDisposed == true) return@ObservableOnSubscribe
val file=File(img)
val requestBody = FileRequestBody(file, object : RetrofitCallback<ResponseBody>() {
override fun onProgress(total: Long, progress: Long) {
}
})
val part = MultipartBody.Part.createFormData("Filedata", getFileName(file), requestBody)
RetrofitManager.getInstance(HaloApp.getInstance().application)
.uploadApi.uploadImage(part, type.name)
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
if (subscription?.isDisposed == true) return
val string = data.string()
if (!string.isNullOrEmpty()) {
val url = JSONObject(string).getString("url")
if (!url.isNullOrEmpty()) {
val map = LinkedHashMap<String, String>()
map[file.path] = url
it.onNext(map)
return
}
}
onFailure(IllegalAccessException("HeHe"))
}
override fun onFailure(exception: Exception) {
// 若遇到错误且 subscription?.isDisposed 为 true 时会抛出 io.reactivex.exceptions.UndeliverableException 异常
// if (subscription?.isDisposed == true) return
// it.onError(exception) // fuck
it.onNext(Collections.emptyMap())
}
})
}
it.onComplete()
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<Map<String, String>?> {
override fun onSubscribe(d: Disposable) {
subscription = d
}
override fun onComplete() {
listener.onFinish()
}
override fun onNext(t: Map<String, String>) {
if (t.isNotEmpty()) {
listener.onSuccess(t)
}
}
override fun onError(e: Throwable) {
listener.onError()
e.printStackTrace()
}
})
return subscription
}
// 同步调用->避免在主线程调用以免阻塞主线程
private fun compressImageList(imgs: List<String>, compressGif: Boolean): List<File> {
val compressList: MutableList<File> = ArrayList()
@ -215,4 +288,9 @@ object UploadImageUtils {
fun onError() // 全部上传失败时回调
fun onProgress(total: Long, progress: Long)
}
interface OnUploadImageListCountListener{
fun onSuccess(map:Map<String, String>)//上传成功一个回调
fun onFinish()//全部上传成功回调
fun onError() // 全部上传失败时回调
}
}

View File

@ -0,0 +1,16 @@
package com.gh.common.view
import android.graphics.Color
import android.graphics.drawable.PaintDrawable
import android.view.View
import android.widget.PopupWindow
class BugFixedPopupWindow @JvmOverloads constructor(contentView: View? = null, width: Int = 0, height: Int = 0)
: PopupWindow(contentView, width, height) {
init {
// 若不设置这个可能在一些旧设备(小于6.0)上无法无法通过返回键和点击外部关闭
setBackgroundDrawable(PaintDrawable(Color.TRANSPARENT))
}
}

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

@ -0,0 +1,147 @@
package com.gh.common.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
public class CircleProgressBar extends View {
private int height;
private int width;
private Paint mPaint;
private int strokeWidth = 5;//线条宽度
private RectF rectF;
private int normalColor = Color.parseColor("#999999");//普通的颜色
private int progressColor = Color.parseColor("#2496FF");//已经走了的进度条颜色
private int textColor = Color.parseColor("#1F89EC");//文字颜色
private int disableNormalColor = Color.parseColor("#80999999");//禁用普通的颜色
private int disableProgressColor = Color.parseColor("#999999");//禁用已经走了的进度条颜色
private int disableTextColor = Color.parseColor("#999999");//禁用文字颜色
private int currentNormalColor = normalColor;
private int currentProgressColor = progressColor;
private int currentTextColor = textColor;
private float textSize = 20;//文字大小
private int progress = 0;//进度条
private String centerText = "0%";//中心填充文字
private Paint fontPaint = null;
private Paint.Style progress_style = Paint.Style.STROKE;//填充式还是环形式
public CircleProgressBar(Context context) {
this(context, null);
}
public CircleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
textSize = array.getDimension(R.styleable.CircleProgressBar_text_size, textSize);
centerText = array.getString(R.styleable.CircleProgressBar_text) == null ? centerText : array.getString(R.styleable.CircleProgressBar_text);
strokeWidth = DisplayUtils.dip2px(array.getInteger(R.styleable.CircleProgressBar_stroke_width, strokeWidth));
textColor = array.getColor(R.styleable.CircleProgressBar_text_color, textColor);
normalColor = array.getColor(R.styleable.CircleProgressBar_normal_color, normalColor);
progressColor = array.getColor(R.styleable.CircleProgressBar_progress_color, progressColor);
disableTextColor = array.getColor(R.styleable.CircleProgressBar_disable_text_color, disableTextColor);
disableNormalColor = array.getColor(R.styleable.CircleProgressBar_disable_normal_color, disableNormalColor);
disableProgressColor = array.getColor(R.styleable.CircleProgressBar_disable_progress_color, disableProgressColor);
progress = array.getInt(R.styleable.CircleProgressBar_progress, progress);
progress_style = array.getInt(R.styleable.CircleProgressBar_progress_style, 0) == 0 ? Paint.Style.STROKE : Paint.Style.FILL;
array.recycle();
initPaint();
}
// 2.初始化画笔
private void initPaint() {
mPaint = new Paint();
mPaint.setColor(currentNormalColor); //设置画笔颜色
mPaint.setAntiAlias(true);
mPaint.setStyle(progress_style); //设置画笔模式为描边
mPaint.setStrokeWidth(strokeWidth); //设置画笔宽度为10px
fontPaint = new Paint();
fontPaint.setTextSize(textSize);
fontPaint.setAntiAlias(true);
fontPaint.setColor(currentTextColor);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
height = MeasureSpec.getSize(heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
if (height > width)//高大于宽的情况
{
rectF = new RectF(strokeWidth, (height / 2 - width / 2) + strokeWidth, width - strokeWidth, (height / 2 + width / 2) - strokeWidth);
} else if (width > height)//宽大于高的情况
{
rectF = new RectF((width / 2 - height / 2) + strokeWidth, strokeWidth, (width / 2 + height / 2) - strokeWidth, height - strokeWidth);
} else//宽等于高的情况
{
rectF = new RectF(strokeWidth, strokeWidth, width - strokeWidth, height - strokeWidth);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Paint.FontMetrics fontMetrics = null;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(currentNormalColor);
if (progress < 360) {
canvas.drawArc(rectF, 270 + progress, 360 - progress, progress_style == Paint.Style.FILL, mPaint);
}
mPaint.setColor(currentProgressColor);
canvas.drawArc(rectF, 270, progress, progress_style == Paint.Style.FILL, mPaint);
fontMetrics = fontPaint.getFontMetrics();
float textWidth = fontPaint.measureText(centerText);
float textHeight = fontPaint.ascent() + fontPaint.descent();
canvas.drawText(centerText, width / 2 - textWidth / 2, height / 2 - textHeight / 2, fontPaint);
}
/**
* 更新界面
*
* @param progress
* @param text
*/
public void update(int progress, String text) {
this.progress = progress;
this.centerText = text;
postInvalidate();
}
/**
* 是否禁用
*
* @param isDisable
*/
public void isDisable(boolean isDisable) {
currentNormalColor = isDisable ? disableNormalColor : normalColor;
currentProgressColor = isDisable ? disableProgressColor : progressColor;
currentTextColor = isDisable ? disableTextColor : textColor;
fontPaint.setColor(currentTextColor);
postInvalidate();
}
}

View File

@ -8,28 +8,39 @@ import android.view.ViewParent;
import android.widget.TextView;
public class CustomLinkMovementMethod extends LinkMovementMethod {
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
boolean b = super.onTouchEvent(widget, buffer, event);
//解决点击事件冲突问题
if (!b && event.getAction() == MotionEvent.ACTION_UP) {
ViewParent parent = widget.getParent();//处理widget的父控件点击事件
if (parent instanceof ViewGroup) {
ViewParent parent = iterateViewParentForClicking(widget.getParent());//处理widget的父控件点击事件
if (parent != null && parent instanceof ViewGroup) {
return ((ViewGroup) parent).performClick();
}
}
return b;
}
private ViewParent iterateViewParentForClicking(ViewParent parent) {
if (parent instanceof ViewGroup) {
if (((ViewGroup) parent).hasOnClickListeners()) {
return parent;
} else {
return iterateViewParentForClicking(parent.getParent());
}
}
return null;
}
public static CustomLinkMovementMethod getInstance() {
if (sInstance == null)
sInstance = new CustomLinkMovementMethod();
if (sInstance == null) sInstance = new CustomLinkMovementMethod();
return sInstance;
}
private static CustomLinkMovementMethod sInstance;
}

View File

@ -22,14 +22,16 @@ 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,
NONE,
NONE_WITH_HINT,
PLUGIN,
LAUNCH_OR_OPEN,
INSTALL_NORMAL,
@ -53,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) {
@ -65,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);
@ -102,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);
@ -119,16 +130,40 @@ 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) {
switch (downloadType) {
case NORMAL:
case NONE_WITH_HINT:
case INSTALL_NORMAL:
switch (mDownloadStyle) {
case DOWNLOAD_RECT_STYLE:
@ -183,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

@ -1,5 +1,6 @@
package com.gh.common.view
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
@ -7,6 +8,18 @@ import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import com.gh.common.util.DisplayUtils
import com.halo.assistant.HaloApp
import android.graphics.drawable.StateListDrawable
import android.widget.TextView
import androidx.annotation.DrawableRes
import com.gh.common.util.dip2px
import com.j256.ormlite.stmt.query.In
import android.graphics.Shader
import android.graphics.LinearGradient
import android.graphics.drawable.shapes.RectShape
import android.graphics.drawable.ShapeDrawable
import android.opengl.ETC1.getHeight
import com.gh.gamecenter.R
import com.lightgame.utils.Utils
object DrawableView {
@ -16,7 +29,6 @@ object DrawableView {
return getServerDrawable(ContextCompat.getColor(HaloApp.getInstance().application, colorId))
}
@JvmStatic
fun getServerDrawable(colorCode: String): Drawable {
return getServerDrawable(Color.parseColor(colorCode))
@ -31,10 +43,62 @@ object DrawableView {
}
@JvmStatic
fun getOvalDrawable(@ColorRes colorId: Int): Drawable {
fun getOvalDrawable(@ColorRes colorId: Int, radius: Float = 999F): Drawable {
val drawable = GradientDrawable()
drawable.setColor(ContextCompat.getColor(HaloApp.getInstance().application, colorId))
drawable.cornerRadius = DisplayUtils.dip2px(999F).toFloat()
drawable.cornerRadius = DisplayUtils.dip2px(radius).toFloat()
return drawable
}
@JvmStatic
fun getOvalSelectorStyle(@ColorRes defaultColorId: Int, @ColorRes checkColorId: Int): StateListDrawable {
val res = StateListDrawable()
res.addState(intArrayOf(android.R.attr.state_checked), getOvalDrawable(checkColorId))
res.addState(intArrayOf(), getOvalDrawable(defaultColorId))
return res
}
@JvmStatic
fun getSelectorColorStyle(@ColorRes defaultColorId: Int, @ColorRes checkColorId: Int): ColorStateList {
val states = arrayOf(
intArrayOf(-android.R.attr.state_checked),
intArrayOf(android.R.attr.state_checked))
val colors = intArrayOf(
ContextCompat.getColor(HaloApp.getInstance().application, defaultColorId),
ContextCompat.getColor(HaloApp.getInstance().application, checkColorId))
return ColorStateList(states, colors)
}
@JvmStatic
fun getStrokeDrawable(@ColorRes colorCode: Int, strokeWidth: Float = 1F, radius: Float = 999F): Drawable {
val drawable = GradientDrawable()
drawable.setStroke(strokeWidth.dip2px(), ContextCompat.getColor(HaloApp.getInstance().application, colorCode))
drawable.cornerRadius = radius
return drawable
}
@JvmStatic
fun setTextDrawable(textView: TextView, @DrawableRes drawableId: Int?, text: String? = null) {
val drawable = if (drawableId != null) {
ContextCompat.getDrawable(HaloApp.getInstance().application, drawableId)
} else {
null
}
drawable?.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
textView.setCompoundDrawables(drawable, null, null, null)
if (text != null) textView.text = text
}
// 需要跳转角度请自行设置 x0,y0,x1,y1
@JvmStatic
fun getGradientDrawable(width: Int, startColor: Int, endColor: Int): Drawable {
val drawable = ShapeDrawable(RectShape())
drawable.paint.shader = LinearGradient(0f, 0F, width.toFloat(), 0F, startColor, endColor, Shader.TileMode.REPEAT)
return drawable
}
fun convertAlphaKey(percent: Int): String {
val hexString = Integer.toHexString(Math.round((255 * percent / 100).toFloat()))
return (if (hexString.length < 2) "0" else "") + hexString
}
}

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,16 +12,15 @@ 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 CharSequence mCloseText;
private String mExpendText = "...全文";
@ -48,7 +47,6 @@ public class ExpendTextView extends AppCompatTextView {
super.onLayout(changed, left, top, right, bottom);
if (mInitLayout && !mOpenLayout && getLineCount() > mMaxLines) {
mSnapshotText = getText();
mCloseText = getText();
mInitLayout = false;
showExpendButton();
}
@ -93,39 +91,31 @@ public class ExpendTextView extends AppCompatTextView {
}
}
}
SpannableStringBuilder msp = new SpannableStringBuilder(mCloseText);
SpannableStringBuilder msp = new SpannableStringBuilder(mSnapshotText);
int length = msp.length();
int startPosition = content.length() - mExpendText.length();
startPosition = startPosition < 0 ? 0 : startPosition;
msp.replace(startPosition, length, mExpendText);
msp.setSpan(
new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme));
ds.setUnderlineText(false);
}
msp.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
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);
@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);
msp.setSpan(
new BackgroundColorSpan(Color.WHITE),
startPosition,
msp.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (mExpandCallback != null) {
mExpandCallback.onExpand();
}
}
}, 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());

View File

@ -0,0 +1,30 @@
package com.gh.common.view;
import android.content.Context;
import android.util.AttributeSet;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class FixLinearLayoutManager extends LinearLayoutManager {
public FixLinearLayoutManager(Context context) {
super(context);
}
public FixLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public FixLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (Exception ignore) {
}
}
}

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,47 @@
package com.gh.common.view
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class GridSpacingItemDecoration(private val mSpanCount: Int,
private val mSpacing: Int,
private val mIncludeEdge: Boolean) : RecyclerView.ItemDecoration() {
private var mTopDecoration = 0
constructor(spanCount: Int,
spacing: Int,
includeEdge: Boolean,
topDecoration: Int) : this(spanCount, spacing, includeEdge) {
this.mTopDecoration = topDecoration
}
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val position = parent.getChildAdapterPosition(view)
val column = position % mSpanCount
if (mIncludeEdge) {
outRect.left = mSpacing - column * mSpacing / mSpanCount
outRect.right = (column + 1) * mSpacing / mSpanCount
if (position < mSpanCount) {
outRect.top = mSpacing
}
outRect.bottom = mSpacing
} else {
outRect.left = column * mSpacing / mSpanCount
outRect.right = mSpacing - (column + 1) * mSpacing / mSpanCount
if (position >= mSpanCount) {
outRect.top = mSpacing
}
}
if (mTopDecoration != 0 && position < mSpanCount) {
outRect.top = outRect.top + mTopDecoration
}
}
}

View File

@ -0,0 +1,33 @@
package com.gh.common.view
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.widget.TextView
import com.gh.common.util.SimpleCallback
import com.gh.common.util.TextHelper
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
/**
* 默认用 ###高亮内容### 格式来高亮文字并添加点击复制至剪贴板功能的 TextView
*/
class HighlightableTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : TextView(context, attrs) {
init {
movementMethod = CustomLinkMovementMethod.getInstance()
highlightColor = Color.TRANSPARENT
}
override fun setText(text: CharSequence?, type: BufferType?) {
super.setText(TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(context, text.toString(), "###", R.color.theme, object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = arg
Utils.toast(application, "已复制:$arg")
}
}), BufferType.SPANNABLE)
}
}

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,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.RelativeLayout
class MaterializedRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
: RelativeLayout(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,61 @@
package com.gh.common.view
import android.app.Activity
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.View
import android.view.ViewConfiguration
/**
* 导航栏占位 View
*/
class NavigationBarView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val height = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
0
} else {
retrieveNavigationHeight()
}
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height)
}
// TODO 将这部分移到通用方法去
private fun hasSoftKeys(): Boolean {
if (context !is Activity) return false
val hasSoftwareKeys: Boolean
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val d = (context as Activity).windowManager.defaultDisplay
val realDisplayMetrics = DisplayMetrics()
d.getRealMetrics(realDisplayMetrics)
val realHeight = realDisplayMetrics.heightPixels
val realWidth = realDisplayMetrics.widthPixels
val displayMetrics = DisplayMetrics()
d.getMetrics(displayMetrics)
val displayHeight = displayMetrics.heightPixels
val displayWidth = displayMetrics.widthPixels
hasSoftwareKeys = realWidth - displayWidth > 0 || realHeight - displayHeight > 0
} else {
val hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey()
val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)
hasSoftwareKeys = !hasMenuKey && !hasBackKey
}
return hasSoftwareKeys
}
private fun retrieveNavigationHeight(): Int {
val resources = context.resources
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return if (resourceId > 0 && hasSoftKeys()) resources.getDimensionPixelSize(resourceId) else 0
}
}

View File

@ -1,294 +0,0 @@
package com.gh.common.view
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
import android.os.Handler
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import cn.jzvd.*
import com.gh.common.observer.MuteCallback
import com.gh.common.observer.VolumeObserver
import com.gh.common.util.DialogUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.NetworkUtils
import com.gh.gamecenter.R
import com.halo.assistant.HaloApp
import java.util.*
class PlayerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : JzvdStd(context, attrs) {
var showAlertDialogForTheFistTime: Boolean = true
var gameName: String = ""
lateinit var muteIv: ImageView
lateinit var rotateIv: ImageView
val muteCallback = object : MuteCallback {
override fun onMute(isMute: Boolean) {
if (isMute) {
muteIv.setImageResource(R.drawable.ic_volume_off)
} else {
muteIv.setImageResource(R.drawable.ic_volume_on)
}
}
}
var volumeObserver = VolumeObserver(context, Handler(), muteCallback)
override fun init(context: Context?) {
super.init(context)
muteIv = findViewById(R.id.mute)
rotateIv = findViewById(R.id.rotate)
muteIv.setOnClickListener(this)
rotateIv.setOnClickListener(this)
Jzvd.WIFI_TIP_DIALOG_SHOWED = true
}
override fun onClick(v: View) {
if (v.id == R.id.start || v.id == R.id.thumb) {
if (Jzvd.CURRENT_STATE_PLAYING != currentState) {
if ((currentScreen == SCREEN_WINDOW_NORMAL || currentScreen == SCREEN_WINDOW_LIST)) {
MtaHelper.onEvent("游戏详情_新", "视频_点击播放", gameName)
} else {
MtaHelper.onEvent("游戏详情_新", "视频全屏_点击播放", gameName)
}
} else {
MtaHelper.onEvent("游戏详情_新", "视频_点击暂停", gameName)
}
if (showAlertDialogForTheFistTime
&& !NetworkUtils.isWifiConnected(context)
&& currentState != Jzvd.CURRENT_STATE_PLAYING) {
showNetworkAlertDialog()
} else {
super.onClick(v)
}
} else {
super.onClick(v)
when (v.id) {
R.id.rotate -> {
if (Jzvd.FULLSCREEN_ORIENTATION != SCREEN_ORIENTATION_LANDSCAPE) {
Jzvd.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
JZUtils.setRequestedOrientation(context, Jzvd.FULLSCREEN_ORIENTATION)
} else {
Jzvd.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
JZUtils.setRequestedOrientation(context, Jzvd.FULLSCREEN_ORIENTATION)
}
MtaHelper.onEvent("游戏详情_新", "视频全屏_点击旋转", gameName)
}
R.id.mute -> {
toggleMute()
}
}
}
}
override fun getLayoutId(): Int {
return R.layout.player_view
}
private fun toggleMute() {
HaloApp.getInstance().isMute = !HaloApp.getInstance().isMute
updateMuteStatus()
}
private fun updateMuteStatus() {
if (HaloApp.getInstance().isMute) {
mute()
} else {
unmute()
}
}
private fun showNetworkAlertDialog() {
DialogUtils.showAlertDialog(context,
"播放视频",
"您当前使用的网络为2G/3G/4G播放视频将会消耗移动流量确定播放",
"确定",
"取消",
DialogUtils.ConfirmListener {
showAlertDialogForTheFistTime = false
startButton.performClick()
},
null
).show()
}
private fun mute() {
muteIv.setImageResource(R.drawable.ic_volume_off)
try {
JZMediaManager.instance()?.jzMediaInterface?.setVolume(0f, 0f)
} catch (e: Exception) {
e.printStackTrace()
}
MtaHelper.onEvent("游戏详情_新", "视频_点击静音", gameName)
}
private fun unmute() {
muteIv.setImageResource(R.drawable.ic_volume_on)
try {
JZMediaManager.instance()?.jzMediaInterface?.setVolume(1.0f, 1.0f)
} catch (e: Exception) {
e.printStackTrace()
}
MtaHelper.onEvent("游戏详情_新", "视频_解除静音", gameName)
}
override fun onStatePlaying() {
super.onStatePlaying()
// 默认加载完显示播放信息
if (currentScreen != Jzvd.SCREEN_WINDOW_FULLSCREEN) {
changeUiToPlayingShow()
}
}
override fun onStatePrepared() {
super.onStatePrepared()
updateMuteStatus()
}
override fun onClickUiToggle() {
// 仅在全屏状态下才会 toggle 播放信息
if (currentScreen == Jzvd.SCREEN_WINDOW_FULLSCREEN) {
if (bottomContainer.visibility != View.VISIBLE) {
setSystemTimeAndBattery()
clarity.text = jzDataSource.currentKey.toString()
}
if (currentState == Jzvd.CURRENT_STATE_PREPARING) {
changeUiToPreparing()
if (bottomContainer.visibility == View.VISIBLE) {
} else {
setSystemTimeAndBattery()
}
} else if (currentState == Jzvd.CURRENT_STATE_PLAYING) {
if (bottomContainer.visibility == View.VISIBLE) {
changeUiToPlayingClear()
} else {
changeUiToPlayingShow()
}
} else if (currentState == Jzvd.CURRENT_STATE_PAUSE) {
if (bottomContainer.visibility == View.VISIBLE) {
changeUiToPauseClear()
} else {
changeUiToPauseShow()
}
}
} else {
// 小界面播放中或者准备中的时候点击直接进入全屏
when (currentState) {
Jzvd.CURRENT_STATE_PLAYING,
Jzvd.CURRENT_STATE_PREPARING -> {
startWindowFullscreen()
}
}
}
}
override fun setUp(jzDataSource: JZDataSource?, screen: Int) {
super.setUp(jzDataSource, screen)
batteryTimeLayout.visibility = View.INVISIBLE
// 初始化隐藏和置换一些原有资源
if (currentScreen == SCREEN_WINDOW_NORMAL || currentScreen == SCREEN_WINDOW_LIST) {
progressBar.visibility = View.INVISIBLE
totalTimeTextView.visibility = View.INVISIBLE
muteIv.visibility = View.VISIBLE
rotateIv.visibility = View.GONE
// 将右下角的按钮变成静音与否
updateMuteStatus()
} else {
progressBar.visibility = View.VISIBLE
totalTimeTextView.visibility = View.VISIBLE
muteIv.visibility = View.GONE
rotateIv.visibility = View.VISIBLE
}
}
override fun updateStartImage() {
when (currentState) {
Jzvd.CURRENT_STATE_PLAYING -> {
if (currentScreen == SCREEN_WINDOW_NORMAL || currentScreen == SCREEN_WINDOW_LIST) {
startButton.visibility = View.INVISIBLE
} else {
startButton.visibility = View.VISIBLE
startButton.setImageResource(cn.jzvd.R.drawable.jz_click_pause_selector)
replayTextView.visibility = View.INVISIBLE
}
}
Jzvd.CURRENT_STATE_ERROR -> {
startButton.visibility = View.INVISIBLE
replayTextView.visibility = View.INVISIBLE
}
Jzvd.CURRENT_STATE_AUTO_COMPLETE -> {
startButton.visibility = View.VISIBLE
startButton.setImageResource(cn.jzvd.R.drawable.jz_click_replay_selector)
replayTextView.visibility = View.VISIBLE
}
else -> {
startButton.setImageResource(cn.jzvd.R.drawable.jz_click_play_selector)
replayTextView.visibility = View.INVISIBLE
}
}
}
override fun playOnThisJzvd() {
super.playOnThisJzvd()
if (HaloApp.getInstance().isMute) {
mute()
}
// 处理从全屏跳转回小界面
Jzvd.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
if (currentScreen == SCREEN_WINDOW_NORMAL || currentScreen == SCREEN_WINDOW_LIST) {
progressBar.visibility = View.INVISIBLE
totalTimeTextView.visibility = View.INVISIBLE
MtaHelper.onEvent("游戏详情_新", "视频全屏_点击后退", gameName)
} else {
progressBar.visibility = View.VISIBLE
totalTimeTextView.visibility = View.VISIBLE
}
}
override fun startWindowFullscreen() {
super.startWindowFullscreen()
unmute()
MtaHelper.onEvent("游戏详情_新", "视频_点击进入全屏", gameName)
}
override fun startDismissControlViewTimer() {
// 仅在全屏是才自动隐藏播放信息
cancelDismissControlViewTimer()
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
DISMISS_CONTROL_VIEW_TIMER = Timer()
mDismissControlViewTimerTask = DismissControlViewTimerTask()
DISMISS_CONTROL_VIEW_TIMER.schedule(mDismissControlViewTimerTask, 3000)
}
}
fun observeVolume(fragment: androidx.fragment.app.Fragment?) {
fragment?.context?.applicationContext?.contentResolver?.registerContentObserver(
android.provider.Settings.System.CONTENT_URI, true, volumeObserver)
fragment?.fragmentManager?.registerFragmentLifecycleCallbacks(
object : androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentPaused(fm: FragmentManager, f: Fragment) {
if (f === fragment) {
fragment.context?.applicationContext?.contentResolver?.unregisterContentObserver(volumeObserver)
fragment.fragmentManager?.unregisterFragmentLifecycleCallbacks(this)
}
}
}, false)
}
}

View File

@ -1,254 +0,0 @@
package com.gh.common.view;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import java.util.ArrayList;
import java.util.List;
/**
* Created by khy on 2017/2/16.
* 快传接收方 的雷达动画
*/
public class RadarLayout extends FrameLayout {
public static final int INFINITE = 0;
private static final int DEFAULT_COUNT = 4;
private static final int DEFAULT_COLOR = Color.rgb(0, 116, 193);
private static final int DEFAULT_DURATION = 7000;
private static final int DEFAULT_REPEAT = INFINITE;
private static final int DEFAULT_STROKE_WIDTH = 2;
private int mCount;
private int mDuration;
private int mRepeat;
private AnimatorSet mAnimatorSet;
private Paint mPaint;
private int mColor;
private float mRadius;
private float mCenterX;
private float mCenterY;
private int mStrokeWidth;
private boolean mIsStarted;
private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
mIsStarted = true;
}
@Override
public void onAnimationEnd(Animator animator) {
mIsStarted = false;
}
@Override
public void onAnimationCancel(Animator animator) {
mIsStarted = false;
}
@Override
public void onAnimationRepeat(Animator animator) {
}
};
private boolean mUseRing;
public RadarLayout(Context context) {
super(context);
initGlobalparams();
}
private void initGlobalparams() {
mColor = DEFAULT_COLOR;
mCount = DEFAULT_COUNT;
mDuration = DEFAULT_DURATION;
mRepeat = DEFAULT_REPEAT;
mUseRing = false;
mStrokeWidth = dip2px(DEFAULT_STROKE_WIDTH);
build();
}
private int dip2px(float dpValue) {
final float scale = getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
private void build() {
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
int repeatCount = (mRepeat == INFINITE) ? ObjectAnimator.INFINITE : mRepeat;
List animators = new ArrayList();
for (int index = 0; index < mCount; index++) {
RadarView radarView = new RadarView(getContext());
radarView.setScaleX(0);
radarView.setScaleY(0);
radarView.setAlpha(1);
addView(radarView, index, params);
// 计算时间间隔
long delay = index * mDuration / mCount;
// 属性动画
animators.add(create(radarView, "scaleX", repeatCount, delay, 0, 1));
animators.add(create(radarView, "scaleY", repeatCount, delay, 0, 1));
animators.add(create(radarView, "alpha", repeatCount, delay, 1, 0));
}
mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(animators);
mAnimatorSet.setInterpolator(new LinearInterpolator());
mAnimatorSet.setDuration(mDuration);
mAnimatorSet.addListener(mAnimatorListener);
}
private ObjectAnimator create(View target, String propertyName, int repeatCount, long delay, float from, float to) {
ObjectAnimator animator = ObjectAnimator.ofFloat(target, propertyName, from, to);
animator.setRepeatCount(repeatCount);
animator.setRepeatMode(ObjectAnimator.RESTART);
animator.setStartDelay(delay);
return animator;
}
public RadarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initGlobalparams();
}
public RadarLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initGlobalparams();
}
public int getCount() {
return mCount;
}
public void setCount(int count) {
if (count < 0) {
throw new IllegalArgumentException("Count cannot be negative");
}
if (count != mCount) {
mCount = count;
reset();
invalidate();
}
}
private void reset() {
boolean isStarted = isStarted();
clear();
build();
if (isStarted) {
start();
}
}
public synchronized boolean isStarted() {
return (mAnimatorSet != null && mIsStarted);
}
private void clear() {
stop();
removeAllViews();
}
public synchronized void start() {
if (mAnimatorSet == null || mIsStarted) {
return;
}
mAnimatorSet.start();
}
public synchronized void stop() {
if (mAnimatorSet == null || !mIsStarted) {
return;
}
mAnimatorSet.end();
}
public int getDuration() {
return mDuration;
}
public void setDuration(int millis) {
if (millis < 0) {
throw new IllegalArgumentException("Duration cannot be negative");
}
if (millis != mDuration) {
mDuration = millis;
reset();
invalidate();
}
}
public void setColor(int color) {
if (mColor != color) {
mColor = color;
reset();
invalidate();
}
}
public void setUseRing(boolean useRing) {
if (mUseRing != useRing) {
mUseRing = useRing;
reset();
invalidate();
}
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
// 确定圆的圆点坐标及半径
mCenterX = width * 0.5f;
mCenterY = height * 0.5f;
mRadius = Math.min(width, height) * 0.5f;
}
private class RadarView extends View {
public RadarView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
if (null == mPaint) {
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setAntiAlias(true);
// 注意Style的用法【STROKE画环】【FILL画圆】
mPaint.setStyle(mUseRing ? Paint.Style.STROKE : Paint.Style.FILL);
mPaint.setStrokeWidth(mUseRing ? mStrokeWidth : 0);
}
// 画圆或环
canvas.drawCircle(mCenterX, mCenterY, mUseRing ? mRadius - mStrokeWidth : mRadius, mPaint);
}
}
}

View File

@ -1,163 +0,0 @@
package com.gh.common.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.gh.gamecenter.R;
/**
* Created by khy on 22/06/17.
*
* 光环快传-扫描雷达动画
*/
public class RadarView extends View {
private Context mContext;
private boolean isSearching = false;// 标识是否处于扫描状态,默认为不在扫描状态
private Paint mPaint;// 画笔
private Bitmap mScanBmp;// 执行扫描运动的图片
private int mOffsetArgs = 0;// 扫描运动偏移量参数
private int mWidth, mHeight;// 宽高
int mCx, mCy;// x、y轴中心点
int mOutsideRadius, mInsideRadius;// 外、内圆半径
public RadarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public RadarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public RadarView(Context context) {
super(context);
init(context);
}
/**
* 提前初始化好需要使用的对象,避免在绘制过程中多次初始化
*
* @return void
*/
private void init(Context context) {
mPaint = new Paint();
this.mContext = context;
}
/**
* 测量视图及其内容,以确定所测量的宽度和高度(测量获取控件尺寸).
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获取控件区域宽高
if (mWidth == 0 || mHeight == 0) {
final int minimumWidth = getSuggestedMinimumWidth();
final int minimumHeight = getSuggestedMinimumHeight();
mWidth = resolveMeasured(widthMeasureSpec, minimumWidth);
mHeight = resolveMeasured(heightMeasureSpec, minimumHeight);
mScanBmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.radar_scan_img), mWidth, mWidth, false);
// 获取x/y轴中心点
mCx = mWidth / 2;
mCy = mHeight / 2;
// 计算内、外半径
mOutsideRadius = mWidth / 2;// 外圆的半径
mInsideRadius = mWidth / 4 / 2;// 内圆的半径,除最外层,其它圆的半径=层数*insideRadius
}
}
/**
* 绘制视图--从外部向内部绘制
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 开始绘制最外层的圆
mPaint.setAntiAlias(true);// 设置抗锯齿
mPaint.setStyle(Paint.Style.FILL);// 设置填充样式
mPaint.setColor(0xff327BD7);// 设置画笔颜色
// 1.开始绘制圆形
canvas.drawCircle(mCx, mCy, mOutsideRadius, mPaint);
// 开始绘制内3圆
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.WHITE);
canvas.drawCircle(mCx, mCy, mInsideRadius * 3, mPaint);
// 开始绘制内2圆
canvas.drawCircle(mCx, mCy, mInsideRadius * 2, mPaint);
// 开始绘制内1圆
canvas.drawCircle(mCx, mCy, mInsideRadius * 1, mPaint);
// 2.开始绘制对角线
canvas.drawLine(0, mCy, mWidth, mCy, mPaint);// 绘制0°~180°对角线
canvas.drawLine(mCx, mHeight , mCx, 0,
mPaint);// 绘制90°~270°对角线
// 3.绘制扫描扇形图
canvas.save();// 用来保存Canvas的状态.save之后可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作.
if (isSearching) {// 判断是否处于扫描
canvas.rotate(mOffsetArgs, mCx, mCy);// 绘制旋转角度,参数一:角度;参数二x中心;参数三y中心.
canvas.drawBitmap(mScanBmp, mCx - mScanBmp.getWidth() / 2, mCy
- mScanBmp.getHeight() / 2, null);// 绘制Bitmap扫描图片效果
mOffsetArgs += 3;
} else {
canvas.drawBitmap(mScanBmp, mCx - mScanBmp.getWidth() / 2, mCy
- mScanBmp.getHeight() / 2, null);
}
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.WHITE);
canvas.drawCircle(mCx, mCy, mInsideRadius/4, mPaint);
if (isSearching)
this.invalidate();
}
/**
* 设置扫描状态
*
* @return void
*/
public void setSearching(boolean status) {
this.isSearching = status;
this.invalidate();
}
/**
* 解析获取控件宽高
*
* @return int
*/
private int resolveMeasured(int measureSpec, int desired) {
int result = 0;
int specSize = MeasureSpec.getSize(measureSpec);
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.UNSPECIFIED:
result = desired;
break;
case MeasureSpec.AT_MOST:
result = Math.min(specSize, desired);
break;
case MeasureSpec.EXACTLY:
default:
result = specSize;
}
return result;
}
}

View File

@ -22,9 +22,12 @@ import com.gh.common.util.ImageUtils;
import com.gh.common.util.NetworkUtils;
import com.gh.common.util.RichEditorUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.MyVideoEntity;
import com.gh.gamecenter.qa.entity.EditorInsertEntity;
import com.halo.assistant.HaloApp;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@ -123,7 +126,7 @@ public class RichEditor extends WebView {
public RichEditor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
addJavascriptInterface(new NativeCallBack(), NativeCallBack.class.getSimpleName());
addJavascriptInterface(new NativeCallBack(), "NativeCallBack");
setVerticalScrollBarEnabled(false);
setHorizontalScrollBarEnabled(false);
@ -265,6 +268,28 @@ public class RichEditor extends WebView {
exec("javascript:RE.insertCustomStyleLink('" + GsonUtils.toJson(entity) + "');");
}
public void insertCustomVideo(MyVideoEntity entity) {
try {
JSONObject object = new JSONObject();
object.put("poster", entity.getPoster());
object.put("url", entity.getUrl());
object.put("duration", formatDuration(entity.getLength()));
object.put("id", entity.getId());
exec("javascript:RE.insertCustomVideo('" + object.toString() + "');");
} catch (Exception e) {
e.printStackTrace();
}
}
private String formatDuration(long seconds) {
long absSeconds = Math.abs(seconds);
@SuppressLint("DefaultLocale") String positive = String.format(
"%02d:%02d",
absSeconds / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
public void hideLinkStyle() {
exec("javascript:RE.hideLinkStyle();");
}
@ -558,9 +583,8 @@ public class RichEditor extends WebView {
class NativeCallBack {
@SuppressLint("JavascriptInterface")
@JavascriptInterface
boolean isNativeBuildDebug() {
public boolean isNativeBuildDebug() {
return "internal".equals(BuildConfig.FLAVOR);
}
}

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

@ -0,0 +1,18 @@
package com.gh.common.view
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.View
import com.gh.common.util.DisplayUtils
class StatusBarView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val height = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
0
} else {
DisplayUtils.getStatusBarHeight(resources)
}
setMeasuredDimension(View.MeasureSpec.getSize(widthMeasureSpec), height)
}
}

View File

@ -1,88 +1,99 @@
package com.gh.common.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import com.google.android.material.tabs.TabLayout;
import androidx.core.view.ViewCompat;
import androidx.viewpager.widget.ViewPager;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
import com.google.android.material.tabs.TabLayout;
import androidx.core.view.ViewCompat;
import androidx.viewpager.widget.ViewPager;
/**
* Created by khy on 2/12/17.
*/
public class TabIndicatorView extends View implements ViewPager.OnPageChangeListener {
private TabLayout mTabLayout;
private int mIndicatorSpace;
private int mIndicatorHeight;
private int mIndicatorWidth;
private int mIndicatorColor = 0;
private GradientDrawable mGradientDrawable;
public TabIndicatorView(Context context) {
this(context, null);
}
public TabIndicatorView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TabIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabIndicatorView);
if (a.hasValue(R.styleable.TabIndicatorView_indicatorColor)) {
mIndicatorColor = a.getColor(R.styleable.TabIndicatorView_indicatorColor, 0);
mGradientDrawable = new GradientDrawable();
mGradientDrawable.setShape(GradientDrawable.RECTANGLE);
mGradientDrawable.setColor(mIndicatorColor);
mGradientDrawable.setCornerRadius(Integer.MAX_VALUE);
}
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mIndicatorHeight = MeasureSpec.getSize(heightMeasureSpec);
}
public void setupWithTabLayout(final TabLayout tableLayout) {
mTabLayout = tableLayout;
tableLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
tableLayout.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
if (mTabLayout.getScrollX() != getScrollX())
scrollTo(mTabLayout.getScrollX(), mTabLayout.getScrollY());
}
tableLayout.getViewTreeObserver().addOnScrollChangedListener(() -> {
if (mTabLayout.getScrollX() != getScrollX())
scrollTo(mTabLayout.getScrollX(), mTabLayout.getScrollY());
});
ViewCompat.setElevation(this, ViewCompat.getElevation(mTabLayout));
//清除Tab background
for (int tab = 0; tab < tableLayout.getTabCount(); tab++) {
View tabView = getTabViewByPosition(tab);
if (tabView != null) tabView.setBackgroundResource(0);
}
}
public void setupWithViewPager(ViewPager viewPager) {
viewPager.addOnPageChangeListener(this);
}
public void setIndicatorWidth(int width) {
if (width > 0) this.mIndicatorWidth = DisplayUtils.dip2px(getContext(), width);
}
public void setIndicatorSpace(int space) {
this.mIndicatorSpace = DisplayUtils.dip2px(getContext(), space);
}
private int getIndicatorSpace() {
if (mIndicatorSpace != 0) return mIndicatorSpace;
if (mIndicatorWidth != 0) {
@ -91,88 +102,91 @@ public class TabIndicatorView extends View implements ViewPager.OnPageChangeList
}
return 0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Drawable drawable = getResources().getDrawable(R.drawable.ask_tab_indicator_bg); // 固定Indicator背景 有需要可以自行更改
Drawable drawable;
if (mGradientDrawable != null) {
drawable = mGradientDrawable;
} else {
drawable = getResources().getDrawable(R.drawable.ask_tab_indicator_bg); // 固定Indicator背景 有需要可以自行更改
}
drawable.setBounds(l, t, r, b);
drawable.draw(canvas);
}
int l;
int t;
int r;
int b;
private void generatePath(int position, float positionOffset) {
public void generatePath(int position, float positionOffset) {
RectF range = new RectF();
View tabView = getTabViewByPosition(position);
if (tabView == null)
return;
if (tabView == null) return;
int left, top, right, bottom;
left = top = right = bottom = 0;
if (positionOffset > 0.f && position < mTabLayout.getTabCount() - 1) {
View nextTabView = getTabViewByPosition(position + 1);
if (nextTabView != null) {
left += (int) (nextTabView.getLeft() * positionOffset + tabView.getLeft() * (1.f - positionOffset));
right += (int) (nextTabView.getRight() * positionOffset + tabView.getRight() * (1.f - positionOffset));
}
left += getIndicatorSpace();
right -= getIndicatorSpace();
top = tabView.getTop() + getPaddingTop();
bottom = tabView.getBottom() - getPaddingBottom();
range.set(left, top, right, bottom);
} else {
left = tabView.getLeft() + getIndicatorSpace();
right = tabView.getRight() - getIndicatorSpace();
top = tabView.getTop() + getPaddingTop();
bottom = tabView.getBottom() - getPaddingBottom();
range.set(left, top, right, bottom);
if (range.isEmpty())
return;
if (range.isEmpty()) return;
}
r = right;
l = left;
t = top;
b = top + mIndicatorHeight;
invalidate();
}
private View getTabViewByPosition(int position) {
if (mTabLayout != null && mTabLayout.getTabCount() > 0) {
ViewGroup tabStrip = (ViewGroup) mTabLayout.getChildAt(0);
return tabStrip != null ? tabStrip.getChildAt(position) : null;
}
return null;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
generatePath(position, positionOffset);
invalidate();
}
@Override
public void onPageSelected(int position) {
if (mTabLayout.getSelectedTabPosition() != position) {
TabLayout.Tab tab = mTabLayout.getTabAt(position);
if (tab != null) tab.select();
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
}

View File

@ -0,0 +1,25 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import androidx.viewpager.widget.ViewPager
class WrapHeightViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var height = 0
for (i in 0 until childCount) {
val child = getChildAt(i)
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
val h = child.measuredHeight
if (h > height) height = h
}
val resultHeightMeasureSpec = if (height != 0) {
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
} else {
heightMeasureSpec
}
super.onMeasure(widthMeasureSpec, resultHeightMeasureSpec)
}
}

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