Compare commits

...

341 Commits

Author SHA1 Message Date
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
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
684 changed files with 25924 additions and 17705 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")
}
}
@ -235,10 +239,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 +255,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 +275,11 @@ 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 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

@ -32,6 +32,14 @@
<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"/>
@ -42,7 +50,6 @@
android:resizeable = "true"
android:smallScreens = "true" />
<!--android:largeHeap = "true"-->
<application
android:name = "com.halo.assistant.TinkerApp"
android:allowBackup = "true"
@ -50,6 +57,7 @@
android:label = "@string/app_name"
android:resizeableActivity = "true"
android:theme = "@style/AppCompatTheme.APP"
android:largeHeap="true"
tools:targetApi = "n" >
<!--android:launchMode = "singleTask"-->
@ -124,30 +132,12 @@
<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" />
@ -217,9 +207,6 @@
android:name = "com.gh.gamecenter.UserInfoEditActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
<activity
android:name = "com.gh.gamecenter.KaiFuActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.qa.search.AskSearchActivity"
@ -286,12 +273,12 @@
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kaifu.add.AddKaiFuActivity"
android:name = "com.gh.gamecenter.servers.add.AddKaiFuActivity"
android:screenOrientation = "portrait"
android:windowSoftInputMode = "stateHidden" />
<activity
android:name = "com.gh.gamecenter.kaifu.patch.PatchKaifuActivity"
android:name = "com.gh.gamecenter.servers.patch.PatchKaifuActivity"
android:screenOrientation = "portrait" />
<activity
@ -315,15 +302,7 @@
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.PersonalHomeActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.answer.PersonalAnswerActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.question.PersonalQuestionActivity"
android:name = "com.gh.gamecenter.personalhome.HomeActivity"
android:screenOrientation = "portrait" />
<activity
@ -379,10 +358,6 @@
android:name = "com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.kuaichuan.view.FileShareActivity"
android:screenOrientation = "portrait" />
<activity
android:name = "com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation = "portrait" />
@ -395,15 +370,52 @@
android:name = "com.gh.gamecenter.tag.TagsActivity"
android:screenOrientation = "portrait" />
<activity android:name = "com.gh.gamecenter.qa.article.SimpleArticleListActivity"
<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"

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);

View File

@ -8,9 +8,6 @@ import android.os.Message;
import android.text.TextUtils;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import com.gh.common.constant.Constants;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
@ -18,6 +15,7 @@ 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;
@ -39,12 +37,13 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import androidx.annotation.NonNull;
import butterknife.ButterKnife;
import pub.devrel.easypermissions.EasyPermissions;
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
public abstract class BaseActivity extends BaseToolBarActivity implements EasyPermissions.PermissionCallbacks {
public abstract class BaseActivity extends BaseToolBarActivity implements EasyPermissions.PermissionCallbacks {
@NonNull
protected String mEntrance;
@ -128,13 +127,11 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
}
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) {
@ -195,33 +192,40 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
@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) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
}
/**
* @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 +236,9 @@ public abstract class BaseActivity extends BaseToolBarActivity implements EasyPe
}
return StringUtils.buildString(entrance, "+(", path, ")");
}
@Override
protected boolean showDownloadMenu() {
return false;
}
}

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
@ -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,38 +1,67 @@
package com.gh.base;
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 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.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.BaseAppCompatActivity;
import com.lightgame.OnTitleClickListener;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
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;
/**
* Created by csheng on 15-10-12.
*/
public abstract class BaseToolBarActivity extends BaseAppCompatActivity implements ToolbarController, Toolbar.OnMenuItemClickListener {
private Toolbar mToolbar;
private TextView mTitleTv;
@Nullable
private PackageViewModel mPackageViewModel;
protected Toolbar mToolbar;
protected TextView mTitleTv;
@Nullable
private TextView mDownloadCountHint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initToolbar();
if (showDownloadMenu()) {
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
mPackageViewModel.getFilterSameUpdateLiveData().observe(this, this::updateDownloadCountHint);
}
}
private void initToolbar() {
@ -41,15 +70,17 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
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();
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();
}
}
}
});
});
}
}
}
@ -81,6 +112,10 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
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);
@ -119,6 +154,39 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
}
}
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; //后续页面做好判断
@ -137,6 +205,12 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_download) {
// todo mEntrance set real value
MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, "");
startActivity(intent);
}
return false;
}
@ -148,7 +222,28 @@ public abstract class BaseToolBarActivity extends BaseAppCompatActivity implemen
}
return super.onOptionsItemSelected(item);
}
/**
* 提供当前 activity 的中文名 (不重载的话为类名)
*/
public String getActivityNameInChinese() {
return getClass().getSimpleName();
}
protected void setStatusBarColor(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(color);
}
}
protected abstract boolean onNavigationIconClicked();
protected View.OnClickListener provideNavigationItemClickListener() {
return view -> onBackPressed();
}
protected abstract boolean showDownloadMenu();
}

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

@ -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

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

View File

@ -0,0 +1,56 @@
package com.gh.common
import android.webkit.JavascriptInterface
import androidx.annotation.Keep
import com.gh.base.CurrentActivityHolder
import com.gh.common.util.MtaHelper
import com.gh.common.util.toObject
import com.gh.gamecenter.ViewImageActivity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
class DefaultJsApi {
@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 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,117 @@
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, "文章链接")
}
DialogUtils.showLowVersionDialog(context)
}
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

@ -16,12 +16,20 @@ public class Constants {
public static final String USER_INFO_KEY = "userInfoKey";
public static final String DEVICE_KEY = "deviceKey";
public static final String HAS_REQUESTED_NOTIFICATION_PERMISSIONS = "has_requested_notification_permissions";
public static final String SHOULD_SHOW_VIDEO_MOBILE_WARNING = "should_show_video_mobile_warning";
public static final String GAME_DETAIL_COME_IN = "game_detail_come_in"; // 从游戏详情进入
public static final String XPOSED_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer";
// 最近显示的弹窗信息
public static final String 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";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
@ -50,4 +58,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

@ -28,6 +28,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

@ -9,10 +9,6 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.OnViewClickListener;
import com.gh.common.constant.Config;
@ -32,6 +28,7 @@ import com.gh.common.util.PlatformUtils;
import com.gh.common.util.StringUtils;
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 +37,11 @@ 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.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;
@ -54,6 +52,10 @@ import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/**
* Created by khy on 12/02/18.
*/
@ -76,7 +78,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 +90,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 +119,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));
@ -319,8 +321,13 @@ public class BindingAdapters {
}
// 显示下载按钮状态
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);
@ -505,4 +512,30 @@ 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);
}
}
}

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,12 @@ 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
class ReserveDialogFragment : BaseDialogFragment() {
// 预约弹窗
class ReserveDialogFragment : BaseTrackableDialogFragment() {
@BindView(R.id.reserve_hint_tv)
lateinit var reserveHintTv: TextView
@ -61,6 +61,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?) {
@ -79,7 +87,7 @@ class ReserveDialogFragment : BaseDialogFragment() {
mSuccessCallback?.onSuccess()
}
}
dialog.setCanceledOnTouchOutside(true)
dialog?.setCanceledOnTouchOutside(true)
}
private fun showSuccessDialog(withMobile: Boolean) {
@ -90,13 +98,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()) {
customizableBtn.visibility = View.GONE
} else {
customizableBtn.text = dialogConfig?.text
customizableBtn.setOnClickListener {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
DirectUtils.directToLinkPage(
requireContext(),
dialogConfig!!.toLinkEntity(),
@ -114,6 +123,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 +134,12 @@ class ReserveDialogFragment : BaseDialogFragment() {
return
}
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
mViewModel.reserve(gameId = mGameId, gameName = mGameName, mobile = mobile)
}
R.id.close_btn -> {
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
dismissAllowingStateLoss()
}
}

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
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

@ -4,7 +4,6 @@ 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;
@ -33,6 +32,7 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.core.content.ContextCompat;
import retrofit2.HttpException;
/**
@ -87,7 +87,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 +259,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 +284,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 +295,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 +335,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);
}
@ -340,8 +345,8 @@ public class CommentUtils {
//检查是否是自身评论
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 +358,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());

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();
}
/**
@ -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
@ -15,8 +16,11 @@ 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.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.HomeActivity
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
@ -26,6 +30,7 @@ import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
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,6 +127,10 @@ object DirectUtils {
display = linkEntity.display ?: Display())))
}
"column_collection" -> {
context.startActivity(ColumnCollectionDetailActivity.getIntent(context, linkEntity.link!!, entrance))
}
else -> DialogUtils.showLowVersionDialog(context)
}
}
@ -135,7 +144,12 @@ 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(HomeActivity.getIntent(context, userId ?: "", entrance, path))
}
/**
@ -148,7 +162,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 +178,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 +190,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 +198,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 +213,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 +225,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 +245,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 +255,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 +264,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 +273,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 +331,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)
}
/**
@ -320,7 +349,7 @@ 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(EBReuse(CommunityFragment.EB_RETRY_PAGE))
}
}
@ -348,4 +377,23 @@ 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)
}
}
}

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

@ -7,12 +7,6 @@ import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.common.dialog.ReserveDialogFragment;
import com.gh.common.exposure.ExposureEvent;
@ -35,6 +29,12 @@ import com.lightgame.utils.Utils;
import java.util.concurrent.LinkedBlockingQueue;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
public class DownloadItemUtils {
// 更新下载进度条
@ -167,13 +167,20 @@ 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));
} 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);

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,6 +39,7 @@ 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";
@ -61,6 +62,7 @@ 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_PATH = "path";
@ -83,6 +85,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 +116,12 @@ 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_COLLECTION_ID = "collectionId";
public static final String KEY_NAVIGATION_TITLE = "navigationTitle";
public static void jumpActivity(Context context, Bundle bundle) {
@ -121,18 +130,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,8 @@ 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, "标题可能包含敏感词,请修改后再提交")
403020 -> if (showHighPriorityHint) {
DialogUtils.showAlertDialog(context,
@ -130,8 +132,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 +148,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 +156,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,28 @@ fun ViewPager.addOnPageChangeListener(onSelected: ((position: Int) -> Unit)? = n
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 +120,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 +205,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 +260,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 +324,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: String,
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

@ -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

@ -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

@ -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) {

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

@ -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

@ -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,6 +50,9 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import static com.gh.common.util.GetLoginDataUtils.SCOPE;
/**
@ -87,7 +88,8 @@ public class ShareUtils {
askInvite,
askNormal, // 问答问题/答案
shareGh,
communityArticle
communityArticle,
video
}
private String[] arrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "新浪微博", "短信", "复制链接", "取消"};
@ -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

@ -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,21 @@
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.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.gamecenter.R
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.util.*
import java.util.regex.Pattern
object TextHelper {
@ -49,6 +60,96 @@ 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: String,
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
}
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,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

@ -15,12 +15,12 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ProgressBar;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
public class DownloadProgressBar extends ProgressBar {
private static final int MAX_LENGTH = 1000;
private static final int DOWNLOAD_NORMAL_STYLE = 0;
@ -30,6 +30,7 @@ public class DownloadProgressBar extends ProgressBar {
public enum DownloadType {
NORMAL,
NONE,
NONE_WITH_HINT,
PLUGIN,
LAUNCH_OR_OPEN,
INSTALL_NORMAL,
@ -129,6 +130,7 @@ public class DownloadProgressBar extends ProgressBar {
public void setDownloadType(DownloadType downloadType) {
switch (downloadType) {
case NORMAL:
case NONE_WITH_HINT:
case INSTALL_NORMAL:
switch (mDownloadStyle) {
case DOWNLOAD_RECT_STYLE:

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

@ -19,69 +19,67 @@ import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
public class ExpendTextView extends AppCompatTextView {
private CharSequence mSnapshotText;
private CharSequence mCloseText;
private String mExpendText = "...全文";
private int mMaxLines = 3; // 由于sdk版本限制(getMaxLines) 这里设置默认值
private boolean mInitLayout = false;
private boolean mOpenLayout = false;
private ExpandCallback mExpandCallback;
public ExpendTextView(Context context) {
super(context);
}
public ExpendTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mMaxLines = getMaxLines();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mInitLayout && !mOpenLayout && getLineCount() > mMaxLines) {
mSnapshotText = getText();
mCloseText = getText();
mInitLayout = false;
showExpendButton();
}
}
public void setExpendText(String text) {
this.mExpendText = text;
}
public void setExpandCallback(ExpandCallback callback) {
this.mExpandCallback = callback;
}
@Override
public void setText(CharSequence text, BufferType type) {
mInitLayout = true;
super.setText(text, type);
}
private void showExpendButton() {
Layout layout = getLayout();
int start = layout.getLineStart(0);
int lastLineEnd = layout.getLineEnd(mMaxLines - 1);
int lastLineStart = layout.getLineStart(mMaxLines - 1);
float lastLineRight = layout.getLineRight(mMaxLines - 1);
int viewWidth = getWidth() - getPaddingRight() - getPaddingLeft();
TextPaint paint = getPaint();
float expendTextWidth = paint.measureText(mExpendText);
CharSequence content = mSnapshotText.subSequence(start, lastLineEnd);
if (viewWidth - lastLineRight > expendTextWidth) {
content = content.toString().trim() + mExpendText;
content = content.toString().trim() + mExpendText ;
} else {
CharSequence lastText = mSnapshotText.subSequence(lastLineStart, lastLineEnd);
for (int i = lastText.length() - 1; i > 0; i--) {
@ -93,52 +91,44 @@ 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);
}
@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);
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);
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);
setText(msp);
setMovementMethod(CustomLinkMovementMethod.getInstance());
}
public void setExpendMaxLines(int maxLines) {
mMaxLines = maxLines;
setMaxLines(maxLines);
}
public interface ExpandCallback {
void onExpand();
}
}

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

@ -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.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,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)
}
}

View File

@ -0,0 +1,22 @@
package com.gh.common.view.vertical_recycler;
public interface OnPagerListener {
/**
* 初始化完成
*/
void onInitComplete();
/**
* 释放的监听
* @param isNext 是否下一个true表示下一个false表示上一个
* @param position 索引
*/
void onPageRelease(boolean isNext, int position);
/***
* 选中的监听以及判断是否滑动到底部
* @param position 索引
* @param isBottom 是否到了底部
*/
void onPageSelected(int position, boolean isBottom);
}

View File

@ -0,0 +1,211 @@
package com.gh.common.view.vertical_recycler;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
public class PagerLayoutManager extends LinearLayoutManager {
private RecyclerView mRecyclerView;
private ScrollPageHelper mPagerSnapHelper;
private OnPagerListener mOnViewPagerListener;
private static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
private static final int VERTICAL = OrientationHelper.VERTICAL;
private int mOrientation;
/**
* 位移,用来判断移动方向
*/
private int mDrift;
public PagerLayoutManager(Context context, int orientation) {
super(context, orientation, false);
this.mOrientation = orientation;
init();
}
public PagerLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
this.mOrientation = orientation;
init();
}
/**
* 初始化操作
*/
private void init() {
switch (mOrientation){
case HORIZONTAL:
mPagerSnapHelper = new ScrollPageHelper(Gravity.START,false);
break;
case VERTICAL:
mPagerSnapHelper = new ScrollPageHelper(Gravity.TOP,false);
break;
default:
mPagerSnapHelper = new ScrollPageHelper(Gravity.TOP,false);
break;
}
}
/**
* attach到window窗口时该方法必须调用
* @param recyclerView recyclerView
*/
@Override
public void onAttachedToWindow(RecyclerView recyclerView){
if (recyclerView == null) {
throw new IllegalArgumentException("The attach RecycleView must not null!!");
}
super.onAttachedToWindow(recyclerView);
this.mRecyclerView = recyclerView;
if (mPagerSnapHelper==null){
init();
}
try {
//attachToRecyclerView源码上的方法可能会抛出IllegalStateException异常这里手动捕获一下
RecyclerView.OnFlingListener onFlingListener = mRecyclerView.getOnFlingListener();
//源码中判断了如果onFlingListener已经存在的话再次设置就直接抛出异常那么这里可以判断一下
if (onFlingListener==null){
mPagerSnapHelper.attachToRecyclerView(mRecyclerView);
}
} catch (IllegalStateException e){
e.printStackTrace();
}
mRecyclerView.addOnChildAttachStateChangeListener(mChildAttachStateChangeListener);
}
/**
* 销毁的时候调用该方法,需要移除监听事件
* @param view view
* @param recycler recycler
*/
@Override
public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
super.onDetachedFromWindow(view, recycler);
if (mRecyclerView!=null){
mRecyclerView.removeOnChildAttachStateChangeListener(mChildAttachStateChangeListener);
}
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
}
/**
* 滑动状态的改变
* 缓慢拖拽-> SCROLL_STATE_DRAGGING
* 快速滚动-> SCROLL_STATE_SETTLING
* 空闲状态-> SCROLL_STATE_IDLE
* @param state 状态
*/
@Override
public void onScrollStateChanged(int state) {
switch (state) {
case RecyclerView.SCROLL_STATE_IDLE:
View viewIdle = mPagerSnapHelper.findSnapView(this);
int positionIdle = 0;
if (viewIdle != null) {
positionIdle = getPosition(viewIdle);
}
int childCount = getChildCount();
if (mOnViewPagerListener != null && childCount == 1) {
mOnViewPagerListener.onPageSelected(positionIdle,
positionIdle == childCount - 1);
}
break;
case RecyclerView.SCROLL_STATE_DRAGGING:
View viewDrag = mPagerSnapHelper.findSnapView(this);
if (viewDrag != null) {
int positionDrag = getPosition(viewDrag);
}
break;
case RecyclerView.SCROLL_STATE_SETTLING:
View viewSettling = mPagerSnapHelper.findSnapView(this);
if (viewSettling != null) {
int positionSettling = getPosition(viewSettling);
}
break;
default:
break;
}
}
/**
* 监听竖直方向的相对偏移量
* @param dy y轴滚动值
* @param recycler recycler
* @param state state滚动状态
* @return int值
*/
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
RecyclerView.State state) {
//需要判断子类的数量不能为0的情况
if (getChildCount() == 0 || dy == 0) {
return 0;
}
this.mDrift = dy;
return super.scrollVerticallyBy(dy, recycler, state);
}
/**
* 监听水平方向的相对偏移量
* @param dx x轴滚动值
* @param recycler recycler
* @param state state滚动状态
* @return int值
*/
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
RecyclerView.State state) {
if (getChildCount() == 0 || dx == 0) {
return 0;
}
this.mDrift = dx;
return super.scrollHorizontallyBy(dx, recycler, state);
}
/**
* 设置监听
* @param listener listener
*/
public void setOnViewPagerListener(OnPagerListener listener){
this.mOnViewPagerListener = listener;
}
private RecyclerView.OnChildAttachStateChangeListener mChildAttachStateChangeListener =
new RecyclerView.OnChildAttachStateChangeListener() {
/**
* 第一次进入界面的监听,可以做初始化方面的操作
* @param view view
*/
@Override
public void onChildViewAttachedToWindow(@NonNull View view) {
if (mOnViewPagerListener != null && getChildCount() == 1) {
mOnViewPagerListener.onInitComplete();
}
}
/**
* 页面销毁的时候调用该方法,可以做销毁方面的操作
* @param view view
*/
@Override
public void onChildViewDetachedFromWindow(@NonNull View view) {
if (mDrift >= 0){
if (mOnViewPagerListener != null) {
mOnViewPagerListener.onPageRelease(true , getPosition(view));
}
}else {
if (mOnViewPagerListener != null) {
mOnViewPagerListener.onPageRelease(false , getPosition(view));
}
}
}
};
}

View File

@ -0,0 +1,274 @@
package com.gh.common.view.vertical_recycler;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
public class ScrollPageHelper extends PagerSnapHelper {
private OrientationHelper mHorizontalHelper, mVerticalHelper;
private int gravity;
private boolean snapLastItem;
private boolean isRtlHorizontal;
/**
* 构造方法
* @param gravity 位置
* @param enableSnapLast 最后一个是否按照位置对齐
*/
public ScrollPageHelper(int gravity, boolean enableSnapLast){
this.snapLastItem = enableSnapLast;
this.gravity = gravity;
}
/**
* 这个方法是与recyclerView绑定
* @param recyclerView recyclerView
* @throws IllegalStateException
*/
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
throws IllegalStateException {
if (recyclerView != null && !(recyclerView.getLayoutManager()
instanceof LinearLayoutManager)) {
throw new IllegalStateException("ScrollPageHelper needs a " +
"RecyclerView with a LinearLayoutManager");
}
if (recyclerView != null) {
//设置fling监听为null
recyclerView.setOnFlingListener(null);
if ((gravity == Gravity.START || gravity == Gravity.END)) {
isRtlHorizontal = isRtl();
}
}
super.attachToRecyclerView(recyclerView);
}
/**
*
* @param layoutManager layoutManager
* @param targetView 目标view
* @return
*/
@Nullable
@Override
public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager,
@NonNull View targetView) {
//创建数组
int[] out = new int[2];
//判断是否是横向方法
if (layoutManager.canScrollHorizontally()) {
if (gravity == Gravity.START) {
out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager), false);
} else { // END
out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager), false);
}
} else {
out[0] = 0;
}
//判断是否是竖直方法
if (layoutManager.canScrollVertically()) {
if (gravity == Gravity.TOP) {
out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager), false);
} else { // BOTTOM
out[1] = distanceToEnd(targetView, getVerticalHelper(layoutManager), false);
}
} else {
out[1] = 0;
}
return out;
}
/**
* 找到当前时刻的SnapView
* @param layoutManager layoutManager
* @return
*/
@Nullable
@Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
View snapView = null;
if (layoutManager instanceof LinearLayoutManager) {
switch (gravity) {
case Gravity.START:
snapView = findStartView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.END:
snapView = findEndView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.TOP:
snapView = findStartView(layoutManager, getVerticalHelper(layoutManager));
break;
case Gravity.BOTTOM:
snapView = findEndView(layoutManager, getVerticalHelper(layoutManager));
break;
default:
break;
}
}
return snapView;
}
private boolean isRtl() {
return TextUtils.getLayoutDirectionFromLocale(
Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL;
}
@NonNull
private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
if (mVerticalHelper == null) {
mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
}
return mVerticalHelper;
}
@NonNull
private OrientationHelper getHorizontalHelper(
@NonNull RecyclerView.LayoutManager layoutManager) {
if (mHorizontalHelper == null) {
mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return mHorizontalHelper;
}
private int distanceToStart(View targetView, @NonNull OrientationHelper helper, boolean fromEnd) {
if (isRtlHorizontal && !fromEnd) {
return distanceToEnd(targetView, helper, true);
}
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
private int distanceToEnd(View targetView, @NonNull OrientationHelper helper, boolean fromStart) {
if (isRtlHorizontal && !fromStart) {
return distanceToStart(targetView, helper, true);
}
return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
}
@Nullable
private View findStartView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int firstChild = reverseLayout ? linearLayoutManager.findLastVisibleItemPosition()
: linearLayoutManager.findFirstVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
boolean endOfList;
if (!reverseLayout) {
endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
} else {
endOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition()
== 0;
}
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (snapLastItem && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(firstChild - offset)
: layoutManager.findViewByPosition(firstChild + offset);
}
}
return null;
}
@Nullable
private View findEndView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition()
: linearLayoutManager.findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
boolean startOfList;
if (!reverseLayout) {
startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
} else {
startOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
}
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset)
: layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
}

View File

@ -10,9 +10,6 @@ import android.os.Message;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.util.AppDebugConfig;
import com.gh.common.util.DataCollectionUtils;
@ -24,6 +21,8 @@ import com.gh.common.util.NetworkUtils;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.entity.ApkEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.PluginLocation;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.manager.PackagesManager;
import com.google.gson.Gson;
@ -50,6 +49,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
import static android.os.Build.MANUFACTURER;
public class DownloadManager implements DownloadStatusListener {
@ -85,7 +87,8 @@ public class DownloadManager implements DownloadStatusListener {
@Override
public void onTaskAdded(DownloadEntity entity) {
EventBus.getDefault().post(new EBDownloadStatus("download"));
EventBus.getDefault().post(new EBDownloadStatus("download",entity.getName(),
entity.getPlatform(), entity.getUrl(), entity.getPackageName(), entity.getGameId()));
DownloadNotification.showDownloadingNotification(mContext);
@ -611,10 +614,20 @@ public class DownloadManager implements DownloadStatusListener {
Utils.log("checkRetryDownload::" + downloadEntity.getStatus());
}
}
//
// public void removeObservers() {
// Utils.log(DownloadManager.class.getSimpleName(), "removeObserver");
// DataChanger.INSTANCE.deleteObservers();
// }
public int getDownloadOrUpdateCount(List<GameUpdateEntity> updateList) {
int downloadSize = getAll().size();
if (downloadSize != 0) {
return downloadSize;
}
int updateSize = 0;
if (updateList != null) {
for (GameUpdateEntity updateEntity : updateList) {
if (updateEntity.isShowPlugin(PluginLocation.only_index)) updateSize++;
}
}
return updateSize;
}
}

View File

@ -17,4 +17,17 @@ class BlockActivity : NormalActivity() {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setToolbarMenu(R.menu.menu_download)
}
override fun showDownloadMenu(): Boolean {
return true
}
override fun getActivityNameInChinese(): String {
return "板块"
}
}

View File

@ -8,7 +8,7 @@ import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.entity.LinkEntity;
import com.gh.gamecenter.entity.MessageEntity;
import com.gh.gamecenter.qa.comment.CommentActivity;
import com.gh.gamecenter.qa.comment.CommentConversationFragment;
import com.gh.gamecenter.qa.comment.NewCommentConversationFragment;
import com.halo.assistant.fragment.comment.CommentDetailFragment;
/**
@ -32,7 +32,7 @@ public class CommentDetailActivity extends NormalActivity {
args.putString(EntranceUtils.KEY_COMMENTID, commentId);
args.putString(EntranceUtils.KEY_ANSWER_ID, answerId);
args.putParcelable(EntranceUtils.KEY_LINK, linkEntity);
return getTargetIntent(context, CommentDetailActivity.class, CommentConversationFragment.class, args);
return getTargetIntent(context, CommentDetailActivity.class, NewCommentConversationFragment.class, args);
}
@ -43,10 +43,22 @@ public class CommentDetailActivity extends NormalActivity {
LinkEntity linkEntity) {
Bundle args = new Bundle();
args.putString(CommentActivity.ARTICLE_ID, articleId);
args.putString(EntranceUtils.KEY_ARTICLE_COMMENT_ID, articleCommentId);
args.putString(EntranceUtils.KEY_COMMENTID, articleCommentId);
args.putString(CommentActivity.COMMUNITY_ID, communityId);
args.putParcelable(EntranceUtils.KEY_LINK, linkEntity);
return getTargetIntent(context, CommentDetailActivity.class, CommentConversationFragment.class, args);
return getTargetIntent(context, CommentDetailActivity.class, NewCommentConversationFragment.class, args);
}
public static Intent getVideoCommentIntent(Context context,
String commentId,
String videoId,
LinkEntity linkEntity) {
Bundle args = new Bundle();
args.putString(EntranceUtils.KEY_COMMENTID, commentId);
args.putString(CommentActivity.VIDEO_ID, videoId);
args.putParcelable(EntranceUtils.KEY_LINK, linkEntity);
return getTargetIntent(context, CommentDetailActivity.class, NewCommentConversationFragment.class, args);
}
}

View File

@ -32,10 +32,9 @@ public class DownloadManagerActivity extends NormalActivity {
return getTargetIntent(context, DownloadManagerActivity.class, DownloadFragment.class, bundle);
}
public static Intent getDownloadMangerIntent(Context context, int position, String entrance) {
public static Intent getDownloadMangerIntent(Context context, String entrance) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance);
bundle.putInt(BaseFragment_TabLayout.PAGE_INDEX, position);
return getTargetIntent(context, DownloadManagerActivity.class, DownloadFragment.class, bundle);
}

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.Bundle;
@ -9,23 +10,37 @@ import com.gh.common.exposure.ExposureManager;
import com.gh.common.exposure.ExposureTraceUtils;
import com.gh.common.exposure.ExposureType;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.gamedetail.GameDetailFragment;
import com.halo.assistant.HaloApp;
import cn.jzvd.Jzvd;
import static com.gh.common.constant.Constants.GAME_DETAIL_COME_IN;
/**
* Created by khy on 2017/3/24.
* 游戏详情适配器
*/
public class GameDetailActivity extends NormalActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DisplayUtils.transparentStatusBar(this);
}
@Override
protected Intent provideNormalIntent() {
return getTargetIntent(this, GameDetailActivity.class, GameDetailFragment.class);
}
@Override
protected int getLayoutId() {
return R.layout.activity_game_detail;
}
/**
* 启动游戏详情页面
*/
@ -121,6 +136,16 @@ public class GameDetailActivity extends NormalActivity {
context.startActivity(getTargetIntent(context, GameDetailActivity.class, GameDetailFragment.class, bundle));
}
/**
* 启动游戏详情页面并定位到第一个或第二个 tab
*/
public static void startGameDetailByShortcut(Context context, GameEntity game, int tab, String entrance) {
Bundle bundle = new Bundle();
bundle.putParcelable(GameEntity.TAG, game);
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance);
bundle.putInt(EntranceUtils.KEY_TARGET, tab);
context.startActivity(getTargetIntent(context, GameDetailActivity.class, GameDetailFragment.class, bundle));
}
/**
* 如果存在多个游戏平台则打开
@ -133,16 +158,38 @@ public class GameDetailActivity extends NormalActivity {
context.startActivity(getTargetIntent(context, GameDetailActivity.class, GameDetailFragment.class, bundle));
}
@Override
public void onBackPressed() {
if (Jzvd.backPress()) {
return;
}
super.onBackPressed();
}
@Override
public boolean showToolbarAtLeft() {
return true;
}
@Override
protected boolean showDownloadMenu() {
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
HaloApp.remove(GAME_DETAIL_COME_IN);
}
@Override
public String getActivityNameInChinese() {
return "游戏详情";
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new ContextWrapper(newBase) {
@Override
public Object getSystemService(String name) {
// 解决 VideoView 中 AudioManager 造成的内存泄漏
if (Context.AUDIO_SERVICE.equals(name)) {
return getApplicationContext().getSystemService(name);
}
return super.getSystemService(name);
}
});
}
}

View File

@ -1,24 +0,0 @@
package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.kaifu.KaiFuWrapperFragment;
/**
* Created by khy on 18/08/17.
*/
@Deprecated
public class KaiFuActivity extends NormalActivity {
@NonNull
public static Intent getIntent(Context context, String entrance) {
Bundle args = new Bundle();
args.putString(EntranceUtils.KEY_ENTRANCE, entrance);
return getTargetIntent(context, KaiFuActivity.class, KaiFuWrapperFragment.class, args);
}
}

View File

@ -22,14 +22,12 @@ import android.view.View;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import com.gh.base.AppUncaughtHandler;
import com.gh.base.BaseActivity;
import com.gh.base.fragment.BaseFragment_ViewPager;
import com.gh.common.AppExecutor;
import com.gh.common.constant.Config;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.ExposureUtils;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.im.ImManager;
@ -49,9 +47,11 @@ import com.gh.common.util.GsonUtils;
import com.gh.common.util.LogUtils;
import com.gh.common.util.LunchType;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NotificationHelper;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.PushHelper;
import com.gh.common.util.SPUtils;
import com.gh.common.util.ThirdPartyPackageHelper;
import com.gh.common.util.UrlFilterUtils;
import com.gh.download.DownloadManager;
@ -61,6 +61,7 @@ import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.GameDigestEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
import com.gh.gamecenter.entity.NotificationHint;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBPackage;
@ -74,7 +75,8 @@ import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.normal.NormalFragment;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.qa.AskFragment;
import com.gh.gamecenter.qa.CommunityFragment;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.EmptyResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
@ -110,6 +112,8 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
@ -313,6 +317,8 @@ public class MainActivity extends BaseActivity {
// checkTinkerPath(); // todo 看情况是否需要显示弹窗
checkRetryDownload();
checkNotificationPermission();
// 初始化 IM只有在 APP 刚启动时执行
if (HaloApp.get(SHOULD_INIT_IM, false) != null) {
@ -334,8 +340,9 @@ public class MainActivity extends BaseActivity {
handler.postDelayed(() -> {
PushHelper.postPushClickAction(this.getApplicationContext(), null);
}, 2000);
}
@Override
protected void onDestroy() {
super.onDestroy();
@ -382,6 +389,15 @@ public class MainActivity extends BaseActivity {
}
}, 500);
}
private void checkNotificationPermission() {
// 仅登录后再启动光环时请求一次权限
if (!SPUtils.getBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS)
&& UserManager.getInstance().isLoggedIn()) {
SPUtils.setBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS, true);
showNotificationHintDialog();
}
}
// 统计下载
private void uploadData(String id, String platform) {
@ -543,7 +559,7 @@ public class MainActivity extends BaseActivity {
getIntent().putExtra(SWITCH_TO_COMMUNITY, false);
Log.e("Switch", "true");
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_GAMEFRAGMENT, 1));
EventBus.getDefault().post(new EBReuse(AskFragment.EB_RETRY_PAGE));
EventBus.getDefault().post(new EBReuse(CommunityFragment.EB_RETRY_PAGE));
}
private void getGhzsSettings() {
@ -663,6 +679,24 @@ public class MainActivity extends BaseActivity {
}
});
}
@SuppressLint("CheckResult")
private void showNotificationHintDialog() {
if (!SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_HINT)) {
RetrofitManager.getInstance(this).getApi().getBootPopup()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NotificationHint>() {
@Override
public void onSuccess(NotificationHint data) {
try {
NotificationHelper.showEnableNotificationDialogIfItsDisabled(MainActivity.this, data);
} catch (Exception ignore){
}
}
});
}
}
private void oldUserSkip(String deviceId) {
mSp.edit().putString("syncDeviceID", deviceId).apply();
@ -748,12 +782,14 @@ public class MainActivity extends BaseActivity {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBPackage busFour) {
final String packageName = busFour.getPackageName();
String gameId = "";
DownloadEntity mDownloadEntity = null;
for (DownloadEntity downloadEntity : DownloadManager.getInstance(getApplicationContext()).getAll()) {
//todo 根据包名获取DownloadEntity? 假如存在相同包名的下载任务,有可能会删除错误
if (packageName.equals(downloadEntity.getPackageName())) {
mDownloadEntity = downloadEntity;
gameId = mDownloadEntity.getGameId();
break;
}
}
@ -809,7 +845,7 @@ public class MainActivity extends BaseActivity {
});
}
postNewlyInstalledApp(packageName);
postNewlyInstalledApp(gameId, packageName);
}
if ("卸载".equals(busFour.getType())) {
mPackageViewModel.addUninstalledGame(packageName);
@ -837,7 +873,7 @@ public class MainActivity extends BaseActivity {
}
@SuppressLint("CheckResult")
private void postNewlyInstalledApp(String packageName) {
private void postNewlyInstalledApp(String gameId, String packageName) {
// 发送应用变更前都检查一下是否需要把所有应用都上传
PackageRepository.checkAndUploadAppList();
@ -853,6 +889,14 @@ public class MainActivity extends BaseActivity {
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn()) {
RetrofitManager.getInstance(MainActivity.this).getApi()
.postPlayedGame(UserManager.getInstance().getUserId(), gameId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
}
}
@SuppressLint("CheckResult")
@ -876,5 +920,9 @@ public class MainActivity extends BaseActivity {
MetaUtil.INSTANCE.refreshMeta();
}
}
@Override
public String getActivityNameInChinese() {
return "游戏首页";
}
}

View File

@ -695,4 +695,8 @@ public class NewsDetailActivity extends BaseActivity implements OnClickListener,
}
}
@Override
protected boolean showDownloadMenu() {
return true;
}
}

View File

@ -1,154 +0,0 @@
package com.gh.gamecenter
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseActivity
import com.gh.common.util.EntranceUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.StringUtils
import com.gh.gamecenter.baselist.ListActivity
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.entity.PersonalHistoryEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.message.MessageUnreadViewModel
import com.gh.gamecenter.personalhome.PersonalHomeAdapter
import com.gh.gamecenter.personalhome.PersonalHomeViewModel
import com.gh.gamecenter.user.UserViewModel
import com.halo.assistant.HaloApp
/**
* 个人主页内部相关的页面不要直接使用 UserManager.getInstance().userId 获取用户ID
*/
class PersonalHomeActivity : ListActivity<PersonalHistoryEntity, PersonalHomeViewModel>() {
private var mAdapter: PersonalHomeAdapter? = null
private var mUnreadViewModel: MessageUnreadViewModel? = null
private var mUserViewModel: UserViewModel? = null
private var mPath: String? = ""
private var mUserId: String? = ""
override fun provideListAdapter(): PersonalHomeAdapter {
if (mAdapter == null) mAdapter = PersonalHomeAdapter(this, mListViewModel, mEntrance)
return mAdapter!!
}
override fun provideListViewModel(): PersonalHomeViewModel {
val factory = PersonalHomeViewModel.Factory(
HaloApp.getInstance().application,
intent.getStringExtra(EntranceUtils.KEY_USER_ID))
return ViewModelProviders.of(this, factory).get(PersonalHomeViewModel::class.java)
}
override fun isAutomaticLoad(): Boolean {
return false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNavigationTitle("个人主页")
val factory = MessageUnreadViewModel.Factory(application)
mUnreadViewModel = ViewModelProviders.of(this, factory).get(MessageUnreadViewModel::class.java)
mUnreadViewModel?.liveData?.observe(this, Observer {
mAdapter?.setMessageUnreadData(it)
})
mPath = intent.getStringExtra(EntranceUtils.KEY_PATH)
mUserId = intent.getStringExtra(EntranceUtils.KEY_USER_ID)
mListViewModel.personalDataLD.observe(this, Observer {
if (mListViewModel.userId == UserManager.getInstance().userId) {
val data = mUserViewModel?.loginObsUserinfo?.value?.data
it?.icon = data?.icon!!
it?.name = data.name!!
it?.introduce = data.introduce
}
trackMtaEvent(it?.name)
mAdapter?.personalData = it
mAdapter?.notifyDataSetChanged()
})
val userFactory = UserViewModel.Factory(application)
mUserViewModel = ViewModelProviders.of(this, userFactory).get(UserViewModel::class.java)
mUserViewModel?.editObsUserinfo?.observe(this, Observer {
val data = it?.data
if (data != null) {
val personalData = mAdapter?.personalData
if (personalData != null) {
personalData.icon = data.icon!!
personalData.name = data.name!!
personalData.introduce = data.introduce!!
mAdapter?.personalData = personalData
mAdapter?.notifyDataSetChanged()
}
}
})
mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val topView = mLayoutManager.findViewByPosition(0)
val personalData = mAdapter?.personalData
if (personalData != null) {
if (topView == null || -topView.top > 150) {
setNavigationTitle(personalData.name)
} else {
setNavigationTitle("个人主页")
}
}
}
})
}
private fun trackMtaEvent(name: String? = "") {
MtaHelper.onEvent("个人主页", mPath, StringUtils.combineTwoString(name, mUserId))
MtaHelper.onEvent("个人主页", "不区分位置", StringUtils.combineTwoString(name, mUserId))
}
override fun onLoadRefresh() {
mReuseNoConn.visibility = View.GONE
mReuseNoData.visibility = View.GONE
mListLoading.visibility = View.VISIBLE
mListRv.visibility = View.GONE
mBaseHandler.postDelayed({ mListViewModel.initData() }, 500)
}
override fun onLoadError() {
if (mListViewModel.personalDataLD.value != null) {
mAdapter?.loadChange(LoadStatus.LIST_FAILED)
super.onLoadDone()
} else {
super.onLoadError()
}
}
override fun onLoadEmpty() {
if (mListViewModel.personalDataLD.value != null) {
mAdapter?.loadChange(LoadStatus.LIST_OVER)
super.onLoadDone()
} else {
super.onLoadEmpty()
}
}
companion object {
@JvmStatic
fun startTargetActivity(context: Context, userId: String?, entrance: String?, path: String?) {
if (!userId.isNullOrEmpty()) {
val intent = Intent(context, PersonalHomeActivity::class.java)
intent.putExtra(EntranceUtils.KEY_USER_ID, userId)
intent.putExtra(EntranceUtils.KEY_PATH, path)
intent.putExtra(EntranceUtils.KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
context.startActivity(intent)
}
}
}
}

View File

@ -32,8 +32,6 @@ public class ShareGhActivity extends BaseActivity {
ImageView mGhQrcode;
@BindView(R.id.gh_address_tv)
TextView mGhAddress;
@BindView(R.id.wifi_share_btn)
Button mWifiShareBtn;
@BindView(R.id.content_ll)
LinearLayout mContentLl;
@BindView(R.id.share_rl)
@ -72,11 +70,6 @@ public class ShareGhActivity extends BaseActivity {
, "绿色安全的手游加速助手", ShareUtils.ShareType.shareGh);
}
@OnClick(R.id.wifi_share_btn)
public void skipWifiShare() {
startActivity(ShareGhWfifActivity.getIntent(this));
}
@OnClick(R.id.gh_address_tv)
public void copyAddress() {
ClipboardManager cmb = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

View File

@ -1,357 +0,0 @@
package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import android.text.Html;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.gh.base.BaseActivity;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.RandomUtils;
import com.gh.gamecenter.entity.KcWebRequestEntity;
import com.gh.gamecenter.kuaichuan.Constant;
import com.gh.gamecenter.kuaichuan.DownloadUriHandler;
import com.gh.gamecenter.kuaichuan.HotspotManager;
import com.gh.gamecenter.kuaichuan.HtmlUriHandler;
import com.gh.gamecenter.kuaichuan.ImageUriHandler;
import com.gh.gamecenter.kuaichuan.KcUriHandler;
import com.gh.gamecenter.kuaichuan.WifiMgr;
import com.gh.gamecenter.receiver.WifiAPBroadcastReceiver;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by khy on 2017/2/6.
*/
public class ShareGhWfifActivity extends BaseActivity {
// @BindView(R.id.hotspot_name) TextView mHotSpotName;
@BindView(R.id.init_hotpost_pb)
ProgressBar mInitHotspostPb;
@BindView(R.id.init_status_icon)
ImageView mInitStatusIcon;
@BindView(R.id.init_status_tv)
TextView mInitStatusTv;
@BindView(R.id.init_hotpost_hint)
TextView mInitHotpostHint;
@BindView(R.id.init_success_ll)
LinearLayout mInitSuccessLl;
@BindView(R.id.init_conn_hint)
TextView initConnHint;
private ServerSocket mServerSocket;
private WifiAPBroadcastReceiver mWifiAPBroadcastReceiver;
private boolean mIsInitialized = false;
private List<KcUriHandler> mUriHandlers;
private SharedPreferences sp;
private boolean isColseActivity;
private boolean isOpenWifi; //记录开热点前的WiFi状态
private boolean initSuccess;
private String mySsid;
@NonNull
public static Intent getIntent(Context context) {
Intent intent = new Intent(context, ShareGhWfifActivity.class);
return intent;
}
@Override
protected int getLayoutId() {
return R.layout.activity_share_gh_wifi;
}
@Override
public void onBackPressed() {
DialogUtils.showWarningDialog(this, "退出分享", "退出本页面即会关闭分享热点,确定退出吗?"
, "取消", "确定"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
isColseActivity = true;
unregisterReceiver(mWifiAPBroadcastReceiver);
try {
if (mWifiAPBroadcastReceiver != null) {
unregisterReceiver(mWifiAPBroadcastReceiver);
mWifiAPBroadcastReceiver = null;
}
} catch (Exception e) {
Utils.log("网页传发送异常-关闭广播");
e.printStackTrace();
}
for (KcUriHandler uriHandler : mUriHandlers) {
uriHandler.destroy();
}
if (mServerSocket != null) {
try {
mServerSocket.close();
mServerSocket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
HotspotManager.initUserAp(getApplicationContext());
if (isOpenWifi) {
WifiMgr.getInstance(ShareGhWfifActivity.this).openWifi();
}
finish();
}
}, null);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setNavigationTitle(getString(R.string.title_share_via_wifi));
ButterKnife.bind(this);
mUriHandlers = new ArrayList<>();
mUriHandlers.add(new HtmlUriHandler(this));
mUriHandlers.add(new ImageUriHandler(this));
mUriHandlers.add(new DownloadUriHandler(this));
sp = PreferenceManager.getDefaultSharedPreferences(this);
isColseActivity = false;
initSuccess = false;
if (WifiMgr.getInstance(this).isWifiEnable()) {
isOpenWifi = true;
WifiMgr.getInstance(this).closeWifi();
}
HotspotManager.initApData(getApplicationContext()); // 记录原始热点信息
initHotSpotView(0);
initHotSpot();
}
/**
* 初始化创建热点View
*
* @param i i=0 初始化中, i=1 初始化成功, i=2 初始化失败
*/
public void initHotSpotView(int i) {
switch (i) {
case 0:
mInitHotspostPb.setVisibility(View.VISIBLE);
mInitStatusIcon.setVisibility(View.GONE);
mInitStatusTv.setText("正在创建热点...");
mInitStatusTv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.title));
mInitHotpostHint.setVisibility(View.VISIBLE);
mInitHotpostHint.setText("如果出现获取权限的提示,请点击允许");
break;
case 1:
mInitStatusIcon.setVisibility(View.VISIBLE);
mInitStatusIcon.setImageResource(R.drawable.kc_checkbox_select);
mInitStatusTv.setText(Html.fromHtml(getString(R.string.create_hotspot_blue, mySsid)));
mInitHotpostHint.setVisibility(View.VISIBLE);
mInitHotpostHint.setText("为了避免消耗流量,请关闭你手机的移动网络");
mInitHotspostPb.setVisibility(View.GONE);
initConnHint.setText(Html.fromHtml(getString(R.string.kc_conn_hint, mySsid)));
mInitSuccessLl.setVisibility(View.VISIBLE);
initSuccess = true;
break;
case 2:
mInitStatusIcon.setVisibility(View.VISIBLE);
mInitStatusIcon.setImageResource(R.drawable.hotspot_failed_icon);
mInitStatusTv.setText("初始化失败, 请退出重试");
mInitStatusTv.setTextColor(ContextCompat.getColor(this, R.color.red));
mInitHotpostHint.setVisibility(View.VISIBLE);
mInitHotspostPb.setVisibility(View.GONE);
break;
}
}
private void initHotSpot() {
mWifiAPBroadcastReceiver = new WifiAPBroadcastReceiver() {
@Override
public void onWifiApEnabled() {
if (!mIsInitialized) {
Utils.log("===初始化热点成功");
HaloApp.getInstance().getMainExecutor().execute(checkHotSpot());
mIsInitialized = true;
// mHotSpotName.setText(mySsid);
}
}
};
IntentFilter filter = new IntentFilter(WifiAPBroadcastReceiver.ACTION_WIFI_AP_STATE_CHANGED);
registerReceiver(mWifiAPBroadcastReceiver, filter);
HotspotManager.isApOn(getApplicationContext());
mySsid = sp.getString("hotspotName", null);
if (TextUtils.isEmpty(mySsid)) {
String chars = "abcdefghijklmnopqrstuvwxyz";
int[] randomArray = RandomUtils.getRandomArray(2, 25);
mySsid = "ghZS-";
for (int i : randomArray) {
mySsid = mySsid + chars.charAt(i);
}
int default_user_icon = sp.getInt("default_user_icon", 0);
if (default_user_icon == 0) {
default_user_icon = RandomUtils.nextInt(8) + 1;
sp.edit().putInt("default_user_icon", default_user_icon).apply();
}
mySsid = mySsid + default_user_icon;
sp.edit().putString("hotspotName", mySsid).apply();
}
HotspotManager.configApState(getApplicationContext(), mySsid); // change Ap state :boolean
}
private Runnable checkHotSpot() {
return new Runnable() {
@Override
public void run() {
try {
// 确保热点开启之后获取得到IP地址
String hotspotIpAddr = WifiMgr.getInstance(ShareGhWfifActivity.this).getHotspotLocalIpAddress();
int count = 0;
while (hotspotIpAddr.equals(Constant.DEFAULT_UNKOWN_IP) && count < Constant.DEFAULT_TRY_TIME) {
Thread.sleep(1000);
hotspotIpAddr = WifiMgr.getInstance(ShareGhWfifActivity.this).getIpAddressFromHotspot();
count++;
}
// 即使热点wifi的IP地址也是无法连接网络 所以采取此策略
// count = 0;
// while(!WifiUtils.pingIpAddress(hotspotIpAddr) && count < Constant.DEFAULT_TRY_TIME){
// Thread.sleep(500);
// count ++;
// }
} catch (Exception e) {
Utils.log("==热点启动异常::" + e.toString());
}
Utils.log("===热点可用");
initMicroServer();
}
};
}
private void initMicroServer() {
HaloApp.getInstance().getMainExecutor().execute(new Runnable() {
@Override
public void run() {
try {
Utils.log("===准备开启微型服务器");
if (mServerSocket == null) {
mServerSocket = new ServerSocket();
mServerSocket.setReuseAddress(true);
mServerSocket.bind(new InetSocketAddress(Constant.DEFAULT_MICRO_SERVER_PORT));
}
while (!isColseActivity) {
if (!initSuccess) {
mInitStatusTv.post(new Runnable() {
@Override
public void run() {
initHotSpotView(1);
}
});
}
Utils.log("===循环等待客户端请求");
Socket socket = mServerSocket.accept();
KcWebRequestEntity requestEntity = hanlderSocket(socket);
for (KcUriHandler uriHandler : mUriHandlers) {
if (!uriHandler.matches(requestEntity.getUri())) {
continue;
}
Utils.log("====请求处理::" + requestEntity.getUri() + "==" + uriHandler.getClass().toString());
uriHandler.handler(requestEntity);
}
}
} catch (IOException e) {
Utils.log("===网页传下载出现异常" + e.toString());
e.printStackTrace();
if (!e.toString().contains("Socket closed")) {
mInitStatusTv.post(new Runnable() {
@Override
public void run() {
initHotSpotView(2);
}
});
}
}
}
});
}
private KcWebRequestEntity hanlderSocket(Socket socket) {
KcWebRequestEntity requestEntity = new KcWebRequestEntity();
requestEntity.setSocket(socket);
try {
InputStream is = socket.getInputStream();
StringBuilder sb = new StringBuilder();
int a = 0, b = 0;
while ((b != -1) && !(a == '\r' && b == '\n')) {
a = b;
b = is.read();
sb.append((char) (b));
}
String[] split = sb.toString().split(" ");
if (split.length > 1) {
String requestUri = split[1];
requestEntity.setUri(requestUri);
Utils.log("===客户端请求链接::" + requestUri);
} else {
requestEntity.setUri("/ERROR");
Utils.log("===客户端请求链接异常::" + sb.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
return requestEntity;
}
}

View File

@ -7,10 +7,12 @@ import android.text.TextUtils;
import com.gh.base.BaseActivity;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.PlatformUtils;
import com.gh.common.util.RunningUtils;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
@ -23,6 +25,8 @@ import static com.gh.common.util.EntranceUtils.HOST_DOWNLOAD;
import static com.gh.common.util.EntranceUtils.HOST_GAME;
import static com.gh.common.util.EntranceUtils.HOST_QUESTION;
import static com.gh.common.util.EntranceUtils.HOST_SUGGESTION;
import static com.gh.common.util.EntranceUtils.HOST_TOOLBOX;
import static com.gh.common.util.EntranceUtils.HOST_VIDEO;
import static com.gh.common.util.EntranceUtils.KEY_GAME_NAME;
import static com.gh.common.util.EntranceUtils.KEY_NAME;
import static com.gh.common.util.EntranceUtils.KEY_PACKAGENAME;
@ -86,6 +90,9 @@ public class SkipActivity extends BaseActivity {
case HOST_QUESTION:
DirectUtils.directToQuestionDetail(this, id, ENTRANCE_BROWSER, "浏览器");
break;
case HOST_TOOLBOX:
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), ENTRANCE_BROWSER);
break;
case HOST_COMMUNITY:
Intent intent;
UserManager.getInstance().setCommunityData(new CommunityEntity(id, name));
@ -130,6 +137,12 @@ public class SkipActivity extends BaseActivity {
break;
}
break;
case HOST_VIDEO:
DirectUtils.directToVideoDetail(this, id, VideoDetailContainerViewModel.Location.HOTTEST_GAME_VIDEO.getValue(), false, ENTRANCE_BROWSER, "浏览器");
break;
default:
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转致首页
return;
}
}
}

View File

@ -125,7 +125,10 @@ public class SplashScreenActivity extends BaseActivity {
// 判断是不是光环的新用户
if (SPUtils.getBoolean(SP_BRAND_NEW_USER, true)) {
View introBackground = findViewById(R.id.splash_intro_background);
introBackground.setVisibility(View.VISIBLE);
showPrivacyPolicy(() -> {
introBackground.setVisibility(View.GONE);
// Dialog dismiss 后的回调
SPUtils.setBoolean(SP_BRAND_NEW_USER, false);
requestPermissionAndLaunchMainActivity();

View File

@ -49,7 +49,6 @@ import com.gh.common.util.UploadImageUtils;
import com.gh.gamecenter.entity.ErrorEntity;
import com.gh.gamecenter.entity.InstallGameEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SuggestionTypeEntity;
import com.gh.gamecenter.entity.UserInfoEntity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.retrofit.Response;
@ -57,7 +56,6 @@ import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.suggest.SuggestPicAdapter;
import com.gh.gamecenter.suggest.SuggestSelectGameAdapter;
import com.gh.gamecenter.suggest.SuggestType;
import com.google.gson.Gson;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Util_System_Phone_State;
@ -275,7 +273,8 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
mSuggestPicRv.setAdapter(mAdapter);
if (!TextUtils.isEmpty(mSuggestContent)) {
if (mSuggestType == SuggestType.gameQuestion && "game".equals(mSuggestHintType)) {
if (mSuggestType == SuggestType.gameQuestion
&& ("game".equals(mSuggestHintType) || "welfare_game".equals(mSuggestHintType) || "online_game".equals(mSuggestHintType) || "local_game".equals(mSuggestHintType))) {
mSuggestContentEt.setText("问题反馈:");
mSuggestSelectGame.setVisibility(View.GONE);
mSuggestGameName.setVisibility(View.VISIBLE);
@ -290,8 +289,7 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
String suggestionType = sp.getString(SUGGESTION_HINT_TYPE, null);
if (!TextUtils.isEmpty(mSuggestHintType) && !TextUtils.isEmpty(suggestionType)) {
Gson gson = new Gson();
SuggestionTypeEntity typeEntity = gson.fromJson(suggestionType, SuggestionTypeEntity.class);
SettingsEntity.Suggestion typeEntity = GsonUtils.fromJson(suggestionType, SettingsEntity.Suggestion.class);
if (typeEntity != null) {
switch (mSuggestHintType) {
case EntranceUtils.KEY_PLUGIN:
@ -300,10 +298,22 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
showHintDialog(plugin);
}
break;
case "game":
List<String> game = typeEntity.getGame();
if (game != null && game.size() > 0) {
showHintDialog(game);
case "local_game":
List<String> localGameList = typeEntity.getLocalGame();
if (localGameList != null && localGameList.size() > 0) {
showHintDialog(localGameList);
}
break;
case "welfare_game":
List<String> welfareGame = typeEntity.getWelfareGame();
if (welfareGame != null && welfareGame.size() > 0) {
showHintDialog(welfareGame);
}
break;
case "online_game":
List<String> onlineGame = typeEntity.getOnlineGame();
if (onlineGame != null && onlineGame.size() > 0) {
showHintDialog(onlineGame);
}
break;
case "libao":
@ -863,7 +873,7 @@ public class SuggestionActivity extends BaseActivity implements OnRequestCallBac
() -> {
if (ShareUtils.isQQClientAvailable(this)) {
finish();
DirectUtils.directToQqConversation(this, "2586716223");
DirectUtils.directToQqConversation(this, "3467475980");
} else {
toast("本机未安装QQ应用");
}

View File

@ -14,27 +14,35 @@ import com.gh.base.BaseActivity;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.TextHelper;
import com.gh.common.util.UrlFilterUtils;
import com.gh.common.view.VerticalItemDecoration;
import com.gh.gamecenter.adapter.ToolBoxRvAdapter;
import com.gh.gamecenter.entity.ToolBoxEntity;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.suggest.SuggestType;
import com.google.android.material.appbar.AppBarLayout;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by khy on 24/05/17.
*/
public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.OnRefreshListener,
OnRequestCallBackListener {
public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.OnRefreshListener, OnRequestCallBackListener {
@BindView(R.id.et_search)
public EditText searchEt;
@BindView(R.id.tv_search)
@ -55,58 +63,64 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
SwipeRefreshLayout mRefresh;
@BindView(R.id.reuse_ll_loading)
View mLoading;
private LinearLayoutManager mLayoutManager;
private ToolBoxRvAdapter mRvAdapter;
private ToolBoxRvAdapter mNormalRvAdapter;
private boolean mIsSearch; // 记录页面状态 搜索页面/普通页面
private String mSearchKey; // 记录搜索关键字
Runnable runnable = () -> changeAdapter(true);
@NonNull
public static Intent getIntent(Context context, String entrance) {
Intent intent = new Intent(context, ToolBoxActivity.class);
intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance);
return intent;
}
@Override
protected int getLayoutId() {
return R.layout.activity_toolbox;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setNavigationTitle("光环工具箱");
mRefresh.setColorSchemeResources(R.color.theme);
mRefresh.setOnRefreshListener(this);
// 跳转到工具箱 https://gitlab.ghzs.com/pm/halo-app-issues/issues/636
String gameId = getIntent().getStringExtra(EntranceUtils.KEY_GAMEID);
String targetUrl = getIntent().getStringExtra(EntranceUtils.KEY_URL);
if (!TextUtils.isEmpty(targetUrl) && !TextUtils.isEmpty(gameId)) {
findGameAndOpenItsToolboxWebview(gameId, targetUrl);
}
mLayoutManager = new LinearLayoutManager(this);
mToolboxRv.setLayoutManager(mLayoutManager);
mRvAdapter = new ToolBoxRvAdapter(this, this, mIsSearch, mSearchKey);
mToolboxRv.addItemDecoration(new VerticalItemDecoration(this, 8, false));
mToolboxRv.setAdapter(mRvAdapter);
mNormalRvAdapter = mRvAdapter;
mToolboxRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE
&& mLayoutManager.findLastVisibleItemPosition() + 1 == mRvAdapter.getItemCount()) {
if (newState == RecyclerView.SCROLL_STATE_IDLE && mLayoutManager.findLastVisibleItemPosition() + 1 == mRvAdapter
.getItemCount()) {
if (!mRvAdapter.isOver() && !mRvAdapter.isLoading() && !mRvAdapter.isNetworkError()) {
mRvAdapter.loadData();
}
}
}
});
mAppBar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
if (verticalOffset == 0) {
mRefresh.setEnabled(true);
@ -118,17 +132,38 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
Util_System_Keyboard.hideSoftKeyboard(this);
}
});
initSearch();
}
private void findGameAndOpenItsToolboxWebview(String gameId, String url) {
RetrofitManager.getInstance(this)
.getApi()
.getGameToolBoxData(1, UrlFilterUtils.getFilterQuery("game_id", gameId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<ToolBoxEntity>>() {
@Override
public void onResponse(@Nullable List<ToolBoxEntity> response) {
if (response == null) return;
for (ToolBoxEntity toolbox : response) {
if (url.equals(toolbox.getUrl())) {
Intent intent = WebActivity.getWebByCollectionTools(ToolBoxActivity.this, toolbox, false);
startActivity(intent);
}
}
}
});
}
private void initSearch() {
backTv.setOnClickListener(v -> search(false, searchEt.getText().toString()));
TextHelper.limitTheLengthOfEditText(searchEt, 20, () -> {
Utils.toast(this, "最多输入20字");
});
searchTv.setOnClickListener(v -> {
if (TextUtils.isEmpty(searchEt.getText().toString())) {
Utils.toast(this, R.string.search_hint);
@ -136,13 +171,13 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
}
search(true, searchEt.getText().toString());
});
searchEt.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
Util_System_Keyboard.hideSoftKeyboard(this, searchEt);
}
});
searchEt.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
searchTv.performClick();
@ -150,8 +185,8 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
return false;
});
}
@OnClick({R.id.reuse_no_connection, R.id.reuse_none_data})
public void onClick(View view) {
if (view.getId() == R.id.reuse_no_connection) {
@ -165,7 +200,7 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
}
}
}
@Override
public void loadDone() {
mRefresh.setRefreshing(false);
@ -173,12 +208,12 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
mNoConnection.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
}
@Override
public void loadDone(Object obj) {
}
@Override
public void loadEmpty() {
mRefresh.setRefreshing(false);
@ -191,7 +226,7 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
mNoneDataTv.setText(getResources().getString(R.string.game_empty));
}
}
@Override
public void loadError() {
mRefresh.setRefreshing(false);
@ -199,12 +234,12 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
mNoConnection.setVisibility(View.VISIBLE);
mLoading.setVisibility(View.GONE);
}
@Override
public void onRefresh() {
mRefresh.postDelayed(runnable, 1000);
}
public void search(boolean isSearch, String searchKey) {
if (mNoneData.getVisibility() == View.VISIBLE) {
mNoneData.setVisibility(View.GONE);
@ -216,7 +251,7 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
mSearchKey = searchKey;
changeAdapter(false);
}
private void changeAdapter(boolean isRefresh) {
if (mIsSearch) {
mRvAdapter = new ToolBoxRvAdapter(this, this, mIsSearch, mSearchKey);
@ -229,12 +264,12 @@ public class ToolBoxActivity extends BaseActivity implements SwipeRefreshLayout.
}
}
mToolboxRv.setAdapter(mRvAdapter);
if (mSearchKey != null) {
searchEt.setText(mSearchKey);
searchEt.setSelection(searchEt.getText().length());
}
if (mIsSearch) {
backTv.setVisibility(View.VISIBLE);
} else {

View File

@ -18,12 +18,6 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
import com.facebook.binaryresource.BinaryResource;
import com.facebook.cache.common.CacheKey;
import com.facebook.common.executors.CallerThreadExecutor;
@ -37,9 +31,11 @@ import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.gh.base.BaseActivity;
import com.gh.common.Base64ImageHolder;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MD5Utils;
import com.gh.common.util.MessageShareUtils;
import com.gh.common.util.NetworkUtils;
import com.gh.common.util.PermissionHelper;
@ -63,6 +59,11 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
import butterknife.BindView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -89,7 +90,11 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
private ViewImageAdapter adapter;
private ImagePipeline mImagePipeline;
private boolean mShowBase64Image = false;
private static final String KEY_BASE64 = "base64";
private static final String KEY_URLS = "urls";
private static final String KEY_CURRENT = "current";
private static final String KEY_SCALETYPE = "ScaleType";
@ -101,6 +106,12 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
private int mLimitWidth;
private boolean isOrientation;
public static Intent getBase64ViewImageIntent(Context context, boolean showSingleBase64Image) {
Intent checkIntent = new Intent(context, ViewImageActivity.class);
checkIntent.putExtra(KEY_BASE64, showSingleBase64Image);
return checkIntent;
}
public static Intent getViewImageIntent(Context context, ArrayList<String> list, int position, String entrance) {
Intent checkIntent = new Intent(context, ViewImageActivity.class);
@ -125,8 +136,14 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
int current = 0;
Bundle extras = getIntent().getExtras();
if (extras != null) {
urls = extras.getStringArrayList(KEY_URLS);
current = extras.getInt(KEY_CURRENT, 0);
if (extras.getBoolean(KEY_BASE64)) {
mShowBase64Image = true;
urls = new ArrayList<>();
urls.add(Base64ImageHolder.INSTANCE.getImage());
} else {
urls = extras.getStringArrayList(KEY_URLS);
current = extras.getInt(KEY_CURRENT, 0);
}
}
if (savedInstanceState != null) {
@ -190,6 +207,8 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
.build());
}
});
DisplayUtils.transparentStatusAndNavigation(this);
}
@Override
@ -202,6 +221,10 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
@Override
protected void onDestroy() {
super.onDestroy();
if (mShowBase64Image) {
urls.clear();
Base64ImageHolder.INSTANCE.setImage("");
}
mViewPager.onDestroy(); // 注销EventBus
}
@ -414,8 +437,15 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
}
private void saveImage(Bitmap bitmap, String curUrl) {
String fileName = "";
if (mShowBase64Image) {
fileName = MD5Utils.getUrlMD5(curUrl.substring(0, 50)) + ".png";
} else {
fileName = curUrl.substring(curUrl.lastIndexOf("/"));
}
String fileName = curUrl.substring(curUrl.lastIndexOf("/"));
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
try {

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.entity.ConcernEntity;
@ -39,6 +40,15 @@ public class WebActivity extends NormalActivity {
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getUploadProtocolIntent(Context context) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_GAMENAME, context.getString(R.string.upload_protocol_title));
bundle.putString(EntranceUtils.KEY_URL, context.getString(R.string.upload_protocol_url));
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getPrivacyPolicyIntent(Context context) {
Bundle bundle = new Bundle();
@ -46,6 +56,13 @@ public class WebActivity extends NormalActivity {
bundle.putString(EntranceUtils.KEY_URL, context.getString(R.string.privacy_policy_url));
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getUploadPolicyIntent(Context context) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_GAMENAME, context.getString(R.string.upload_game_policy_title));
bundle.putString(EntranceUtils.KEY_URL, context.getString(R.string.upload_game_policy_url));
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getCommentRulesIntent(Context context) {
@ -93,4 +110,13 @@ public class WebActivity extends NormalActivity {
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@Override
protected View.OnClickListener provideNavigationItemClickListener() {
Bundle bundle = getIntent().getBundleExtra(NORMAL_FRAGMENT_BUNDLE);
if (bundle != null && bundle.getBoolean(WebFragment.KEY_ISTOOLS, false)) {
return view -> finish();
} else {
return super.provideNavigationItemClickListener();
}
}
}

View File

@ -4,8 +4,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
@ -22,6 +22,8 @@ import com.sina.weibo.sdk.share.WbShareCallback;
import com.sina.weibo.sdk.share.WbShareHandler;
import com.sina.weibo.sdk.utils.Utility;
import androidx.annotation.NonNull;
/**
* Created by khy on 2016/11/23.
* <p>
@ -88,12 +90,19 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
@Override
protected void onNewResultImpl(Bitmap bitmap) {
Utils.log("分享获取bitmap成功准备分享");
if (ShareUtils.ShareType.video.name().equals(mShareType)) {
// 分享类型为视频时裁为正方形
int dimension = Math.min(bitmap.getWidth(), bitmap.getHeight());
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);
}
Bitmap compressBp = ShareUtils.compressBitmap(bitmap);
Bitmap bgBitmap;
if (ShareUtils.ShareType.askInvite.name().equals(mShareType) || ShareUtils.ShareType.askNormal.name().equals(mShareType)) {
bgBitmap = compressBp;
} else {
} else {
bgBitmap = ShareUtils.getInstance(getApplicationContext()).addBackGround(compressBp);
}

View File

@ -1,8 +1,6 @@
package com.gh.gamecenter.adapter;
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
@ -10,7 +8,8 @@ import android.view.ViewGroup;
import com.gh.common.constant.ItemViewType;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CommentUtils;
import com.gh.gamecenter.PersonalHomeActivity;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.TextHelper;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder;
@ -25,6 +24,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@ -152,8 +153,8 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
CommentUtils.setCommentUserView(mContext, holder, commentEntity);
CommentUtils.setCommentTime(holder.commentTimeTv, commentEntity.getTime());
holder.commentContentTv.setText(commentEntity.getContent());
TextHelper.highlightTextThatIsWrappedInsideWrapperByDefault(holder.commentContentTv, commentEntity.getContent());
ArticleCommentParent parent = commentEntity.getParent();
if (parent != null && !TextUtils.isEmpty(parent.getUser().getName())) {
holder.quoteContainer.setVisibility(View.VISIBLE);
@ -166,7 +167,7 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
content = mContext.getString(R.string.comment_hide_hint);
holder.quoteContentTv.setTextColor(mContext.getResources().getColor(R.color.text_d5d5d5));
}
holder.quoteContentTv.setText(content);
TextHelper.highlightTextThatIsWrappedInsideWrapperByDefault(holder.quoteContentTv, content);
} else {
holder.quoteContainer.setVisibility(View.GONE);
}
@ -182,8 +183,8 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
mContext, false,
mOnCommentCallBackListener, null, "资讯文章-评论"));
holder.commentUserIconDv.setOnClickListener(v -> PersonalHomeActivity.startTargetActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> PersonalHomeActivity.startTargetActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
if (commentEntity.getPriority() != 0) {
holder.commentBadge.setVisibility(View.VISIBLE);

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