Compare commits

...

271 Commits

Author SHA1 Message Date
82a859e820 tinker-base-3.7.4-bugfix 2020-03-24 10:40:08 +08:00
c7db58f6ea 处理一些闪退异常 2020-03-23 15:18:27 +08:00
79ff887375 修复一些闪退问题 2020-03-23 13:35:46 +08:00
4f68f30576 修复玩过的游戏统计异常 2020-03-23 11:27:37 +08:00
0683a579c0 tinker_base 3.7.4 2020-03-18 19:21:45 +08:00
f1194d434b 帮助与反馈拼接标题 2020-03-18 18:21:10 +08:00
59e80970ae tinker_base 3.7.4 2020-03-18 14:36:31 +08:00
92a0d77885 光环助手V3.7.4-测试问题汇总(20200311-1900)10 https://gitlab.ghzs.com/pm/halo-app-issues/issues/797 2020-03-17 16:07:35 +08:00
1bc0b0e085 tinker_base 3.7.4 2020-03-17 09:57:08 +08:00
a5129c809b 完成复刻工具箱礼包码跳转游戏详情礼包项的需求 https://gitlab.ghzs.com/pm/halo-app-issues/issues/807 2020-03-16 21:12:40 +08:00
3e8e5572d2 修复未登录状态下游戏详情动态 tab 的礼包不显示领取按钮的问题 2020-03-16 21:06:26 +08:00
862b66f8e7 回退启动页更改(在全屏下拉伸比较严重,无奈~) 2020-03-16 15:25:32 +08:00
15fad5635b 避免原因未知的闪退 2020-03-13 19:04:00 +08:00
bddde8c851 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-12 16:28:06 +08:00
b589c38eea 尝试修复启动图适配问题 2020-03-12 16:27:47 +08:00
5c3cdf227e 解决第一次滑动视频闪退 2020-03-12 16:27:29 +08:00
838b775a3e 光环助手V3.7.4-测试问题汇总(20200311-1900)3,4 https://gitlab.ghzs.com/pm/halo-app-issues/issues/797 2020-03-12 15:52:19 +08:00
7af2b7c2d7 api版本改为3.7.4
修改社区问题的点击效果
2020-03-11 17:33:49 +08:00
f78570ce80 答案/文章富文本编辑框添加meta避免缩放 2020-03-11 15:56:27 +08:00
071376267a 修复点击动态页进入问答的闪退问题 2020-03-11 15:55:04 +08:00
51c3d25f3a 调整 Entity 命名 2020-03-11 11:44:20 +08:00
cc6c31027a 修复进入已关注游戏的游戏详情不会自动切换到动态tab的问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/783 2020-03-11 11:24:54 +08:00
f3b91b63ec 完成游戏详情加载优化(将接口分为用户相关和用户不相关两部分) https://gitlab.ghzs.com/pm/halo-app-issues/issues/783 2020-03-10 21:30:36 +08:00
48b8c0d23e 去掉无用的 ijk so 减小应用体积 2020-03-10 14:23:52 +08:00
c56826b29d Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-10 13:53:25 +08:00
28ec3ef5dc 全局拦截参数缺失的非法请求 2020-03-10 13:53:09 +08:00
c3b8538ac3 修复在部分老旧设备上 webview 标题回调异常的问题 2020-03-09 17:48:00 +08:00
f04b1c4300 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-09 16:46:41 +08:00
1d7c8b894f 社区回答/文章编辑,插入回答-收藏回答去除修改红点提示 2020-03-09 16:46:29 +08:00
afd1232cea Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-09 15:59:03 +08:00
2b141e79cd 修改会刷到重复视频问题 2020-03-09 15:58:30 +08:00
f6e452237a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-09 15:08:18 +08:00
508dff3bae 尝试修复游戏库闪屏问题 2020-03-09 15:08:03 +08:00
1259199e2c 删除一些无用代码 2020-03-09 15:05:00 +08:00
85fc2dda02 更换首页安利墙和评分字体颜色 2020-03-09 10:36:44 +08:00
d57a6879fb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-07 10:58:18 +08:00
c0f32124ad 回退WebFragment的修改 2020-03-07 10:57:46 +08:00
b3a53f51b0 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-06 18:25:55 +08:00
66175c7f20 光环助手V4.0-测试问题汇总(20200304-1900)UI测试补充 https://gitlab.ghzs.com/pm/halo-app-issues/issues/796 2020-03-06 18:25:22 +08:00
dc698ca2cc 微调社区相关UI 2020-03-06 16:40:43 +08:00
6d8c703f33 再次调整视频双击点赞时间间隔 2020-03-06 16:15:22 +08:00
f32e6b60d1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-06 15:12:22 +08:00
f45d1ded17 光环助手V4.0-测试问题汇总(20200304-1900)5,11 https://gitlab.ghzs.com/pm/halo-app-issues/issues/796 2020-03-06 15:12:00 +08:00
da9eac4ecd 修复RichEditor个别机型插入自定义样式无法跳转问题 2020-03-06 15:07:34 +08:00
b58d52709f 光环助手V4.0-视频相关测试汇总(正式环境)19-23 https://gitlab.ghzs.com/pm/halo-app-issues/issues/794 2020-03-06 15:05:46 +08:00
3cde5cc39d 修复游戏搜索多次输入相同关键字时,只有首次触发的问题 2020-03-06 14:28:08 +08:00
50214e7461 修复首页可能出现的无响应问题(改了这个又不能防止抖动了)
社区问答/文章发表评论对接关闭评论和隐藏状态
 修改社区评论/资讯评论可以回复自己的BUG
2020-03-06 12:02:23 +08:00
dc0994d084 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.
2020-03-05 19:46:00 +08:00
f79a45e533 光环助手V4.0-测试问题汇总(20200304-1900)(14.16) https://gitlab.ghzs.com/pm/halo-app-issues/issues/796 2020-03-05 19:45:14 +08:00
b704e47322 光环助手V4.0-测试问题汇总(20200304-1900)完成4,7,8,9 https://gitlab.ghzs.com/pm/halo-app-issues/issues/796 2020-03-05 17:47:35 +08:00
dab9f850ba Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-05 15:41:58 +08:00
e7073bf010 修改视频流非Wifi弹窗只弹一次 2020-03-05 15:41:35 +08:00
c1ab9617ad 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.
2020-03-05 14:54:33 +08:00
c6d9026333 修改问题详情图标 2020-03-05 14:53:14 +08:00
42dae5c993 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-05 12:06:26 +08:00
a3af3dcf9b 调整视频双击点赞时间间隔 2020-03-05 12:05:59 +08:00
ba15462981 修复部分列表社区文章无法点赞问题 2020-03-05 11:33:29 +08:00
c29066eb46 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-05 11:07:30 +08:00
0464a859d2 尝试修复OnErrorNotImplementedException 2020-03-05 11:07:13 +08:00
962ff89833 避免原因未知的数组越界异常 2020-03-05 11:02:55 +08:00
74a40ebe97 在自动编译安装包的反馈闪退内容中添加编译时间帮助定位问题 2020-03-05 10:57:55 +08:00
686b454abe Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-05 10:32:03 +08:00
6d54ddea60 修复资讯文章评论后用户ID错误问题 2020-03-05 10:31:55 +08:00
d005403f65 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-04 18:19:27 +08:00
8e907f5221 恢复顶部视频非wifi不自动播放 2020-03-04 18:19:05 +08:00
96bb953d9d 更换部分图标 2020-03-04 18:15:22 +08:00
78b581b376 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-04 18:01:59 +08:00
ef7edb4a9e 社区回答/文章列表增加隐藏和关闭评论判断 2020-03-04 18:01:51 +08:00
4bf5ae40e2 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-04 16:44:32 +08:00
22ebdc0e87 添加卡顿检测BlockCanary 2020-03-04 16:44:19 +08:00
01bd1628cf 光环助手V4.0-视频相关测试汇总(正式环境)17,18 https://gitlab.ghzs.com/pm/halo-app-issues/issues/794 2020-03-04 16:39:18 +08:00
7de88bc8ad 修复下载流量提醒在某个别设备toast样式不同问题 2020-03-04 14:41:43 +08:00
1a01e2dd4d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-04 11:55:25 +08:00
9e20c7082a 回退关注问题/我的问题UI代码到v3.7.3 2020-03-04 11:55:15 +08:00
74cb2f253b Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-04 11:25:08 +08:00
cf41d2e4a7 我的光环分组小红点添加描边 2020-03-04 11:24:44 +08:00
f232adaa98 修复隐私弹窗内容不居中问题 2020-03-04 11:18:21 +08:00
713af4bf12 修复首页横向专题刷新问题 2020-03-04 09:53:46 +08:00
f0f1906ffc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-03 18:21:19 +08:00
3da6444ede 光环助手V4.0-测试问题汇总(UI相关)https://gitlab.ghzs.com/pm/halo-app-issues/issues/795 2020-03-03 18:21:10 +08:00
f149c56617 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-03 17:44:02 +08:00
9915a18656 解决视频点赞动画点击边缘变小问题 2020-03-03 17:43:40 +08:00
2173e5a91c 光环助手V4.0-视频相关测试汇总(正式环境)13 https://gitlab.ghzs.com/pm/halo-app-issues/issues/794 2020-03-03 17:43:08 +08:00
4a6866d8fd 完成测试问题汇总(20200228-1930)的1(4) https://gitlab.ghzs.com/pm/halo-app-issues/issues/793 2020-03-03 16:11:10 +08:00
ddc324bcf1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-03 15:42:08 +08:00
daba7e0d12 完成光环助手V4.0-测试问题汇总(20200228-1930)14 https://gitlab.ghzs.com/pm/halo-app-issues/issues/793 2020-03-03 15:41:42 +08:00
6203b80c4e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-03 15:12:38 +08:00
416cbe7e82 光环助手V4.0-测试问题汇总(20200228-1930)(1(2),1(5),1(6),2,3,4,5,6,7,10,11,12) https://gitlab.ghzs.com/pm/halo-app-issues/issues/793 2020-03-03 15:12:30 +08:00
e28ce4d099 完成20200303补充11,12 https://gitlab.ghzs.com/pm/halo-app-issues/issues/794 2020-03-03 10:56:19 +08:00
d1f5ec6c2e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-02 18:31:49 +08:00
166f44bb1d 光环助手V4.0-视频相关测试汇总(正式环境)https://gitlab.ghzs.com/pm/halo-app-issues/issues/794 2020-03-02 18:31:30 +08:00
c8a0420b21 修改隐私弹窗UI 2020-03-02 18:31:09 +08:00
a3d7d9cb81 处理视频滑动冲突 2020-03-02 15:13:27 +08:00
b6d49c88db Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-02 14:45:48 +08:00
8572f8eaf4 修改视频点赞效果 2020-03-02 14:45:07 +08:00
c533cd021f 社区回答/文章列表增加防抖操作 2020-02-28 19:00:40 +08:00
3eb1af7e23 修改社区回答/文章列表混合状态时点赞和评论异常问题 2020-02-28 18:40:24 +08:00
97188a7d9c Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-28 17:56:34 +08:00
e29ffa3d13 光环助手V4.0.0-问答社区优化汇总(2200226测试)
https://gitlab.ghzs.com/pm/halo-app-issues/issues/768
2020-02-28 17:56:16 +08:00
5b772a0537 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-28 16:52:23 +08:00
82a8888676 修改一些UI问题 2020-02-28 16:52:01 +08:00
bf8630756a 回退视频上传转码中相关代码 2020-02-28 16:24:37 +08:00
35fc381162 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-28 15:42:10 +08:00
f72342ac72 社区测试汇总 2020-02-28 15:42:04 +08:00
5a6e528c65 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-28 14:46:03 +08:00
4eb52c91a4 设备未安装“抖音”应用,直接打开网页 2020-02-28 14:45:41 +08:00
77bc1594aa 回答和文章列表增加取消点赞操作 2020-02-28 13:26:12 +08:00
23267ec0ee 回退关注问题/我的问题UI代码 2020-02-28 12:44:41 +08:00
1b1bd3264a Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-28 12:08:33 +08:00
b954c1f664 修复游戏库刷新替换抖动的问题 2020-02-28 12:08:21 +08:00
707beb9672 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-28 11:53:31 +08:00
b2f5a19bde 更换视频点赞动画 2020-02-28 11:52:56 +08:00
e24d7f1045 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-28 10:57:47 +08:00
142a64d261 修复上传视频修改封面图闪退问题
回答/文章列表点赞时检查登录状态
2020-02-28 10:57:29 +08:00
2ef98fd050 完成游戏详情加载优化的0228测试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/783 2020-02-28 10:00:04 +08:00
2f3c387c16 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-27 18:16:10 +08:00
83b97a9de9 修复评论标签显示问题 2020-02-27 18:15:38 +08:00
97becbea2e 修改字体/色块颜色 2020-02-27 18:13:34 +08:00
8361609c70 merge change_theme_color into dev 2020-02-27 18:07:13 +08:00
eb7d871e70 修复收藏文章提交已读信息闪退问题 2020-02-27 16:24:22 +08:00
d06ab34db1 下载互斥弹窗逻辑修改 2020-02-27 16:18:42 +08:00
d59f604c7e Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-27 16:01:37 +08:00
a8d9bb9180 修改隐私弹窗 2020-02-27 16:01:27 +08:00
db90717617 双击点赞toast多次只显示一次 2020-02-27 15:50:03 +08:00
f916c7b8a5 修改游戏库刷新替换规则 2020-02-27 13:56:53 +08:00
4e410e3ea3 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-27 12:32:04 +08:00
5a5fb7a5cc 修改评论输入框UI 2020-02-27 12:31:22 +08:00
233a2172f1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-26 18:00:37 +08:00
6376973a61 修复线程池线程数量不够报错,改用newCachedThreadPool 2020-02-26 18:00:04 +08:00
5dd6d73603 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-26 17:54:12 +08:00
5918b35793 修改社区专题详情UI 2020-02-26 17:53:52 +08:00
10c3536b2b 修改问答专题徽章显示问题 2020-02-26 17:47:49 +08:00
fffef74480 完成光环前端优化汇总(2020年2月第1周)第2点的0226测试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-26 17:36:14 +08:00
c5c2938089 修改App桌面图片 2020-02-26 17:24:58 +08:00
32fe28f536 社区文章/回答列表对接点赞数据 2020-02-26 16:43:27 +08:00
fc4a751b2b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-26 16:08:33 +08:00
e364b7d3b0 修改我的收藏-社区文章/回答UI 2020-02-26 16:08:13 +08:00
bc28e08b3f 处理在子线程调用ExoPlayer方法报错和限制预加载视频50M 2020-02-26 15:38:53 +08:00
69b8155dcd Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-26 13:30:02 +08:00
16254bb578 社区回答/文章相关列表增加多图显示 2020-02-26 13:29:50 +08:00
acc4a5b2aa 20200226补充:1,2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/769 2020-02-26 12:18:53 +08:00
fddce1ebe3 解决视频双击点赞点三次会触发单击事件 2020-02-26 11:13:25 +08:00
7151cba40e 修改上传配置 2020-02-25 18:36:50 +08:00
6cff45eada Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-25 18:10:41 +08:00
a05b4f7b65 全局修改评论相关样式(资讯文章/社区/视频) 2020-02-25 18:10:23 +08:00
e5797a41b7 游戏详情顶部声音问题 2020-02-25 16:51:00 +08:00
9f0191ce0a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-25 16:39:02 +08:00
68a5c472c0 标记我的收藏已读 2020-02-25 16:38:39 +08:00
6c7e6d95ce 删除一些无用资源 2020-02-25 16:31:36 +08:00
ec84bbb4f3 完成游戏详情加载优化 https://gitlab.ghzs.com/pm/halo-app-issues/issues/783 2020-02-25 15:38:02 +08:00
780a8649e3 完成光环前端优化汇总(2020年2月第1周)第2点的0225测试 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-25 15:33:34 +08:00
9aaaf2204a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-25 14:08:39 +08:00
c7f608b9cb 完成0225测试 第6点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-25 14:08:16 +08:00
591885095b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-25 13:18:00 +08:00
3bcdd37837 修改游戏搜索“找不到想要的游戏”悬浮窗的显示规则 2020-02-25 13:17:50 +08:00
959c5e4cf5 修改评论作者显示错误 2020-02-25 09:33:11 +08:00
7ecc8446ea Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-24 18:20:41 +08:00
d3809bb699 修改文案 2020-02-24 18:20:31 +08:00
d5113a52fc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-24 18:15:28 +08:00
e2dd868705 完成20200224测试补充 https://gitlab.ghzs.com/pm/halo-app-issues/issues/779 2020-02-24 18:15:05 +08:00
41ae5b9b6b Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-24 18:11:07 +08:00
b0470b3a41 光环助手V4.0.0-插件版本下载互斥弹窗 https://gitlab.ghzs.com/pm/halo-app-issues/issues/788 2020-02-24 18:10:56 +08:00
d371ae9dc5 补充佩戴徽章的显示位置 https://gitlab.ghzs.com/pm/halo-app-issues/issues/778 2020-02-24 17:15:06 +08:00
00124a657d 完成光环前端优化汇总(2020年2月第1周)的第2点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-24 16:52:53 +08:00
620cec08eb Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-24 16:42:54 +08:00
b1205356c8 光环助手V4.0.0-版块(游戏库)优化:新增刷新按钮 https://gitlab.ghzs.com/pm/halo-app-issues/issues/784 2020-02-24 16:42:38 +08:00
e96d6829a4 处理徽章显示异常 2020-02-24 15:08:06 +08:00
0652da2300 完成游戏详情动态 tab 接口的合并 https://gitlab.ghzs.com/pm/halo-app-issues/issues/783 2020-02-22 17:44:08 +08:00
ebe3852132 正式环境接口切换到 4.0.0 2020-02-22 16:58:02 +08:00
1ae73277a9 更换桌面图标 2020-02-21 17:56:55 +08:00
97ec50f8a9 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-21 16:38:43 +08:00
1997a8b296 光环前端优化汇总(2020年2月第3周)(1.2.3.5.6) https://gitlab.ghzs.com/pm/halo-app-issues/issues/791 2020-02-21 16:38:25 +08:00
baae0e5bca 预加载视频封面图 2020-02-21 15:51:52 +08:00
4136bfab42 社区文章/回答列表增加点赞动画 2020-02-20 17:17:25 +08:00
3d64d3c90e 社区问题列表支持跳转至回答编辑页面 2020-02-20 15:59:25 +08:00
7d2835bb83 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-20 15:32:54 +08:00
9ffaa97d70 撰写回答页面问题标题增加收起功能 2020-02-20 15:32:29 +08:00
363751a970 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-20 14:27:42 +08:00
c7218d9c0d 视频点赞取消toast 2020-02-20 14:27:30 +08:00
e9387e29c6 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-20 13:33:59 +08:00
33b4d60882 视频管理后台增加压缩功能(6.7.9.10.11)https://gitlab.ghzs.com/pm/halo-app-issues/issues/785 2020-02-20 13:33:40 +08:00
86537b8f1e 光环前端优化汇总(2020年2月第3周)4 https://gitlab.ghzs.com/pm/halo-app-issues/issues/791 2020-02-20 10:01:15 +08:00
c2e64e2a71 双击点赞引导 2020-02-19 18:28:13 +08:00
79af4945e3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-19 16:56:34 +08:00
f83a50d4c5 添加点赞动画 2020-02-19 16:54:49 +08:00
1868488390 社区文章/回答列表增加点赞和评论功能 2020-02-19 15:54:51 +08:00
4dc71d2d76 光环助手V4.0.0-问答社区优化汇总(4) https://gitlab.ghzs.com/pm/halo-app-issues/issues/768 2020-02-19 15:01:29 +08:00
dca5565f45 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-18 16:11:41 +08:00
aa6294bfd4 光环前端优化汇总(2020年2月第2周)(1) https://gitlab.ghzs.com/pm/halo-app-issues/issues/786 2020-02-18 16:11:18 +08:00
77a6d3f295 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-18 10:47:12 +08:00
10fd6d9aef 光环助手V4.0.0-徽章功能优化汇总4,5 https://gitlab.ghzs.com/pm/halo-app-issues/issues/778 2020-02-18 10:46:46 +08:00
37e6120768 光环助手V4.0.0-视频功能优化(视频详情)1,2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/777 2020-02-18 10:46:18 +08:00
b9defd4a58 光环助手V4.0.0-视频功能优化(上传视频)(3) https://gitlab.ghzs.com/pm/halo-app-issues/issues/776 2020-02-17 17:51:12 +08:00
7f7938fdfa 修改社区搜索样式 2020-02-17 15:30:11 +08:00
7c2f411a48 修改社区文章/回答列表样式 2020-02-17 14:26:37 +08:00
51c152ca5e 使用exo自带缓存策略,重写预加载功能 2020-02-17 11:12:45 +08:00
dc46ee4431 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-14 18:53:40 +08:00
da3ba76547 全局修改社区所有列表UI(未完成)(6)
https://gitlab.ghzs.com/pm/halo-app-issues/issues/768
2020-02-14 18:53:24 +08:00
36a31f28f0 完成光环前端优化汇总(2020年2月第2周)的第4点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/786 2020-02-14 11:57:20 +08:00
450a732f2e 修复4.0.0数据后台统计的 6 https://gitlab.ghzs.com/pm/halo-app-issues/issues/789 2020-02-14 11:56:21 +08:00
b8c5dcf4b4 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-13 17:39:50 +08:00
8ae5eacffe 游戏搜索(游戏搜索索引和游戏搜索结果)页面重构并且游戏搜索结果页面加上分页操作 2020-02-13 17:39:31 +08:00
bb9f7a33fb 修复游戏评论相关Bug汇总的三(2) https://gitlab.ghzs.com/pm/halo-app-issues/issues/774 2020-02-13 17:36:47 +08:00
06f603e975 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-13 16:38:05 +08:00
20c74a1727 光环前端优化汇总(2020年2月第1周)7 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-13 16:37:48 +08:00
5dd3ba43c9 光环前端优化汇总(2020年2月第2周)6 https://gitlab.ghzs.com/pm/halo-app-issues/issues/786 2020-02-12 20:09:30 +08:00
cd749fc1c9 光环前端优化汇总(2020年2月第2周)8,9 https://gitlab.ghzs.com/pm/halo-app-issues/issues/786 2020-02-12 18:08:42 +08:00
6b7610bac8 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-12 17:29:47 +08:00
041f48bdb5 光环前端优化汇总(2020年2月第2周)(2)https://gitlab.ghzs.com/pm/halo-app-issues/issues/786 2020-02-12 17:28:58 +08:00
a1adfb336b 修复在低版本系统上自动安装时的闪退问题 2020-02-12 17:24:37 +08:00
35ff5af974 光环助手V4.0.0-版块(游戏库)优化:新增刷新按钮&显示静态图标(二)
https://gitlab.ghzs.com/pm/halo-app-issues/issues/784
2020-02-12 16:21:11 +08:00
638f324cd2 Merge branch 'exo' into dev 2020-02-12 11:36:33 +08:00
62390f88e5 我的光环小红点 2020-02-12 10:57:15 +08:00
9428604613 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-11 17:32:47 +08:00
610fc444af 光环助手V4.0.0-问答社区优化汇总(5) https://gitlab.ghzs.com/pm/halo-app-issues/issues/768 2020-02-11 17:32:25 +08:00
e5d7b68a85 版本号升级为4.0.0, 测试环境API亦切换至 4.0.0 2020-02-11 17:24:48 +08:00
9e91a53e94 修复新首页轮播图路径记录问题 https://gitlab.ghzs.com/pm/issues-Inbox/issues/2237 2020-02-11 17:23:46 +08:00
fa553238bb overrideLibrary添加exo,最低版本恢复至16 2020-02-11 10:53:03 +08:00
0a579427f4 顶部视频声音问题 2020-02-11 09:53:37 +08:00
921bc29f73 尝试更换exo内核 2020-02-10 18:26:33 +08:00
2864fa0d91 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-10 18:01:05 +08:00
9771fb7f25 光环助手V4.0.0-问答社区优化汇总(2.3) https://gitlab.ghzs.com/pm/halo-app-issues/issues/768 2020-02-10 18:00:45 +08:00
ec5bf05d42 光环助手V4.0.0-视频功能优化(数据与算法)1-3 https://gitlab.ghzs.com/pm/halo-app-issues/issues/781 2020-02-10 15:47:59 +08:00
7257f88993 增加非Wi-Fi环境播放视频提醒 2020-02-10 09:44:28 +08:00
79a5402e83 fix bug 2020-02-07 19:48:07 +08:00
abc899e822 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-07 19:37:44 +08:00
4e96f00ae9 Matisse增加单选模式 2020-02-07 19:37:21 +08:00
48106a8577 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-07 18:36:14 +08:00
dcdba2a9ad 光环助手V4.0.0-视频功能优化(游戏详情顶部视频)1,2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/779 2020-02-07 18:35:54 +08:00
544c7a065f 优化应用进程重建时的状态异常问题 https://gitlab.ghzs.com/halo/assistant-android/issues/16 2020-02-07 17:04:43 +08:00
cd3ed911d2 视频双击点赞(缺少动画) 2020-02-07 15:33:34 +08:00
e95b2a905c Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-07 14:20:32 +08:00
e36209306e 光环助手V4.0.0-我的光环优化汇总 16 https://gitlab.ghzs.com/pm/halo-app-issues/issues/769 2020-02-07 14:20:09 +08:00
af607bc64a 修复由于CDN缓存造成的游戏收录延迟问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/773 2020-02-07 10:31:40 +08:00
450d81a4e3 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-06 19:12:01 +08:00
75c69adc87 修改首页状态栏高度未被消费问题 2020-02-06 19:11:35 +08:00
97b808fa81 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-02-06 17:26:38 +08:00
512ae70b94 尝试修复已安装列表闪退问题 2020-02-06 17:26:12 +08:00
322a31fcac 光环助手V4.0.0-我的光环优化汇总 7-9,13-15 https://gitlab.ghzs.com/pm/halo-app-issues/issues/769 2020-02-06 15:45:30 +08:00
20b6c383e1 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-06 12:39:12 +08:00
e7ff3ab327 光环前端优化汇总(2020年2月第1周)6 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-06 12:38:47 +08:00
60b55bddab 修复安利内容过长导致标签样式无法显示的问题 2020-02-06 11:57:08 +08:00
1898e594dd 完成前端优化汇总(2月第1周)的 3,4,5 https://gitlab.ghzs.com/pm/halo-app-issues/issues/771 2020-02-06 11:56:09 +08:00
09f0704ad2 更换主题色并区分色块颜色与字体颜色
https://gitlab.ghzs.com/pm/halo-app-issues/issues/767
2020-02-05 17:11:04 +08:00
a6cd047b24 增加回调用于确定 activity 销毁状态 2020-02-05 12:01:40 +08:00
37429a4993 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-04 18:29:15 +08:00
47f2b1e62f 完善登录回落功能 https://gitlab.ghzs.com/halo/assistant-android/issues/17 2020-02-04 18:28:47 +08:00
4e5fe8c32d 修复APP放置于后台过长时间被系统回收后再启动时出现的掉登录的问题 2020-02-04 18:26:31 +08:00
2fdf5421ad 统一管理线程分配,减少资源占用 2020-02-04 16:31:45 +08:00
412e6aa0c5 尝试修复后台执行下载行为时没有将进程转换为前台的问题 2020-02-03 18:02:58 +08:00
1fdafeec4e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-02-03 17:55:28 +08:00
ac819893d4 处理闪退问题 2020-02-03 17:54:40 +08:00
118936845e 处理一些闪退问题 2020-02-03 17:15:44 +08:00
4b1ab3453f 我的光环徽章小红点刷新 2020-02-03 16:13:26 +08:00
53690ff46d Merge branch '3.7.2-bugfix' into 'dev'
3.7.2 bugfix

See merge request !10
2020-02-03 10:09:16 +08:00
e9578bdeec 查看大图兼容 BASE64 编码图片 2020-01-22 11:22:25 +08:00
3c4cc4ff7f tinker-3.7.3-base 2020-01-21 16:03:35 +08:00
150d640977 处理标记下载红点闪退问题 2020-01-21 15:30:45 +08:00
a3599af9d1 修改视频预加载闪退问题 2020-01-21 15:23:53 +08:00
1ac1196b20 处理闪退问题 2020-01-21 14:43:03 +08:00
6c5e863a5b 处理MTA分享事件统计错乱问题 2020-01-21 14:19:35 +08:00
15376a5e13 创建 tinker_3.7.3 标记 2020-01-21 11:13:55 +08:00
eaf5b24044 处理看大图的闪退问题 2020-01-21 10:41:53 +08:00
f05c6540f1 Merge branch '3.7.2-bugfix' of gitlab.ghzhushou.com:halo/assistant-android into 3.7.2-bugfix 2020-01-21 10:18:24 +08:00
25dd3ca4df 完成首页游戏评分显示规则调整 https://gitlab.ghzs.com/pm/halo-app-issues/issues/765 2020-01-21 10:16:51 +08:00
6281b4f510 tinker_base 3.7.2-fix_download 2020-01-20 18:17:33 +08:00
2cbc0b0e17 关闭bugly的Crash处理,统一由AppUncaughtHandler处理 2020-01-20 17:10:25 +08:00
f18a0ef72c Merge branch '3.7.2-bugfix' of gitlab.ghzs.com:halo/assistant-android into 3.7.2-bugfix 2020-01-20 17:04:59 +08:00
98fb4fc412 开启bugly的错误上报 2020-01-20 17:03:52 +08:00
73c995c31f Merge branch '3.7.2-bugfix' of gitlab.ghzhushou.com:halo/assistant-android into 3.7.2-bugfix 2020-01-20 16:28:02 +08:00
60dcafe0c1 处理无参启动 DownloadService 会闪退的问题 2020-01-20 16:27:44 +08:00
512 changed files with 9294 additions and 5794 deletions

View File

@ -247,7 +247,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.contrarywind:Android-PickerView:4.1.3'
implementation 'com.contrarywind:Android-PickerView:4.1.8'
implementation "com.scwang.smartrefresh:SmartRefreshLayout:${smartRefreshLayout}"
implementation "net.cachapa.expandablelayout:expandablelayout:${expandableLayout}"
@ -263,8 +263,9 @@ dependencies {
implementation ("com.shuyu:gsyVideoPlayer-java:$gsyVideo",{
exclude module: "gsyvideoplayer-androidvideocache"
})
implementation "com.shuyu:gsyVideoPlayer-armv7a:$gsyVideo"
implementation "com.shuyu:gsyVideoPlayer-x86:$gsyVideo"
implementation "com.shuyu:GSYVideoPlayer-exo2:$gsyVideo"
// implementation "com.shuyu:gsyVideoPlayer-armv7a:$gsyVideo"
// implementation "com.shuyu:gsyVideoPlayer-x86:$gsyVideo"
implementation "com.github.wendux:DSBridge-Android:$dsBridge"
@ -291,6 +292,9 @@ dependencies {
exclude group: 'com.squareup.okhttp3'
})
debugImplementation "com.github.markzhai:blockcanary-android:$blockcanary"
releaseImplementation "com.github.markzhai:blockcanary-no-op:$blockcanary"
implementation project(':libraries:LGLibrary')
implementation project(':libraries:MTA')
implementation project(':libraries:QQShare')

View File

@ -41,6 +41,8 @@
com.shuyu.gsyvideoplayer.armv7a,
com.shuyu.gsyvideoplayer.x86,
com.shuyu.gsy.base,
com.google.android.exoplayer2,
tv.danmaku.ijk.media.exo2,
shuyu.com.androidvideocache,
pl.droidsonroids.gif" />

View File

@ -2,6 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<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">

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"v":"5.6.4","fr":25,"ip":0,"op":35,"w":1080,"h":214,"nm":"点赞","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"椭圆形 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.588],"y":[0]},"t":17,"s":[15]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[468.04,73.68,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.659,0.659,0.333],"y":[0,0,0]},"t":10,"s":[50,50,100]},{"t":19,"s":[150,150,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":1510,"st":10,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"椭圆形 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.588],"y":[0]},"t":27,"s":[15]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[468.04,73.68,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.659,0.659,0.333],"y":[0,0,0]},"t":20,"s":[50,50,100]},{"t":28,"s":[140,140,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":1520,"st":20,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"路径备份 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.602],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.663],"y":[0]},"t":24,"s":[100]},{"t":29,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[531.02,129.675,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.514,0.514,0.333],"y":[0,0,0]},"t":5,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.533,0.533,0.333],"y":[0,0,0]},"t":10,"s":[90,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.586,0.586,0.333],"y":[0,0,0]},"t":15,"s":[95,95,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.499,0.499,0.333],"y":[0,0,0]},"t":19,"s":[90,90,100]},{"t":24,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.33,-8.3],[3.89,0.27],[-4.4,-1.68],[-4.33,-0.67],[-4.08,9.32],[3.33,5.44],[3.39,4.6],[0.87,-3.7],[3.6,-0.86],[1.03,-0.21],[2.34,-0.53],[0.96,1.15],[4.22,5.48],[-1.18,-4.56]],"o":[[1.11,1.71],[-3.89,-0.27],[6.42,2.5],[4.33,0.66],[1.63,-5.32],[-3.34,-5.45],[-1.68,-2.1],[-0.71,3.14],[-3.43,0.95],[-0.57,0.08],[-3.86,1.12],[-3.23,-3.94],[-1.89,-2.28],[2.42,4.64]],"v":[[-5.387,9.698],[-10.717,8.498],[-12.327,15.628],[5.813,21.748],[23.313,11.778],[20.273,-1.202],[11.563,-13.962],[5.393,-12.362],[1.083,-13.722],[-2.087,-9.742],[-5.707,-11.752],[-8.777,-7.572],[-18.297,-20.542],[-23.827,-17.832]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径备份 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0}],"markers":[]}

File diff suppressed because one or more lines are too long

View File

@ -617,3 +617,10 @@ RE.sendElementNameToNative = function() {
}
}
}
// android function to open link
function customLinkgo(self) {
var datas = self.dataset.datas
// console.log(datas)
window.OnLinkClickListener.onClick(datas)
}

View File

@ -133,9 +133,9 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
shareSummary,
shareType);
if (shareType == ShareUtils.ShareType.game || shareType == ShareUtils.ShareType.plugin) {
MtaHelper.onEvent("内容分享", shareTitle + shareSummary);
MtaHelper.onEvent("内容分享", "内容分享", shareTitle + shareSummary);
} else {
MtaHelper.onEvent("内容分享", shareTitle);
MtaHelper.onEvent("内容分享", "内容分享", shareTitle);
}
}
@ -178,12 +178,23 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
@Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
onFinish();
}
}
@Override
protected void onResume() {
super.onResume();
}
/**
* 可凭借此回调确定当前 activity 已经执行了 finish() 处于 isFinishing 状态
* 可在后续进行
*/
protected void onFinish() {
}
@Override
public void onRequestPermissionsResult(int requestCode,

View File

@ -201,7 +201,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
}
R.id.editor_link_game -> {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-游戏")
startActivityForResult(GameActivity.getIntent(this, "插入游戏"), INSERT_GAME_CODE)
startActivityForResult(GameActivity.getIntent(this, GameActivity.INSERT_GAME_TITLE), INSERT_GAME_CODE)
}
R.id.editor_link_video -> {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")

View File

@ -52,7 +52,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
protected boolean isEverPause;
@NonNull
protected String mEntrance;
protected String mEntrance = "";
protected final Handler mBaseHandler = new BaseFragment.BaseHandler(this);

View File

@ -2,14 +2,27 @@ package com.gh.common
import android.os.Handler
import android.os.Looper
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import com.gh.common.AppExecutor.ioExecutor
import com.gh.common.AppExecutor.lightWeightIoExecutor
import com.gh.common.AppExecutor.uiExecutor
import java.util.concurrent.*
/**
* APP 线程池管理类
*
* [ioExecutor] 是一个最大线程数固定的线程池,较为繁重的 IO 任务可以交给它
* [uiExecutor] 是主线程的包裹,需要切换至主线程执行可以用它
* [lightWeightIoExecutor] 是一个单线程的线程池,轻量级且需要保证同一线程的 IO 任务可以交给它
*
*/
object AppExecutor {
@JvmStatic
var ioExecutor = Executors.newSingleThreadExecutor()
@JvmStatic
var uiExecutor = MainThreadExecutor()
@JvmStatic
var lightWeightIoExecutor = Executors.newSingleThreadExecutor()
@JvmStatic
var ioExecutor = Executors.newCachedThreadPool()
class MainThreadExecutor : Executor {
private val mainThreadHandler = Handler(Looper.getMainLooper())
@ -24,8 +37,12 @@ object AppExecutor {
}
}
fun runOnIoThread(f: () -> Unit) {
AppExecutor.ioExecutor.execute(f)
fun runOnIoThread(isLightWeightTask: Boolean = false, f: () -> Unit) {
if (isLightWeightTask) {
AppExecutor.lightWeightIoExecutor.execute(f)
} else {
AppExecutor.ioExecutor.execute(f)
}
}
fun runOnUiThread(f: () -> Unit) {

View File

@ -15,7 +15,6 @@ import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.subject.SubjectActivity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
object DefaultWebViewUrlHandler {
@ -36,7 +35,7 @@ object DefaultWebViewUrlHandler {
when (host) {
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
"game" -> GameDetailActivity.startGameDetailActivity(context, id, entrance)
"game" -> GameDetailActivity.startGameDetailActivity(context, id, "libao" == uri.getQueryParameter("to"), entrance)
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
@ -116,13 +115,17 @@ object DefaultWebViewUrlHandler {
val categoryId = uri.getQueryParameter("category_id") ?: ""
val link = uri.getQueryParameter("link") ?: ""
val linkEntity = VideoLinkEntity(title, categoryId, link)
if (!CheckLoginUtils.isLogin()) {
HaloApp.put(EntranceUtils.HOST_UPLOAD_VIDEO, linkEntity)
}
CheckLoginUtils.checkLogin(context, EntranceUtils.ENTRANCE_BROWSER) {
// if (!CheckLoginUtils.isLogin()) {
// HaloApp.put(EntranceUtils.HOST_UPLOAD_VIDEO, linkEntity)
// }
CheckLoginUtils.checkLogin(context, null, true, EntranceUtils.ENTRANCE_BROWSER) {
DirectUtils.directToVideoManager(context, linkEntity, EntranceUtils.ENTRANCE_BROWSER, "")
}
}
EntranceUtils.HOST_USERHOME -> {
val position = uri.getQueryParameter("position")
DirectUtils.directToHomeActivity(context, id, if(position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
}
else -> DialogUtils.showLowVersionDialog(context)
}
return true

View File

@ -9,7 +9,7 @@ import com.halo.assistant.HaloApp
import java.util.concurrent.Executors
/**
* 统计用户在当前 Fragment 的停留时间,在 onViewDestroy 或 onDestroy 里获取 elapsedTime 即可,单位为秒
* 统计用户在当前 Fragment/Activity 的停留时间,在 onViewDestroy 或 onDestroy 里获取 elapsedTime 即可,单位为秒
*/
class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {

View File

@ -0,0 +1,31 @@
package com.gh.common.avoidcallback;
import android.content.Intent;
public class ActivityResultInfo {
private int resultCode;
private Intent data;
public ActivityResultInfo(int resultCode, Intent data) {
this.resultCode = resultCode;
this.data = data;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public Intent getData() {
return data;
}
public void setData(Intent data) {
this.data = data;
}
}

View File

@ -0,0 +1,48 @@
package com.gh.common.avoidcallback
import android.content.Intent
import android.os.Bundle
import android.util.SparseArray
import androidx.fragment.app.Fragment
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
class AvoidOnResultFragment : Fragment() {
private val mSubjects = SparseArray<PublishSubject<ActivityResultInfo>>()
private val mCallbacks = SparseArray<Callback>()
private var requestCode = 1000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}
fun startForResult(intent: Intent): Observable<ActivityResultInfo> {
val subject = PublishSubject.create<ActivityResultInfo>()
return subject.doOnSubscribe {
mSubjects.put(requestCode, subject)
startActivityForResult(intent, requestCode)
requestCode++
}
}
fun startForResult(intent: Intent, callback: Callback) {
mCallbacks.put(requestCode, callback)
startActivityForResult(intent, requestCode)
requestCode++
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val subject = mSubjects.get(requestCode)
if (subject != null) {
subject.onNext(ActivityResultInfo(resultCode, data))
subject.onComplete()
}
mSubjects.remove(requestCode)
val callback = mCallbacks.get(requestCode)
callback?.onActivityResult(resultCode, data)
mCallbacks.remove(requestCode)
}
}

View File

@ -0,0 +1,64 @@
package com.gh.common.avoidcallback
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import io.reactivex.Observable
class AvoidOnResultManager {
val TAG = "AvoidOnResultManager"
private var mAvoidOnResultFragment: AvoidOnResultFragment
private constructor(activity: AppCompatActivity) {
mAvoidOnResultFragment = getAvoidOnResultFragment(activity)
}
private constructor(fragment: Fragment) : this(fragment.activity as AppCompatActivity)
companion object {
fun getInstance(activity: AppCompatActivity): AvoidOnResultManager {
return AvoidOnResultManager(activity)
}
fun getInstance(fragment: Fragment): AvoidOnResultManager {
return AvoidOnResultManager(fragment)
}
}
private fun getAvoidOnResultFragment(activity: AppCompatActivity): AvoidOnResultFragment {
var avoidOnResultFragment = findAvoidOnResultFragment(activity)
if (avoidOnResultFragment == null) {
avoidOnResultFragment = AvoidOnResultFragment()
val fragmentManager = activity.supportFragmentManager
fragmentManager
.beginTransaction()
.add(avoidOnResultFragment, TAG)
.commitAllowingStateLoss()
fragmentManager.executePendingTransactions()
}
return avoidOnResultFragment
}
private fun findAvoidOnResultFragment(activity: AppCompatActivity): AvoidOnResultFragment? {
return activity.supportFragmentManager.findFragmentByTag(TAG) as? AvoidOnResultFragment
}
fun startForResult(intent: Intent, callback: Callback) {
mAvoidOnResultFragment.startForResult(intent, callback)
}
fun startForResult(clazz: Class<*>, callback: Callback) {
val intent = Intent(mAvoidOnResultFragment.activity, clazz)
mAvoidOnResultFragment.startForResult(intent, callback)
}
fun startForResult(intent: Intent): Observable<ActivityResultInfo> {
return mAvoidOnResultFragment.startForResult(intent)
}
fun startForResult(clazz: Class<*>): Observable<ActivityResultInfo> {
val intent = Intent(mAvoidOnResultFragment.activity, clazz)
return mAvoidOnResultFragment.startForResult(intent)
}
}

View File

@ -0,0 +1,7 @@
package com.gh.common.avoidcallback
import android.content.Intent
interface Callback {
fun onActivityResult(resultCode: Int, data: Intent?)
}

View File

@ -44,12 +44,24 @@ public class Constants {
public static final String SP_SHOWED_NOTIFICATION_NEW_VERSION = "show_notification_new_version";
// 今天是否已经触发了 “通知管理” 引导弹窗
public static final String SP_IS_SHOWED_NOTIFICATION_TODAY = "show_is_notification_today";
// 标记安装的游戏为已玩过弹窗最多取消2次 (https://gitlab.ghzs.com/pm/halo-app-issues/issues/722 调整为版本相关) (不是常量了也放这里好像有点奇怪)
// v4.0.0已废弃,标记安装的游戏为已玩过弹窗最多取消2次 (https://gitlab.ghzs.com/pm/halo-app-issues/issues/722 调整为版本相关) (不是常量了也放这里好像有点奇怪)
public static final String SP_MARK_INSTALLED_GAME = "mark_installed_game" + PackageUtils.getVersionName();
// 标记安装的游戏为已玩过弹窗(个人主页最多弹一次)
public static final String SP_MARK_INSTALLED_GAME_USER_HOME = "mark_installed_game_user_home" + PackageUtils.getVersionName();
// 标记安装的游戏为已玩过弹窗(我的游戏最多弹一次)
public static final String SP_MARK_INSTALLED_GAME_MY_GAME = "mark_installed_game_my_game" + PackageUtils.getVersionName();
//视频详情滑动引导
public static final String SP_SHOW_SLIDE_GUIDE = "show_slide_guide";
//视频详情点击引导
public static final String SP_SHOW_CLICK_GUIDE = "show_click_guide";
//视频详情双击点赞引导
public static final String SP_SHOW_DOUBLE_CLICK_GUIDE = "show_double_click_guide";
//顶部视频声音状态,重启恢复
public static final String SP_TOP_VIDEO_VOICE = "top_video_voice";
//我的光环提醒设置已读
public static final String SP_ADDONS_FUNCS_HAVE_READ = "addons_funcs_have_read";
//视频非wifi提醒只提醒一次重启恢复
public static final String SP_NON_WIFI_TIPS = "non_wifi_tips";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
@ -84,7 +96,9 @@ public class Constants {
public static final int COMMENT_CD = 60 * 1000;
//我的光环功能分组 cd间隔
public static final int ADDONS_CD = 10 * 60 * 1000;
//已收录包名更新 cd间隔
public static final int PACKAGES_CD = 60 * 1000;
public static final String[] REPORT_LIST = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它"};
public static final String ENTRANCE_UNKNOWN = "(unknown)";

View File

@ -38,7 +38,7 @@ class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
topMargin = DisplayUtils.dip2px(12f)
}
siteTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
siteTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme))
siteTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font))
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {

View File

@ -4,6 +4,7 @@ import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import com.gh.base.CurrentActivityHolder
import com.gh.common.runOnIoThread
import com.gh.common.util.SPUtils
import com.gh.common.util.tryWithDefaultCatch
import com.gh.gamecenter.BuildConfig
@ -128,7 +129,7 @@ object ImManager {
@JvmStatic
fun sendFeedbackMessage(message: String) {
val fromToMessage = IMMessage.createTxtMessage(message)
HaloApp.getInstance().mainExecutor.execute {
runOnIoThread {
tryWithDefaultCatch {
IMChat.getInstance().sendMessage(fromToMessage, object : ChatListener {
override fun onProgress(p0: Int) {}

View File

@ -1,13 +1,17 @@
package com.gh.common.util;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import com.gh.common.avoidcallback.Callback;
import com.gh.gamecenter.LoginActivity;
import com.gh.gamecenter.manager.UserManager;
import com.lightgame.utils.Utils;
import org.jetbrains.annotations.Nullable;
/**
* Created by khy on 28/06/17.
*/
@ -32,6 +36,28 @@ public class CheckLoginUtils {
}
}
public static void checkLogin(final Context context, Bundle nextToBundle, boolean isTriggerNextStep, String entrance, OnLoginListener listener) {
if (!isLogin()) {
if (listener != null) Utils.toast(context, "需要登录");
LogUtils.login("dialog", null, entrance);
LogUtils.login("activity", null, entrance);
// 有可能App未启动
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance);
bundle.putString(EntranceUtils.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivity(context, nextToBundle, bundle, (resultCode, data) -> {
if (isTriggerNextStep && listener != null && isLogin()) {
listener.onLogin();
}
});
} else {
if (listener != null) {
listener.onLogin();
}
}
}
public static boolean isLogin() {
return !TextUtils.isEmpty(UserManager.getInstance().getToken());
}

View File

@ -72,11 +72,6 @@ object CommentHelper {
videoId: String? = null,
listener: OnCommentCallBackListener? = null) {
val dialogOptions = ArrayList<String>()
if (commentEntity.me == null || !commentEntity.me?.isCommentOwner!!) {
dialogOptions.add("回复")
}
dialogOptions.add("复制")
dialogOptions.add("投诉")
@ -97,18 +92,6 @@ object CommentHelper {
when (it) {
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
"回复" -> {
context.ifLogin("回答详情-评论-回复") {
if (listener != null) {
listener.onCommentCallback(commentEntity)
} else if (!TextUtils.isEmpty(commentEntity.id)) {
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, commentEntity.id))
} else {
Utils.toast(context, "缺少关键属性")
}
}
}
"复制" -> copyText(commentEntity.content, context)
"投诉" -> {

View File

@ -13,9 +13,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.gh.gamecenter.CommentDetailActivity;
import com.gh.gamecenter.MessageDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.OnCommentCallBackListener;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.MeEntity;
@ -85,8 +83,6 @@ public class CommentUtils {
public static void showReportDialog(final CommentEntity commentEntity,
final Context context,
final boolean showConversation,
final OnCommentCallBackListener listener,
final String newsId,
final String patch) {
final Dialog dialog = new Dialog(context);
@ -96,11 +92,6 @@ public class CommentUtils {
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
List<String> dialogType = new ArrayList<>();
if (commentEntity.getMe() == null || !commentEntity.getMe().isCommentOwner()) {
dialogType.add("回复");
}
dialogType.add("复制");
dialogType.add("投诉");
@ -126,17 +117,6 @@ public class CommentUtils {
public void onClick(View v) {
dialog.cancel();
switch (reportTv.getText().toString()) {
case "回复":
CheckLoginUtils.checkLogin(context, patch + "-回复", () -> {
if (listener != null) {
listener.onCommentCallback(commentEntity);
} else if (!TextUtils.isEmpty(newsId)) {
context.startActivity(MessageDetailActivity.getMessageDetailIntent(context, commentEntity, newsId));
} else {
Utils.toast(context, "缺少关键属性");
}
});
break;
case "复制":
copyText(commentEntity.getContent(), context);
break;
@ -218,13 +198,13 @@ public class CommentUtils {
public static void postVote(final Context context, final CommentEntity commentEntity,
final TextView commentLikeCountTv, final ImageView commentLikeIv,
final OnVoteListener listener) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
Utils.toast(context, "已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.vote_icon_select);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
@ -242,7 +222,7 @@ public class CommentUtils {
commentEntity.setVote(commentEntity.getVote() - 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
commentLikeIv.setImageResource(R.drawable.comment_vote_unselect);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
@ -284,13 +264,13 @@ public class CommentUtils {
entrance = "社区文章详情-评论-点赞";
}
CheckLoginUtils.checkLogin(context, entrance, () -> {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme)) {
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
Utils.toast(context, "已经点过赞啦!");
return;
}
commentEntity.setVote(commentEntity.getVote() + 1);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme));
commentLikeIv.setImageResource(R.drawable.vote_icon_select);
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
@ -307,7 +287,7 @@ public class CommentUtils {
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);
commentLikeIv.setImageResource(R.drawable.comment_vote_unselect);
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
if (commentEntity.getVote() == 0) {
commentLikeCountTv.setVisibility(View.GONE);
@ -340,14 +320,22 @@ public class CommentUtils {
public static void setCommentUserView(Context mContext, CommentViewHolder holder, CommentEntity entity) {
MeEntity userDataEntity = entity.getMe();
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.hint));
holder.commentLikeIv.setImageResource(R.drawable.vote_icon_unselect);
holder.commentLikeIv.setImageResource(R.drawable.comment_vote_unselect);
if (userDataEntity == null || !userDataEntity.isCommentOwner()) {
holder.replyLine.setVisibility(View.VISIBLE);
holder.commentReply.setVisibility(View.VISIBLE);
} else {
holder.replyLine.setVisibility(View.GONE);
holder.commentReply.setVisibility(View.GONE);
}
if (entity.getVote() == 0) {
holder.commentLikeCountTv.setVisibility(View.GONE);
} else { // 检查是否已点赞
if (userDataEntity != null && (userDataEntity.isCommentVoted())) {
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
holder.commentLikeIv.setImageResource(R.drawable.vote_icon_select);
holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
holder.commentLikeIv.setImageResource(R.drawable.comment_vote_select);
}
holder.commentLikeCountTv.setVisibility(View.VISIBLE);
holder.commentLikeCountTv.setText(NumberUtils.transSimpleCount(entity.getVote()));
@ -367,10 +355,11 @@ public class CommentUtils {
UserInfoEntity userInfo = UserManager.getInstance().getUserInfoEntity();
if (userDataEntity != null && userDataEntity.isCommentOwner() && userInfo != null) {
if (entity.getMe() != null && entity.getMe().isContentOwner()) {
holder.commentUserNameTv.setText(userInfo.getName() + "(作者)");
holder.commentAuthorTv.setVisibility(View.VISIBLE);
} else {
holder.commentUserNameTv.setText(userInfo.getName());
holder.commentAuthorTv.setVisibility(View.GONE);
}
holder.commentUserNameTv.setText(userInfo.getName());
if (userInfo.getAuth() != null) {
ImageUtils.display(holder.commentUserBadgeIv, userInfo.getAuth().getIcon());
} else {
@ -379,10 +368,11 @@ public class CommentUtils {
ImageUtils.displayIcon(holder.commentUserIconDv, userInfo.getIcon());
} else {
if (entity.getMe() != null && entity.getMe().isContentOwner()) {
holder.commentUserNameTv.setText(entity.getUser().getName() + "(作者)");
holder.commentAuthorTv.setVisibility(View.VISIBLE);
} else {
holder.commentUserNameTv.setText(entity.getUser().getName());
holder.commentAuthorTv.setVisibility(View.GONE);
}
holder.commentUserNameTv.setText(entity.getUser().getName());
if (entity.getUser().getAuth() != null) {
ImageUtils.display(holder.commentUserBadgeIv, entity.getUser().getAuth().getIcon());
} else {

View File

@ -238,18 +238,12 @@ public class DataUtils {
}
public static void onError(Context context, Throwable throwable) {
// MTA主动上传错误
//bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
try {
StatService.reportException(context, throwable);
CrashReport.postCatchedException(throwable);
} catch (Exception e) {
}
// //bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
// try {
// CrashReport.postCatchedException(throwable);
// } catch (Exception e) {
// }
//talkingdata
try {
TCAgent.onError(context, throwable);

View File

@ -8,6 +8,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.SpannableStringBuilder;
@ -200,7 +201,7 @@ public class DialogUtils {
String mb = size.toUpperCase().replaceAll("MB", "").trim();
Float i = Float.valueOf(mb);
if (NetworkUtils.isWifiOr4GConnected(context) && i <= 50) {
AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载,请注意流量消耗"),500);
AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载,请注意流量消耗"), 500);
return true;
}
@ -241,7 +242,7 @@ public class DialogUtils {
Context finalContext = context;
allowOnce.setOnClickListener(v -> {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
Utils.toast(HaloApp.getInstance().getApplication(), "已使用移动网络下载,请注意流量消耗");
Utils.toast(finalContext, "已使用移动网络下载,请注意流量消耗");
}, 500);
listener.onConfirm();
dialog.dismiss();
@ -261,7 +262,7 @@ public class DialogUtils {
AppExecutor.getUiExecutor().executeWithDelay(() -> {
// 显示了弹窗以后,即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
// 喷了,延时包治疑难杂症
Utils.toast(HaloApp.getInstance().getApplication(), "已使用移动网络下载,请注意流量消耗");
Utils.toast(finalContext, "已使用移动网络下载,请注意流量消耗");
}, 500);
listener.onConfirm();
dialog.dismiss();
@ -646,9 +647,9 @@ public class DialogUtils {
Button negativeBtn = alertDialog.getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
positiveBtn.setTextSize(13);
positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
positiveBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
negativeBtn.setTextSize(13);
negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
negativeBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
if (mesage != null) {
mesage.setGravity(Gravity.CENTER);
mesage.setTextSize(24);
@ -878,19 +879,24 @@ public class DialogUtils {
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
AtomicBoolean isCanceledByClickOutsideOfDialog = new AtomicBoolean(true);
final Dialog dialog = new Dialog(activityContext, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_privacy_policy, null);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
Window window = dialog.getWindow();
if (window != null) {
window.getDecorView().setPadding(0, 0, 0, 0);
window.setBackgroundDrawableResource(android.R.color.transparent);
WindowManager.LayoutParams params = window.getAttributes();
params.horizontalMargin = 0;
params.width = context.getResources().getDisplayMetrics().widthPixels;
params.height = context.getResources().getDisplayMetrics().heightPixels;
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
int maxHeight = DisplayUtils.dip2px(546);
if (height > maxHeight) {
params.height = maxHeight;
} else {
params.height = height;
}
window.setAttributes(params);
}
@ -898,6 +904,7 @@ public class DialogUtils {
TextView bottomContent = contentView.findViewById(R.id.bottom_content);
TextView topContent = contentView.findViewById(R.id.top_content);
TextView allowButton = contentView.findViewById(R.id.allow_button);
TextView disallowButton = contentView.findViewById(R.id.disallow_button);
TextView linkContent = contentView.findViewById(R.id.link_content);
RecyclerView permissions = contentView.findViewById(R.id.permissions_content);
@ -938,7 +945,7 @@ public class DialogUtils {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.text_1383EB));
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
ds.setUnderlineText(false);
}
@ -954,7 +961,7 @@ public class DialogUtils {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(activityContext, R.color.text_1383EB));
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
ds.setUnderlineText(false);
}
@ -968,17 +975,19 @@ public class DialogUtils {
title.setText(entity.getTitle());
linkContent.setText(skipText);
linkContent.setMovementMethod(new LinkMovementMethod());
allowButton.setText("我知道了");
topContent.setText(entity.getTopContent());
bottomContent.setText(entity.getBottomContent());
allowButton.setOnClickListener(view -> {
dialog.dismiss();
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击我知道了");
callback.onCallback();
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
});
dialog.setOnDismissListener(d -> {
callback.onCallback();
disallowButton.setOnClickListener(v -> {
dialog.dismiss();
showPrivacyPolicyDisallowDialog(activityContext, entity, callback);
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
});
dialog.setOnCancelListener(cd -> {
@ -997,6 +1006,38 @@ public class DialogUtils {
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
try {
dialog.setCancelable(false);
dialog.show();
} catch (Exception ignored) {
}
}
public static void showPrivacyPolicyDisallowDialog(Context context,
@NonNull PrivacyPolicyEntity entity,
EmptyCallback callback) {
final Context activityContext = checkDialogContext(context);
final Dialog dialog = new Dialog(activityContext, R.style.DialogWindowTransparent);
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_disallow_privacy_policy, null);
View backButton = contentView.findViewById(R.id.back_button);
View reviewButton = contentView.findViewById(R.id.review_button);
backButton.setOnClickListener(v -> {
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
dialog.dismiss();
AppManager.getInstance().appExit(activityContext);
});
reviewButton.setOnClickListener(v -> {
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
dialog.dismiss();
showPrivacyPolicyDialog(activityContext, entity, callback);
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(contentView);
try {
dialog.show();
} catch (Exception ignored) {
@ -1150,6 +1191,39 @@ public class DialogUtils {
return dialog;
}
public static void showDownloadMutexDialog(Context context) {
context = checkDialogContext(context);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_downlaod_mutex, null);
TextView positive = contentView.findViewById(R.id.dialog_positive);
CountDownTimer timer = new CountDownTimer(6000, 1000) {
public void onTick(long millisUntilFinished) {
positive.setText(("我知道了(" + millisUntilFinished / 1000 + ""));
}
public void onFinish() {
dialog.dismiss();
}
};
timer.start();
positive.setOnClickListener(v -> {
dialog.dismiss();
});
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();
}
/**
* @param context may be is application context
* @return activity context

View File

@ -149,7 +149,14 @@ object DirectUtils {
"community_special_column" -> context.startActivity(AskColumnDetailActivity.getIntentByColumnId(context, linkEntity.link, linkEntity.community!!, entrance, path))
"web", "inurl", "web链接" -> directToWebView(context, url = linkEntity.link!!, entrance = BaseActivity.mergeEntranceAndPath(entrance, path))
"web", "inurl", "web链接" -> {
when {
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
directDouyin(context, "1402577827140941")
}
else -> directToWebView(context, url = linkEntity.link!!, entrance = BaseActivity.mergeEntranceAndPath(entrance, path))
}
}
"qq", "QQ" -> directToQqConversation(context, linkEntity.link)
@ -234,6 +241,21 @@ object DirectUtils {
context.startActivity(UserHomeActivity.getIntent(context, userId ?: "", entrance, path))
}
/**
* 跳转至个人主页
* @param position 定位到某个tab 0游戏评论 1问答 2视频
*/
@JvmStatic
fun directToHomeActivity(context: Context, userId: String?, position: Int, entrance: String? = null, path: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_USER_ID, userId)
bundle.putString(KEY_TO, UserHomeActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
bundle.putString(KEY_PATH, path)
bundle.putInt(KEY_POSITION, position)
jumpActivity(context, bundle)
}
/**
* 回到首页
*/
@ -246,11 +268,15 @@ object DirectUtils {
* 跳转到游戏详情
*/
@JvmStatic
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null) {
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, scrollToLibao: Boolean = false) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, GameDetailActivity::class.java.simpleName)
bundle.putString(KEY_GAMEID, id)
if (scrollToLibao) {
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
bundle.putBoolean(KEY_SCROLL_TO_LIBAO, scrollToLibao)
}
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
jumpActivity(context, bundle)
}
@ -567,4 +593,13 @@ object DirectUtils {
// context.startActivity(GameVideoActivity.getIntent(context, gameId, entrance, path))
jumpActivity(context, bundle)
}
@JvmStatic
fun directDouyin(context: Context, userId: String) {
if (PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme")) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("snssdk1128://user/profile/$userId"))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}

View File

@ -13,6 +13,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
@ -237,6 +238,18 @@ public class DisplayUtils {
return (resourceId > 0 && hasSoftKeys(context)) ? resources.getDimensionPixelSize(resourceId) : 0;
}
//判断导航栏是否显示
public static boolean isNavigationBarShow(Activity activity) {
ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView();
for (int i = 0; i < vp.getChildCount(); i++) {
View child = vp.getChildAt(i);
if (child.getId() != -1 && "navigationBarBackground".equals(activity.getResources().getResourceEntryName(child.getId())) && child.getMeasuredHeight() != 0) {
return true;
}
}
return false;
}
public static boolean hasSoftKeys(Context context) {
if (!(context instanceof Activity)) return false;

View File

@ -0,0 +1,232 @@
package com.gh.common.util
import android.content.pm.PackageManager
import android.os.Build
import android.preference.PreferenceManager
import com.gh.base.BaseActivity
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.SuggestionActivity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SimpleGameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBShowDialog
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.suggest.SuggestType
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.SettingsFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import com.lightgame.utils.Util_System_Phone_State
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
import java.util.*
object DownloadObserver {
private val mApplication = HaloApp.getInstance().application
@JvmStatic
fun initObserver() {
val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.status != DownloadStatus.downloading) {
LogUtils.uploadDownloadEvent(downloadEntity)
}
if (DownloadStatus.hijack == downloadEntity.status) {
// 链接被劫持
processHijack(downloadEntity)
val nameAndPlatform = (downloadEntity.name + ":"
+ PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
MtaHelper.onEvent( "下载劫持",
"游戏名字", nameAndPlatform,
"网络状态", DeviceUtils.getNetwork(mApplication))
return
} else if (DownloadStatus.notfound == downloadEntity.status) {
// 404 Not Found
// 删除任务
downloadEntity.status = DownloadStatus.cancel
DownloadManager.getInstance(mApplication).cancel(downloadEntity.url)
Utils.toast(mApplication, "该链接已失效!请联系管理员。")
MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
"游戏", downloadEntity.name,
"平台", downloadEntity.platform)
DialogUtils.showAlertDialog(AppManager.getInstance().currentActivity(), "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(),
SuggestType.gameQuestion, "notfound",
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
SimpleGameEntity(downloadEntity.gameId, downloadEntity.name, ""))
}, null)
return
} else if (DownloadStatus.neterror == downloadEntity.status || DownloadStatus.timeout == downloadEntity.status) {
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
"游戏", downloadEntity.name,
"平台", downloadEntity.platform)
}
if (DownloadStatus.done == downloadEntity.status) {
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
MtaHelper.onEvent("软件更新", "下载完成")
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path, true))
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
} else {
statDoneEvent(downloadEntity)
val platform = PlatformUtils.getInstance(mApplication)
.getPlatformName(downloadEntity.platform)
if (platform != null) {
when {
downloadEntity.isPluggable -> // 弹出插件化提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
downloadEntity.isPlugin -> Utils.toast(mApplication, downloadEntity.name + " - " + platform + " - 下载完成")
else -> Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
} else {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
if (!downloadEntity.isPluggable) {
// 是否是自动安装
if (PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
if (FileUtils.isEmptyFile(downloadEntity.path)) {
Utils.toast(mApplication, R.string.install_failure_hint)
DownloadManager.getInstance(mApplication).cancel(downloadEntity.url)
} else {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
} else {
// 弹出卸载提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
}
}
}
}
// 统计下载完成
uploadData(downloadEntity.gameId, downloadEntity.platform)
}
// 下载过程分析统计
val pm = mApplication.packageManager
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
if (packageInfo == null) {
MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
"游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
"游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
}
}
if (downloadEntity.status == DownloadStatus.done) {
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", "", ""))
}
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
}
}
// 添加观察者
DownloadManager.getInstance(mApplication).addObserver(dataWatcher)
}
// 统计下载完成事件
private fun statDoneEvent(downloadEntity: DownloadEntity) {
var type: ExposureUtils.DownloadType
val platform = PlatformUtils.getInstance(HaloApp.getInstance().application).getPlatformName(downloadEntity.platform)
val kv1 = HashMap<String, Any>()
kv1["版本"] = platform
kv1["状态"] = "下载完成"
kv1["用户机型"] = Build.MODEL
kv1["设备IMEI"] = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
kv1["网络状态"] = DeviceUtils.getNetwork(HaloApp.getInstance().application)
kv1["光环助手版本"] = BuildConfig.VERSION_NAME
if (downloadEntity.isUpdate) {
type = ExposureUtils.DownloadType.UPDATE
if (downloadEntity.isPlugin) {
type = ExposureUtils.DownloadType.PLUGIN_UPDATE
}
DataUtils.onEvent(mApplication, "游戏更新", downloadEntity.name, kv1)
} else {
type = ExposureUtils.DownloadType.DOWNLOAD
}
val kv2 = HashMap<String, Any>()
kv2["版本"] = downloadEntity.platform
kv2["状态"] = "下载完成"
kv2["位置"] = downloadEntity.entrance ?: "null"
kv2["游戏分平台"] = downloadEntity.name + "-" + platform
kv2["光环助手版本"] = BuildConfig.VERSION_NAME
DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2)
if (downloadEntity.isPluggable) {
val kv3 = HashMap<String, Any>()
kv3["下载"] = "下载完成"
kv3["版本"] = downloadEntity.platform
kv3["位置"] = downloadEntity.entrance ?: "null"
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
DataUtils.onEvent(mApplication, "插件化", downloadEntity.name, kv3)
MtaHelper.onEvent(
"插件化_新",
"位置", downloadEntity.entrance,
"游戏", downloadEntity.name + "-" + downloadEntity.platform,
"操作", "下载完成",
"网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
}
ExposureUtils.logADownloadCompleteExposureEvent(
GameEntity(downloadEntity.gameId, downloadEntity.name),
downloadEntity.platform,
downloadEntity.exposureTrace,
type)
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")
}
private fun processHijack(downloadEntity: DownloadEntity) {
// 删除任务
downloadEntity.status = DownloadStatus.cancel
DownloadManager.getInstance(mApplication).cancel(downloadEntity.url)
// 弹出提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.DOWNLOAD_HIJACK))
// 记录链接被劫持
DataCollectionUtils.uploadHijack(mApplication, downloadEntity)
// 上传劫持log
DataLogUtils.uploadHijack(mApplication, downloadEntity)
}
// 统计下载
private fun uploadData(id: String, platform: String?) {
val params = HashMap<String, String>()
params["game"] = id
params["platform"] = platform ?: ""
val body = RequestBody.create(MediaType.parse("application/json"),
JSONObject(params).toString())
RetrofitManager.getInstance(mApplication).api.postDownload(body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Response())
}
}

View File

@ -4,11 +4,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.gh.common.avoidcallback.AvoidOnResultManager;
import com.gh.common.avoidcallback.Callback;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.NormalActivity;
import com.gh.gamecenter.SplashScreenActivity;
import com.gh.gamecenter.normal.NormalFragment;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author CsHeng
* @Date 2017/4/25
@ -18,6 +22,7 @@ import com.gh.gamecenter.normal.NormalFragment;
public class EntranceUtils {
public static final String KEY_TO = "to";
public static final String KEY_NEXT_TO = "next_to";
public static final String KEY_NEWSID = "newsId";
public static final String KEY_GAMEID = "gameId";
public static final String KEY_ID = "id";
@ -30,6 +35,7 @@ public class EntranceUtils {
public static final String HOST_VIDEO_STREAMING_HOME = "video_streaming_home";//视频流-首页
public static final String HOST_VIDEO_STREAMING_DESC = "video_streaming_desc";//视频流-游戏介绍进入
public static final String HOST_VIDEO_COLLECTION = "video_collection";//视频合集
public static final String HOST_USERHOME = "userhome";//个人主页
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";
@ -107,6 +113,7 @@ public class EntranceUtils {
public static final String KEY_CATEGORY_INIT_TITLE = "category_init_title";
public static final String KEY_BLOCK_DATA = "blockData";
public static final String KEY_ASK_TAG = "askTag";
public static final String KEY_SCROLL_TO_LIBAO = "libao";
public static final String KEY_ASK_COLUMN_TAG = "askColumnTag";
public static final String KEY_COMMUNITY_ID = "community_id";
public static final String KEY_COMMUNITY_NAME = "community_name";
@ -164,4 +171,33 @@ public class EntranceUtils {
}
}
public static void jumpActivity(Context context, Bundle nextToBundle, Bundle bundle, Callback callback) {
//TODO 把其他类似的跳转启动逻辑也处理掉
if (RunningUtils.isRunning(context)
&& MainActivity.class.getName().equals(RunningUtils.getBaseActivity(context))) {
// 应用正在运行,前台或后台
String to = bundle.getString(KEY_TO);
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);
//TODO:添加FLAG_ACTIVITY_NEW_TASK会导致一跳转页面callback就被调用
//intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.putExtras(bundle);
AvoidOnResultManager.Companion.getInstance((AppCompatActivity) context)
.startForResult(intent1, callback);
}
} else {
// 应用未在运行
if (nextToBundle != null) {
bundle.putBundle(KEY_NEXT_TO, nextToBundle);
}
context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
}
}
}

View File

@ -23,6 +23,10 @@ object ErrorHelper {
customizedHandler: (code: Int) -> Boolean) {
val errorEntity = errorString?.toObject<ErrorEntity>()
if (customizedHandler(errorEntity?.code ?: 0)) {
return
}
if (errorEntity == null) {
Utils.toast(context, R.string.post_failure_hint)
return
@ -33,11 +37,7 @@ object ErrorHelper {
return
}
if (customizedHandler(errorEntity.code ?: 0)) {
return
} else {
handleError(context, showHighPriorityHint, errorEntity)
}
handleError(context, showHighPriorityHint, errorEntity)
}
/**
@ -115,10 +115,11 @@ object ErrorHelper {
403074 -> Utils.toast(context, "该微信号(${errorEntity.data?.nickname})已绑定")
403078 -> Utils.toast(context, "已点赞")
403072 -> Utils.toast(context, R.string.comment_failed_userblocked)
403082 -> Utils.toast(context, "作者已关闭评论")
403020 -> if (showHighPriorityHint) {
DialogUtils.showAlertDialog(context,
"限制提醒",
"提醒",
"提问过于频繁,请先休息一下哦",
"知道了", null, null, null)
} else {

View File

@ -13,6 +13,7 @@ import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
@ -222,6 +223,20 @@ inline fun tryWithDefaultCatch(action: (() -> Unit)) {
}
}
/**
* 只在正式版本进行 try catch 操作
*
* 对于个别偶发的异常尽量不要做暴力的 try catch 处理
*/
inline fun tryCatchInRelease(action: (() -> Unit)) {
try {
action.invoke()
} catch (e: Throwable) {
if (BuildConfig.DEBUG) throw e
else e.printStackTrace()
}
}
/**
* String related
*/
@ -390,7 +405,7 @@ fun FragmentActivity.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
fun TextView.setTextWithHighlightedTextWrappedInsideWrapper(text: CharSequence,
wrapper: String = Constants.DEFAULT_TEXT_WRAPPER,
@ColorRes
highlightColorId: Int = R.color.theme,
highlightColorId: Int = R.color.theme_font,
copyClickedText: Boolean = false,
highlightedTextClickListener: (() -> Unit)? = null) {
TextHelper.highlightTextThatIsWrappedInsideWrapper(this, text, wrapper, highlightColorId, object : SimpleCallback<String> {
@ -419,7 +434,7 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
}
fun Int.toColor(): Int {
return HaloApp.getInstance().application.resources.getColor(this)
return ContextCompat.getColor(HaloApp.getInstance().application, this)
}
fun Int.toResString(): String {

View File

@ -57,7 +57,7 @@ public class GameUtils {
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
} else if ("打开".equals(status) || "启动".equals(status)) {
downloadBtn.setBackgroundResource(R.drawable.detail_download_open_style);
downloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme));
downloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
} else {
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
}

View File

@ -0,0 +1,37 @@
package com.gh.common.util;
import com.contrarywind.adapter.WheelAdapter;
/**
* 注意选择后的数据其实是dates的position需要在回调时对返回的date数据进行转换
*
* 例子请见:
* {@link com.gh.gamecenter.servers.add.AddKaiFuActivity}
*/
public class HaloWheelViewAdapter implements WheelAdapter {
private int[] dates;
public HaloWheelViewAdapter(int[] dates) {
this.dates = dates;
}
@Override
public Object getItem(int index) {
return dates[index];
}
@Override
public int getItemsCount() {
return dates.length;
}
@Override
public int indexOf(Object o) {
try {
return (int) o;
} catch (Exception e) {
return -1;
}
}
}

View File

@ -32,4 +32,39 @@ public class HtmlUtils {
return htmlStr.trim(); //返回文本字符串
}
/**
* 去除html代码及文本
*/
public static String stripHtmlCode(String htmlStr) {
if (TextUtils.isEmpty(htmlStr)) return "";
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
String regEx_html = "<[^>]+>[\\s\\S]*?<\\/[^>]+>"; //定义HTML标签的正则表达式
String regEx_html_single = "<[^>]+>"; //定义HTML单标签的正则表达式
String regEx_blank = "\\s+"; //定义空白字符的正则表达式
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
Matcher m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); //过滤script标签
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
Matcher m_style = p_style.matcher(htmlStr);
htmlStr = m_style.replaceAll(""); //过滤style标签
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
Matcher m_html = p_html.matcher(htmlStr);
htmlStr = m_html.replaceAll(""); //过滤html标签
Pattern p_html_single = Pattern.compile(regEx_html_single, Pattern.CASE_INSENSITIVE);
Matcher m_html_single = p_html_single.matcher(htmlStr);
htmlStr = m_html_single.replaceAll(""); //过滤html单标签
Pattern p_blank = Pattern.compile(regEx_blank, Pattern.CASE_INSENSITIVE);
Matcher m_blank = p_blank.matcher(htmlStr);
htmlStr = m_blank.replaceAll(" ");//过滤空白字符
return htmlStr.trim(); //返回文本字符串
}
}

View File

@ -236,7 +236,7 @@ object ImageUtils {
fun display(view: SimpleDraweeView?, url: String?) {
url?.let {
// 图片是以 gif 结尾的就
if (it.endsWith(".gif")) {
if (it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false) {
if (view?.tag == url) return@let
val controller = Fresco.newDraweeControllerBuilder()

View File

@ -166,12 +166,12 @@ public class LibaoUtils {
case "coming":
libaoBtn.setText(R.string.libao_coming);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "used_up":
libaoBtn.setText(R.string.libao_used_up);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "finish":
libaoBtn.setText(R.string.libao_finish);
@ -181,12 +181,12 @@ public class LibaoUtils {
case "linged":
libaoBtn.setText(R.string.libao_linged);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "taoed":
libaoBtn.setText(R.string.libao_taoed);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "copy":
libaoBtn.setText(R.string.libao_copy);
@ -195,7 +195,7 @@ public class LibaoUtils {
case "repeatLing":
libaoBtn.setText(R.string.libao_repeat_ling);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "repeatLinged":
libaoBtn.setText(R.string.libao_repeat_ling);
@ -204,7 +204,7 @@ public class LibaoUtils {
case "repeatTao":
libaoBtn.setText(R.string.libao_repeat_tao);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme));
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "repeatTaoed":
libaoBtn.setText(R.string.libao_repeat_tao);

View File

@ -1,5 +1,6 @@
package com.gh.common.util;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@ -264,8 +265,9 @@ public class PackageUtils {
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
if (isInAppUpdate) {
// 应用内更新不加 FLAG_ACTIVITY_NEW_TASK 在模拟器上会出现安装完成后安装界面也一并消失的类似闪退的表现
// 应用内更新不加 FLAG_ACTIVITY_NEW_TASK 在模拟器上会出现安装完成后安装界面也一并消失的类似闪退的表现
// Application 上下文就更不用说了
if (isInAppUpdate || context instanceof Application) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");

View File

@ -4,10 +4,9 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Handler;
import androidx.core.content.ContextCompat;
import androidx.collection.ArrayMap;
import android.text.TextUtils;
import com.gh.common.AppExecutor;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.PlatformEntity;
import com.gh.gamecenter.eventbus.EBReuse;
@ -30,6 +29,8 @@ import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@ -153,7 +154,7 @@ public class PlatformUtils {
}
}
if (urls.size() != 0) {
HaloApp.getInstance().getMainExecutor().execute(new Runnable() {
AppExecutor.getIoExecutor().execute(new Runnable() {
@Override
public void run() {
int success = 0;

View File

@ -1,6 +1,7 @@
package com.gh.common.util;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import com.gh.gamecenter.R;
@ -9,6 +10,7 @@ import com.gh.gamecenter.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.utils.Utils;
import com.walkud.rom.checker.RomIdentifier;
import org.json.JSONObject;
@ -25,10 +27,23 @@ import retrofit2.HttpException;
*/
public class PostCommentUtils {
public static void addCommentData(final Context context, final String newsId, final String content,
public static void addCommentData(final Context context, final String newsId, final JSONObject content,
final CommentEntity commentEntity,
final PostCommentListener listener) {
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content);
try {
JSONObject device = new JSONObject();
device.put("os", "Android");
device.put("model", Build.MODEL);
device.put("manufacturer", Build.MANUFACTURER);
device.put("android_version", android.os.Build.VERSION.RELEASE);
device.put("rom", RomIdentifier.getRom().name() + " " + RomIdentifier.getRom().getVersionName());
content.put("device", device);
} catch (Exception e) {
e.printStackTrace();
}
RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toString());
Observable<ResponseBody> observable;
if (commentEntity != null) {
observable = RetrofitManager.getInstance(context).getApi().postReplyComment(commentEntity.getId(), body);

View File

@ -18,6 +18,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
@ -202,8 +203,13 @@ public class ShareUtils {
popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
//解决PopupWindow无法覆盖状态栏
popupWindow.setClippingEnabled(false);
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
if (!DisplayUtils.isNavigationBarShow(activity)) {
bottomLocation = 0;
}
try {
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
} catch (Exception e) {
e.printStackTrace();
}
@ -268,8 +274,15 @@ public class ShareUtils {
popupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.MATCH_PARENT, true);
popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
//解决PopupWindow无法覆盖状态栏
popupWindow.setClippingEnabled(false);
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
if (!DisplayUtils.isNavigationBarShow(activity)) {
bottomLocation = 0;
}
try {
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
// popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import androidx.fragment.app.Fragment
import com.gh.common.annotation.Synchronize
import com.gh.common.util.SyncDataBetweenPageHelper.resultHandle
import com.gh.common.util.SyncDataBetweenPageHelper.startActivityForResult
@ -12,7 +13,7 @@ import com.gh.gamecenter.gamedetail.rating.RatingAdapter
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
/**
* 页面之间实现数据同步
* 页面之间实现数据同步(前提:页面之前拥有同一个数据实体)
* 需要同步的数据,在相应的字段加上[Synchronize]注解,关键方法[resultHandle]
* 如无特殊情况,尽量使用下面方法进行页面联动
* 注意: [startActivityForResult] intent的数据实体key必须是Class的SimpleName
@ -38,6 +39,12 @@ object SyncDataBetweenPageHelper {
}
}
fun startActivityForResult(fragment: Fragment, intent: Intent, requestCode: Int, dataPosition: Int) {
intent.putExtra(DATA_POSITION_TAG, dataPosition)
intent.putExtra(REQUEST_CODE_TAG, requestCode)
fragment.startActivityForResult(intent, requestCode)
}
fun <T : Parcelable> setResultAndFinish(context: Context, syncData: T?, resultCode: Int = Activity.RESULT_OK): Boolean {
if (context is Activity) {
val requestCode = context.intent.getIntExtra(REQUEST_CODE_TAG, DEFAULT_NUMBER)

View File

@ -91,8 +91,8 @@ object TextHelper {
}
@JvmStatic
fun highlightTextThatIsWrappedInsideWrapperByDefault(textView: TextView, text: String) {
textView.text = getHighlightedSpannableStringThatIsWrappedInsideWrapper(textView.context, text, "###", R.color.theme, object : SimpleCallback<String> {
fun highlightTextThatIsWrappedInsideWrapperByDefault(textView: TextView, text: String?) {
textView.text = getHighlightedSpannableStringThatIsWrappedInsideWrapper(textView.context, text ?: "", "###", R.color.theme_font, object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@ -122,7 +122,7 @@ object TextHelper {
text: CharSequence,
wrapper: String = "###",
@ColorRes
highlightColorId: Int = R.color.theme,
highlightColorId: Int = R.color.theme_font,
highlightedTextClickListener: SimpleCallback<String>? = object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
@ -193,7 +193,7 @@ object TextHelper {
splits.forEachIndexed { index, s ->
if (index != 0) {
val item = "<tag>$s"
val pattern = Pattern.compile("<tag>(\\S+)</tag>([\\S,\n]+)")
val pattern = Pattern.compile("<tag>(\\S+)</tag>([\\S\\s\n]+)")
val matcher = pattern.matcher(item)
if (matcher.find()) {
val label = matcher.group(1)

View File

@ -30,6 +30,7 @@ public class TimestampUtils {
intervalMap.put(".*games.*", 15);
intervalMap.put(".*articles.*", 20);
intervalMap.put(".*halo_addons.*", 10);
intervalMap.put(".*packages.*", 1);
}
private static void initCDMap() {
@ -39,6 +40,7 @@ public class TimestampUtils {
cdMap.put(".*games.*", Constants.GAME_CD);
cdMap.put(".*articles.*", Constants.NEWS_CD);
cdMap.put(".*halo_addons.*", Constants.ADDONS_CD);
cdMap.put(".*packages.*", Constants.PACKAGES_CD);
}
/*

View File

@ -12,6 +12,7 @@ import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
@ -49,7 +50,8 @@ public class ClearEditTextNormal extends androidx.appcompat.widget.AppCompatEdit
mClearDrawable = getResources().getDrawable(R.drawable.icon_close);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
// mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
mClearDrawable.setBounds(0, 0, DisplayUtils.dip2px(16), DisplayUtils.dip2px(16));
//默认设置隐藏图标
setClearIconVisible(false);
//设置焦点改变的监听

View File

@ -92,7 +92,7 @@ public class DownloadProgressBar extends ProgressBar {
super.onDraw(canvas);
if (TextUtils.isEmpty(mText)) return;
mPaint.setColor(mDefaultColor == 0 ? ContextCompat.getColor(getContext(), R.color.theme) : mDefaultColor); // 初始化颜色
mPaint.setColor(mDefaultColor == 0 ? ContextCompat.getColor(getContext(), R.color.theme_font) : mDefaultColor); // 初始化颜色
mPaint.setTextSize(mTextSize);
mFakeTextPaint.setTextSize(mTextSize);
mFakeTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
@ -116,7 +116,7 @@ public class DownloadProgressBar extends ProgressBar {
if (DOWNLOAD_IMAGE_STYLE == mDownloadStyle) {
color = Color.BLACK;
} else if (DOWNLOAD_SLIDE_STYLE == mDownloadStyle) {
color = getResources().getColor(R.color.theme);
color = getResources().getColor(R.color.theme_font);
}
mPaint.setColor(color); // 反向颜色
}
@ -200,7 +200,7 @@ public class DownloadProgressBar extends ProgressBar {
switch (mDownloadStyle) {
case DOWNLOAD_RECT_STYLE:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_rect_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme_font);
break;
case DOWNLOAD_IMAGE_STYLE:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_image_style));
@ -208,7 +208,7 @@ public class DownloadProgressBar extends ProgressBar {
break;
default:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme_font);
break;
}
setProgress(0);
@ -217,7 +217,7 @@ public class DownloadProgressBar extends ProgressBar {
switch (mDownloadStyle) {
case DOWNLOAD_RECT_STYLE:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_rect_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme_font);
break;
case DOWNLOAD_IMAGE_STYLE:
case DOWNLOAD_SLIDE_STYLE:
@ -226,7 +226,7 @@ public class DownloadProgressBar extends ProgressBar {
break;
default:
setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style));
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme);
mDefaultColor = ContextCompat.getColor(getContext(), R.color.theme_font);
break;
}
break;

View File

@ -1,6 +1,10 @@
package com.gh.common.view
import android.annotation.SuppressLint
import android.content.Context
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
@ -16,6 +20,7 @@ class EllipsizeTextView : AppCompatTextView {
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
@SuppressLint("DrawAllocation")
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
if (lineCount > maxLines) {
@ -30,7 +35,7 @@ class EllipsizeTextView : AppCompatTextView {
val cutWidth = paint.measureText(text.subSequence(secondLastLineEnd, lastLineEnd - i).toString() + "...")
if (cutWidth <= layout.width) {
charSequence = text.subSequence(0, lastLineEnd - i)
text = "$charSequence..."
text = SpannableStringBuilder().append(charSequence).append("...")
break
}
}

View File

@ -0,0 +1,592 @@
package com.gh.common.view;
import android.content.Context;
import android.graphics.Paint;
import android.os.Build;
import android.text.Layout;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.AlignmentSpan;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import com.gh.gamecenter.R;
import java.lang.reflect.Field;
/**
* 参考: https://github.com/MrTrying/ExpandableText-Example
* <p>
* todo 辣鸡代码,有时间移除并在 {@link ExpandTextView} 实现该功能
*/
public class ExpandAndCloseTextView extends AppCompatTextView {
public static final String ELLIPSIS_STRING = new String(new char[]{'\u2026'});
private static final int DEFAULT_MAX_LINE = 3;
private static final String DEFAULT_OPEN_SUFFIX = " 展开";
private static final String DEFAULT_CLOSE_SUFFIX = " 收起";
volatile boolean animating = false;
boolean isClosed = false;
private int mMaxLines = DEFAULT_MAX_LINE;
/**
* TextView可展示宽度包含paddingLeft和paddingRight
*/
private int initWidth = 0;
/**
* 原始文本
*/
private CharSequence originalText;
private SpannableStringBuilder mOpenSpannableStr, mCloseSpannableStr;
private boolean hasAnimation = false;
private Animation mOpenAnim, mCloseAnim;
private int mOpenHeight, mCLoseHeight;
private boolean mExpandable;
private boolean mCloseInNewLine;
@Nullable
private SpannableString mOpenSuffixSpan, mCloseSuffixSpan;
private String mOpenSuffixStr = DEFAULT_OPEN_SUFFIX;
private String mCloseSuffixStr = DEFAULT_CLOSE_SUFFIX;
private int mOpenSuffixColor, mCloseSuffixColor;
private View.OnClickListener mOnClickListener;
private CharSequenceToSpannableHandler mCharSequenceToSpannableHandler;
public ExpandAndCloseTextView(Context context) {
super(context);
initialize();
}
public ExpandAndCloseTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public ExpandAndCloseTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
/**
* 初始化
*/
private void initialize() {
mOpenSuffixColor = mCloseSuffixColor = getResources().getColor( R.color.theme_font);
setMovementMethod(CustomLinkMovementMethod.getInstance());
setIncludeFontPadding(false);
updateOpenSuffixSpan();
updateCloseSuffixSpan();
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
public void setOriginalText(CharSequence originalText) {
this.originalText = originalText;
mExpandable = false;
mCloseSpannableStr = new SpannableStringBuilder();
final int maxLines = mMaxLines;
SpannableStringBuilder tempText = charSequenceToSpannable(originalText);
mOpenSpannableStr = charSequenceToSpannable(originalText);
if (maxLines != -1) {
Layout layout = createStaticLayout(tempText);
mExpandable = layout.getLineCount() > maxLines;
if (mExpandable) {
//拼接展开内容
if (mCloseInNewLine) {
mOpenSpannableStr.append("\n");
}
if (mCloseSuffixSpan != null) {
mOpenSpannableStr = new SpannableStringBuilder(autoSplitText(mOpenSpannableStr.toString()));
mOpenSpannableStr.append(mCloseSuffixSpan);
}
//计算原文截取位置
int endPos = layout.getLineEnd(maxLines - 1);
if (originalText.length() <= endPos) {
mCloseSpannableStr = charSequenceToSpannable(originalText);
} else {
mCloseSpannableStr = charSequenceToSpannable(originalText.subSequence(0, endPos));
}
SpannableStringBuilder tempText2 = charSequenceToSpannable(mCloseSpannableStr).append(ELLIPSIS_STRING);
if (mOpenSuffixSpan != null) {
tempText2.append(mOpenSuffixSpan);
}
//循环判断,收起内容添加展开后缀后的内容
Layout tempLayout = createStaticLayout(tempText2);
while (tempLayout.getLineCount() > maxLines) {
int lastSpace = mCloseSpannableStr.length() - 1;
if (lastSpace == -1) {
break;
}
if (originalText.length() <= lastSpace) {
mCloseSpannableStr = charSequenceToSpannable(originalText);
} else {
mCloseSpannableStr = charSequenceToSpannable(originalText.subSequence(0, lastSpace));
}
tempText2 = charSequenceToSpannable(mCloseSpannableStr).append(ELLIPSIS_STRING);
if (mOpenSuffixSpan != null) {
tempText2.append(mOpenSuffixSpan);
}
tempLayout = createStaticLayout(tempText2);
}
int lastSpace = mCloseSpannableStr.length() - mOpenSuffixSpan.length();
if (lastSpace >= 0 && originalText.length() > lastSpace) {
CharSequence redundantChar = originalText.subSequence(lastSpace, lastSpace + mOpenSuffixSpan.length());
int offset = hasEnCharCount(redundantChar) - hasEnCharCount(mOpenSuffixSpan) + 1;
lastSpace = offset <= 0 ? lastSpace : lastSpace - offset;
mCloseSpannableStr = charSequenceToSpannable(originalText.subSequence(0, lastSpace));
}
//计算收起的文本高度
mCLoseHeight = tempLayout.getHeight() + getPaddingTop() + getPaddingBottom();
mCloseSpannableStr.append(ELLIPSIS_STRING);
mCloseSpannableStr = new SpannableStringBuilder(autoSplitText(mCloseSpannableStr.toString()));
if (mOpenSuffixSpan != null) {
mCloseSpannableStr.append(mOpenSuffixSpan);
}
}
}
isClosed = mExpandable;
if (mExpandable) {
setText(mCloseSpannableStr);
//设置监听
super.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// switchOpenClose();
// if (mOnClickListener != null) {
// mOnClickListener.onClick(v);
// }
}
});
} else {
setText(mOpenSpannableStr);
}
}
private int hasEnCharCount(CharSequence str) {
int count = 0;
if (!TextUtils.isEmpty(str)) {
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= ' ' && c <= '~') {
count++;
}
}
}
return count;
}
private void switchOpenClose() {
if (mExpandable) {
isClosed = !isClosed;
if (isClosed) {
close();
} else {
open();
}
}
}
/**
* 设置是否有动画
*
* @param hasAnimation
*/
public void setHasAnimation(boolean hasAnimation) {
this.hasAnimation = hasAnimation;
}
/**
* 展开
*/
private void open() {
if (hasAnimation) {
Layout layout = createStaticLayout(mOpenSpannableStr);
mOpenHeight = layout.getHeight() + getPaddingTop() + getPaddingBottom();
executeOpenAnim();
} else {
ExpandAndCloseTextView.super.setMaxLines(Integer.MAX_VALUE);
setText(mOpenSpannableStr);
if (mOpenCloseCallback != null) {
mOpenCloseCallback.onOpen();
}
}
}
/**
* 收起
*/
private void close() {
if (hasAnimation) {
executeCloseAnim();
} else {
ExpandAndCloseTextView.super.setMaxLines(mMaxLines);
setText(mCloseSpannableStr);
if (mOpenCloseCallback != null) {
mOpenCloseCallback.onClose();
}
}
}
/**
* 执行展开动画
*/
private void executeOpenAnim() {
//创建展开动画
if (mOpenAnim == null) {
mOpenAnim = new ExpandCollapseAnimation(this, mCLoseHeight, mOpenHeight);
mOpenAnim.setFillAfter(true);
mOpenAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
ExpandAndCloseTextView.super.setMaxLines(Integer.MAX_VALUE);
setText(mOpenSpannableStr);
}
@Override
public void onAnimationEnd(Animation animation) {
// 动画结束后textview设置展开的状态
getLayoutParams().height = mOpenHeight;
requestLayout();
animating = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
if (animating) {
return;
}
animating = true;
clearAnimation();
// 执行动画
startAnimation(mOpenAnim);
}
/**
* 执行收起动画
*/
private void executeCloseAnim() {
//创建收起动画
if (mCloseAnim == null) {
mCloseAnim = new ExpandCollapseAnimation(this, mOpenHeight, mCLoseHeight);
mCloseAnim.setFillAfter(true);
mCloseAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
animating = false;
ExpandAndCloseTextView.super.setMaxLines(mMaxLines);
setText(mCloseSpannableStr);
getLayoutParams().height = mCLoseHeight;
requestLayout();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
if (animating) {
return;
}
animating = true;
clearAnimation();
// 执行动画
startAnimation(mCloseAnim);
}
/**
* @param spannable
* @return
*/
private Layout createStaticLayout(SpannableStringBuilder spannable) {
int contentWidth = initWidth - getPaddingLeft() - getPaddingRight();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
StaticLayout.Builder builder = StaticLayout.Builder.obtain(spannable, 0, spannable.length(), getPaint(), contentWidth);
builder.setAlignment(Layout.Alignment.ALIGN_NORMAL);
builder.setIncludePad(getIncludeFontPadding());
builder.setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier());
return builder.build();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new StaticLayout(spannable, getPaint(), contentWidth, Layout.Alignment.ALIGN_NORMAL,
getLineSpacingMultiplier(), getLineSpacingExtra(), getIncludeFontPadding());
} else {
return new StaticLayout(spannable, getPaint(), contentWidth, Layout.Alignment.ALIGN_NORMAL,
getFloatField("mSpacingMult", 1f), getFloatField("mSpacingAdd", 0f), getIncludeFontPadding());
}
}
private float getFloatField(String fieldName, float defaultValue) {
float value = defaultValue;
if (TextUtils.isEmpty(fieldName)) {
return value;
}
try {
// 获取该类的所有属性值域
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
if (TextUtils.equals(fieldName, field.getName())) {
value = field.getFloat(this);
break;
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return value;
}
/**
* @param charSequence
* @return
*/
private SpannableStringBuilder charSequenceToSpannable(@NonNull CharSequence charSequence) {
SpannableStringBuilder spannableStringBuilder = null;
if (mCharSequenceToSpannableHandler != null) {
spannableStringBuilder = mCharSequenceToSpannableHandler.charSequenceToSpannable(charSequence);
}
if (spannableStringBuilder == null) {
spannableStringBuilder = new SpannableStringBuilder(charSequence);
}
return spannableStringBuilder;
}
/**
* 初始化TextView的可展示宽度
*
* @param width
*/
public void initWidth(int width) {
initWidth = width;
}
@Override
public void setMaxLines(int maxLines) {
this.mMaxLines = maxLines;
super.setMaxLines(maxLines);
}
/**
* 设置展开后缀text
*
* @param openSuffix
*/
public void setOpenSuffix(String openSuffix) {
mOpenSuffixStr = openSuffix;
updateOpenSuffixSpan();
}
/**
* 设置展开后缀文本颜色
*
* @param openSuffixColor
*/
public void setOpenSuffixColor(@ColorInt int openSuffixColor) {
mOpenSuffixColor = openSuffixColor;
updateOpenSuffixSpan();
}
/**
* 设置收起后缀text
*
* @param closeSuffix
*/
public void setCloseSuffix(String closeSuffix) {
mCloseSuffixStr = closeSuffix;
updateCloseSuffixSpan();
}
/**
* 设置收起后缀文本颜色
*
* @param closeSuffixColor
*/
public void setCloseSuffixColor(@ColorInt int closeSuffixColor) {
mCloseSuffixColor = closeSuffixColor;
updateCloseSuffixSpan();
}
/**
* 收起后缀是否另起一行
*
* @param closeInNewLine
*/
public void setCloseInNewLine(boolean closeInNewLine) {
mCloseInNewLine = closeInNewLine;
updateCloseSuffixSpan();
}
/**
* 更新展开后缀Spannable
*/
private void updateOpenSuffixSpan() {
if (TextUtils.isEmpty(mOpenSuffixStr)) {
mOpenSuffixSpan = null;
return;
}
mOpenSuffixSpan = new SpannableString(mOpenSuffixStr);
mOpenSuffixSpan.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
switchOpenClose();
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(mOpenSuffixColor);
ds.setUnderlineText(false);
}
}, 0, mOpenSuffixStr.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
}
/**
* 更新收起后缀Spannable
*/
private void updateCloseSuffixSpan() {
if (TextUtils.isEmpty(mCloseSuffixStr)) {
mCloseSuffixSpan = null;
return;
}
mCloseSuffixSpan = new SpannableString(mCloseSuffixStr);
if (mCloseInNewLine) {
AlignmentSpan alignmentSpan = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
mCloseSuffixSpan.setSpan(alignmentSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mCloseSuffixSpan.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
switchOpenClose();
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(mCloseSuffixColor);
ds.setUnderlineText(false);
}
}, 1, mCloseSuffixStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
private String autoSplitText(final String rawText) {
final Paint tvPaint = getPaint(); //paint包含字体等信息
final float tvWidth = initWidth - getPaddingLeft() - getPaddingRight(); //控件可用宽度
//将原始文本按行拆分
String[] rawTextLines = rawText.replaceAll("\r", "").split("\n");
StringBuilder sbNewText = new StringBuilder();
for (String rawTextLine : rawTextLines) {
if (tvPaint.measureText(rawTextLine) <= tvWidth) {
//如果整行宽度在控件可用宽度之内,就不处理了
sbNewText.append(rawTextLine);
} else {
//如果整行宽度超过控件可用宽度,则按字符测量,在超过可用宽度的前一个字符处手动换行
float lineWidth = 0;
for (int cnt = 0; cnt != rawTextLine.length(); ++cnt) {
char ch = rawTextLine.charAt(cnt);
lineWidth += tvPaint.measureText(String.valueOf(ch));
if (lineWidth <= tvWidth) {
sbNewText.append(ch);
} else {
sbNewText.append("\n");
lineWidth = 0;
--cnt;
}
}
}
sbNewText.append("\n");
}
//把结尾多余的\n去掉
if (!rawText.endsWith("\n")) {
sbNewText.deleteCharAt(sbNewText.length() - 1);
}
return sbNewText.toString();
}
@Override
public void setOnClickListener(View.OnClickListener onClickListener) {
mOnClickListener = onClickListener;
}
public OpenAndCloseCallback mOpenCloseCallback;
public void setOpenAndCloseCallback(OpenAndCloseCallback callback) {
this.mOpenCloseCallback = callback;
}
public interface OpenAndCloseCallback {
void onOpen();
void onClose();
}
/**
* 设置文本内容处理
*
* @param handler
*/
public void setCharSequenceToSpannableHandler(CharSequenceToSpannableHandler handler) {
mCharSequenceToSpannableHandler = handler;
}
public interface CharSequenceToSpannableHandler {
@NonNull
SpannableStringBuilder charSequenceToSpannable(CharSequence charSequence);
}
class ExpandCollapseAnimation extends Animation {
private final View mTargetView;//动画执行view
private final int mStartHeight;//动画执行的开始高度
private final int mEndHeight;//动画结束后的高度
ExpandCollapseAnimation(View target, int startHeight, int endHeight) {
mTargetView = target;
mStartHeight = startHeight;
mEndHeight = endHeight;
setDuration(400);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
mTargetView.setScrollY(0);
//计算出每次应该显示的高度,改变执行view的高度实现动画
mTargetView.getLayoutParams().height = (int) ((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);
mTargetView.requestLayout();
}
}
}

View File

@ -18,7 +18,7 @@ import androidx.core.content.ContextCompat;
import com.gh.common.util.DisplayUtils;
import com.gh.gamecenter.R;
public class ExpendTextView extends AppCompatTextView {
public class ExpandTextView extends AppCompatTextView {
private CharSequence mSnapshotText;
@ -31,11 +31,11 @@ public class ExpendTextView extends AppCompatTextView {
private ExpandCallback mExpandCallback;
public ExpendTextView(Context context) {
public ExpandTextView(Context context) {
super(context);
}
public ExpendTextView(Context context, AttributeSet attrs) {
public ExpandTextView(Context context, AttributeSet attrs) {
super(context, attrs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mMaxLines = getMaxLines();
@ -100,7 +100,7 @@ public class ExpendTextView extends AppCompatTextView {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme));
ds.setColor(ContextCompat.getColor(getContext(), R.color.theme_font));
ds.setUnderlineText(false);
}

View File

@ -21,7 +21,7 @@ class HighlightableTextView @JvmOverloads constructor(context: Context, attrs: A
}
override fun setText(text: CharSequence?, type: BufferType?) {
super.setText(TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(context, text.toString(), "###", R.color.theme, object : SimpleCallback<String> {
super.setText(TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(context, text.toString(), "###", R.color.theme_font, object : SimpleCallback<String> {
override fun onCallback(arg: String) {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager

View File

@ -0,0 +1,114 @@
package com.gh.common.view
import android.animation.*
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
import com.gh.gamecenter.R
import java.util.*
class LikeView : RelativeLayout {
private val num = floatArrayOf(-35f, -25f, -15f, 0f, 15f, 25f, 35f)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
fun runLikeAnimation(event: MotionEvent) {
val iv = ImageView(context)
val lp = LayoutParams(168, 150)
val widthPixels = context.resources.displayMetrics.widthPixels
val leftMargin = if (event.rawX.toInt() + 84 > widthPixels) {
widthPixels - 168
} else {
event.rawX.toInt() - 84
}
lp.leftMargin = leftMargin
lp.topMargin = event.rawY.toInt() - 220
iv.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_double_click_like))
iv.layoutParams = lp
addView(iv)
val animatorSet = AnimatorSet()
animatorSet.play(
scaleAni(iv, "scaleX", 1f, 2f, 50, 0))
.with(scaleAni(iv, "scaleY", 1f, 2f, 50, 0))
//缩放动画X轴2倍缩小至0.9倍
.with(scaleAni(iv, "scaleX", 2f, 0.9f, 100, 50))
//缩放动画Y轴2倍缩放至0.9倍
.with(scaleAni(iv, "scaleY", 2f, 0.9f, 100, 50))
//旋转动画,随机旋转角
.with(rotation(iv, 0, 0, num[Random().nextInt(6)]))
//渐变透明动画透明度从0-1
.with(alphaAni(iv, 0F, 1F, 100, 0))
//缩放动画X轴0.9倍缩小至
.with(scaleAni(iv, "scaleX", 0.9f, 1F, 50, 150))
//缩放动画Y轴0.9倍缩放至
.with(scaleAni(iv, "scaleY", 0.9f, 1F, 50, 150))
//位移动画Y轴从0上移至600
.with(translationY(iv, 0F, -800F, 1200, 400))
//透明动画从1-0
.with(alphaAni(iv, 1F, 0F, 500, 400))
//缩放动画X轴1至3倍
.with(scaleAni(iv, "scaleX", 1F, 3f, 800, 400))
//缩放动画Y轴1至3倍
.with(scaleAni(iv, "scaleY", 1F, 3f, 800, 400))
animatorSet.start()
animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
removeViewInLayout(iv)
}
})
}
private fun scaleAni(view: View, propertyName: String, from: Float, to: Float, time: Long, delayTime: Long): ObjectAnimator {
val ani: ObjectAnimator = ObjectAnimator.ofFloat(view, propertyName, from, to)
ani.interpolator = LinearInterpolator()
ani.startDelay = delayTime
ani.duration = time
return ani
}
private fun translationX(view: View, from: Float, to: Float, time: Long, delayTime: Long): ObjectAnimator {
val ani: ObjectAnimator = ObjectAnimator.ofFloat(view, "translationX", from, to)
ani.interpolator = LinearInterpolator()
ani.startDelay = delayTime
ani.duration = time
return ani
}
private fun translationY(view: View, from: Float, to: Float, time: Long, delayTime: Long): ObjectAnimator {
val ani: ObjectAnimator = ObjectAnimator.ofFloat(view, "translationY", from, to)
ani.interpolator = LinearInterpolator()
ani.startDelay = delayTime
ani.duration = time
return ani
}
private fun alphaAni(view: View, from: Float, to: Float, time: Long, delayTime: Long): ObjectAnimator {
val ani = ObjectAnimator.ofFloat(view, "alpha", from, to)
ani.interpolator = LinearInterpolator()
ani.startDelay = delayTime
ani.duration = time
return ani
}
private fun rotation(view: View, time: Long, delayTime: Long, vararg values: Float): ObjectAnimator {
val ani = ObjectAnimator.ofFloat(view, "rotation", *values)
ani.duration = time
ani.startDelay = delayTime
ani.interpolator = TimeInterpolator { input -> input }
return ani
}
}

View File

@ -0,0 +1,161 @@
package com.gh.common.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.core.view.MotionEventCompat;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;
public class NestedScrollRichEditor extends RichEditor implements NestedScrollingChild {
public static final String TAG = NestedScrollRichEditor.class.getSimpleName();
private int mLastMotionY;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedYOffset;
private boolean mChange;
private NestedScrollingChildHelper mChildHelper;
public NestedScrollRichEditor(Context context) {
super(context);
init();
}
public NestedScrollRichEditor(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public NestedScrollRichEditor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = false;
MotionEvent trackedEvent = MotionEvent.obtain(event);
final int action = MotionEventCompat.getActionMasked(event);
if (action == MotionEvent.ACTION_DOWN) {
mNestedYOffset = 0;
}
int y = (int) event.getY();
event.offsetLocation(0, mNestedYOffset);
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastMotionY = y;
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
result = super.onTouchEvent(event);
mChange = false;
break;
case MotionEvent.ACTION_MOVE:
int deltaY = mLastMotionY - y;
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
trackedEvent.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
int oldY = getScrollY();
mLastMotionY = y - mScrollOffset[1];
int newScrollY = Math.max(0, oldY + deltaY);
deltaY -= newScrollY - oldY;
if (dispatchNestedScroll(0, newScrollY - deltaY, 0, deltaY, mScrollOffset)) {
mLastMotionY -= mScrollOffset[1];
trackedEvent.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
if(mScrollConsumed[1]==0 && mScrollOffset[1]==0) {
if(mChange){
mChange =false;
trackedEvent.setAction(MotionEvent.ACTION_DOWN);
super.onTouchEvent(trackedEvent);
}else {
result = super.onTouchEvent(trackedEvent);
}
trackedEvent.recycle();
}else{
if(Math.abs(mLastMotionY - y) >= 10) {
if (!mChange) {
mChange = true;
super.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0));
}
}
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
stopNestedScroll();
result = super.onTouchEvent(event);
break;
}
return result;
}
// NestedScrollingChild
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}

View File

@ -26,18 +26,27 @@ class RoundStrokeBackgroundColorSpan(private val strokeColor: Int,
override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
val originalColor = paint.color
val originalTextSize = paint.textSize
paint.color = this.strokeColor
paint.style = Paint.Style.STROKE
paint.strokeWidth = strokeWidth.toFloat()
val fontMetrics = paint.fontMetrics
// 当目标字体大小与原字体大小不一样时,需要先用目标字体大小测量字体宽度
if (textSize != 0) {
paint.textSize = textSize.toFloat()
}
val fontMetrics = paint.fontMetrics
val textWidth = paint.measureText(text, start, end).toInt()
// 用原字体大小画椭圆
paint.textSize = originalTextSize
canvas.drawRoundRect(RectF(
x + halfStrokeWidth,
top.toFloat() + halfStrokeWidth,
x + halfStrokeWidth + paint.measureText(text, start, end).toInt(),
top + fontMetrics.bottom - fontMetrics.top + strokeWidth * 2 - halfStrokeWidth),
x + textWidth + halfStrokeWidth,
top + fontMetrics.bottom - fontMetrics.top),
DisplayUtils.dip2px(HaloApp.getInstance().application, 3f).toFloat(),
DisplayUtils.dip2px(HaloApp.getInstance().application, 3f).toFloat(),
paint)
@ -45,6 +54,11 @@ class RoundStrokeBackgroundColorSpan(private val strokeColor: Int,
paint.color = this.textColor
paint.style = Paint.Style.FILL
paint.strokeWidth = 0f
// 用目标字体大小画字
if (textSize != 0) {
paint.textSize = textSize.toFloat()
}
canvas.drawText(text, start, end, x + halfStrokeWidth, y.toFloat() - strokeWidth, paint)
paint.color = originalColor

View File

@ -2,15 +2,31 @@ package com.gh.common.view
import android.graphics.Rect
import android.view.View
import androidx.annotation.Dimension
import androidx.recyclerview.widget.RecyclerView
/**
* 简单的 recyclerView Item 装饰类
*
* @param onlyDecorateTheFirstItem 只装饰第一个 item
* @param notDecorateTheFirstItem 不装饰第一个 item
* @param notDecorateTheLastItem 不装饰最后一个 item
* @param notDecorateTheFirstTwoItems 不装饰前两个 item
*
* left, top ,right, bottom 分别是四边
*/
class SpacingItemDecoration(
var onlyDecorateTheFirstItem: Boolean = false,
var notDecorateTheFirstItem: Boolean = false,
var notDecorateTheLastItem: Boolean = false,
var notDecorateTheFirstTwoItems: Boolean = false,
@Dimension(unit = Dimension.PX)
var left: Int = 0,
@Dimension(unit = Dimension.PX)
var top: Int = 0,
@Dimension(unit = Dimension.PX)
var right: Int = 0,
@Dimension(unit = Dimension.PX)
var bottom: Int = 0)
: RecyclerView.ItemDecoration() {
@ -18,7 +34,10 @@ class SpacingItemDecoration(
if (onlyDecorateTheFirstItem) {
if (parent.getChildAdapterPosition(view) == 0) outRect.set(left, top, right, bottom)
} else {
if (parent.getChildAdapterPosition(view) == 0 && notDecorateTheFirstItem) {
if (parent.getChildAdapterPosition(view) == 0
&& (notDecorateTheFirstItem || notDecorateTheFirstTwoItems)) {
outRect.set(0, 0, 0, 0)
} else if(parent.getChildAdapterPosition(view) == 1 && notDecorateTheFirstTwoItems) {
outRect.set(0, 0, 0, 0)
} else if (parent.getChildAdapterPosition(view) == parent.adapter!!.itemCount - 1 && notDecorateTheLastItem) {
outRect.set(0, 0, 0, 0)

View File

@ -16,6 +16,7 @@ public class PagerLayoutManager extends LinearLayoutManager {
private static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
private static final int VERTICAL = OrientationHelper.VERTICAL;
private int mOrientation;
private int mLastPosition = -1;
/**
* 位移,用来判断移动方向
*/
@ -115,9 +116,11 @@ public class PagerLayoutManager extends LinearLayoutManager {
positionIdle = getPosition(viewIdle);
}
int childCount = getChildCount();
if (mOnViewPagerListener != null && childCount == 1) {
// if (mOnViewPagerListener != null && childCount == 1) {
if (mOnViewPagerListener != null && positionIdle != mLastPosition) {
mOnViewPagerListener.onPageSelected(positionIdle,
positionIdle == childCount - 1);
mLastPosition = positionIdle;
}
break;
case RecyclerView.SCROLL_STATE_DRAGGING:

View File

@ -243,6 +243,17 @@ public class DownloadManager implements DownloadStatusListener {
}
}
// 插件版本下载互斥弹窗
List<String> mutexPackage = gameEntity.getMutexPackage();
if (mutexPackage != null && mutexPackage.size() > 0) {
for (String pkg : mutexPackage) {
if (PackagesManager.isInstalled(pkg)) {
DialogUtils.showDownloadMutexDialog(context);
break;
}
}
}
DownloadEntity downloadEntity = new DownloadEntity();
downloadEntity.setUrl(apkEntity.getUrl());
downloadEntity.setName(gameEntity.getName());
@ -637,9 +648,10 @@ public class DownloadManager implements DownloadStatusListener {
private void startDownloadService() {
Intent serviceIntent = new Intent(mContext, DownloadService.class);
// 当满足系统版本大于 8.0 、应用在后台运行时以前台服务开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !HaloApp.getInstance().isRunningForeground) {
// 当满足系统版本大于 8.0 就以前台服务开启 DownloadService
// (因为即便在 SplashActivity 里初始化,也有可能报 not allowed to start service, app is in background 的错误)
// DownloadService 会调用 stopForeground 方法,理论上会去掉 `光环助手正在运行中` 的通知
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
mContext.startForegroundService(serviceIntent);
} else {
@ -734,7 +746,7 @@ public class DownloadManager implements DownloadStatusListener {
public void markDownloadedTaskAsRead() {
AppExecutor.getIoExecutor().execute(() -> {
boolean markHasChanged = false;
List<DownloadEntity> all = getAll();
for (DownloadEntity downloadEntity : all) {
DownloadStatus status = downloadEntity.getStatus();
@ -747,20 +759,20 @@ public class DownloadManager implements DownloadStatusListener {
}
}
}
if (markHasChanged) {
EventBus.getDefault().post(new EBDownloadStatus("download", "", "", "", "", ""));
}
});
}
/**
* 标记可用更新为已读 (用于下载管理页入口的 toolbar 红点显示)
*/
public void markUpdatableTaskAsRead() {
AppExecutor.getIoExecutor().execute(() -> {
boolean markHasChanged = false;
ArrayList<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
for (GameUpdateEntity update : updates) {
String mark = update.getId() + update.getPackageName();
@ -769,7 +781,7 @@ public class DownloadManager implements DownloadStatusListener {
if (!markHasChanged) markHasChanged = true;
}
}
if (markHasChanged) {
saveUpdateMarkToStorage();
EventBus.getDefault().post(new EBDownloadStatus("download", "", "", "", "", ""));

View File

@ -12,9 +12,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.Observable;
@ -30,7 +30,7 @@ import okhttp3.Response;
public class CacheManager {
private static final AtomicReference<CacheManager> INSTANCE = new AtomicReference<>();
private volatile HashMap<String, Call> downCalls;
private volatile ConcurrentHashMap<String, Call> downCalls;
private OkHttpClient mClient;
private File cacheDirectory = StorageUtils.getIndividualCacheDirectory(HaloApp.getInstance().getApplication());
private FileNameGenerator generator = new Md5FileNameGenerator();
@ -52,11 +52,11 @@ public class CacheManager {
}
private CacheManager() {
downCalls = new HashMap<>();
downCalls = new ConcurrentHashMap<>();
mClient = new OkHttpClient.Builder().build();
}
private synchronized HashMap<String, Call> getDownCalls() {
private synchronized ConcurrentHashMap<String, Call> getDownCalls() {
return downCalls;
}
@ -226,9 +226,14 @@ public class CacheManager {
}
private List<File> getAllFile() {
if (cacheDirectory.exists()) {
File[] files = cacheDirectory.listFiles();
return Arrays.asList(files);
try {
if (cacheDirectory.exists() && cacheDirectory.isDirectory()) {
File[] files = cacheDirectory.listFiles();
return Arrays.asList(files);
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
return new ArrayList<>();
}

View File

@ -0,0 +1,88 @@
package com.gh.download.cache
import android.net.Uri
import com.gh.common.runOnIoThread
import com.gh.common.util.NetworkUtils
import com.gh.gamecenter.BuildConfig
import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
import com.google.android.exoplayer2.upstream.cache.CacheUtil
import com.google.android.exoplayer2.util.Util
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import tv.danmaku.ijk.media.exo2.ExoSourceManager
import tv.danmaku.ijk.media.exo2.source.GSYExoHttpDataSource
import tv.danmaku.ijk.media.exo2.source.GSYExoHttpDataSourceFactory
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicBoolean
object ExoCacheManager {
private val threads = ConcurrentHashMap<String, AtomicBoolean>()
private const val preLength = 50 * 1024 * 1024L //预加载视频大小
fun preload(videoUri: String) {
if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
runOnIoThread {
threads[videoUri] = AtomicBoolean(false)
val contentLength = getContentLength(videoUri)
val cacheLength = if (contentLength >= preLength) preLength else contentLength
val dataSpec = DataSpec(Uri.parse(videoUri), 0, cacheLength, null)
val simpleCache = ExoSourceManager.getCacheSingleInstance(HaloApp.getInstance().application, null)
val dataSourceFactory = GSYExoHttpDataSourceFactory(Util.getUserAgent(HaloApp.getInstance().application,
"ExoCacheManager"), DefaultBandwidthMeter.Builder(HaloApp.getInstance().application).build(),
GSYExoHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
GSYExoHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, false)
val cacheDataSource = CacheDataSource(simpleCache, dataSourceFactory.createDataSource())
try {
CacheUtil.cache(dataSpec, simpleCache, CacheUtil.DEFAULT_CACHE_KEY_FACTORY, cacheDataSource, CacheUtil.ProgressListener { requestLength, bytesCached, newBytesCached ->
if (requestLength == bytesCached) {
threads.remove(videoUri)
}
if (BuildConfig.DEBUG) {
Utils.log("$requestLength--$bytesCached--$newBytesCached")
}
}, threads[videoUri])
} catch (e: Exception) {
threads.remove(videoUri)
e.printStackTrace()
}
}
}
}
fun cancel(videoUri: String) {
threads[videoUri]?.set(true)
}
fun cancelAll() {
for (entry in threads.entries) {
entry.value.set(true)
}
}
private fun getContentLength(downloadUrl: String): Long {
var contentLength = -1L
val request = Request.Builder()
.url(downloadUrl)
.build()
var response: Response? = null
try {
response = OkHttpClient.Builder().build().newCall(request).execute()
if (response!!.isSuccessful && response.body() != null) {
val length = response.body()!!.contentLength()
contentLength = if (length == 0L) -1L else length
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
response?.close()
}
return contentLength
}
}

View File

@ -59,12 +59,24 @@ public class GameDetailActivity extends NormalActivity {
* 启动游戏详情页面
*/
public static void startGameDetailActivity(Context context, String gameId, String entrance) {
startGameDetailActivity(context, gameId, false, entrance);
}
/**
* @param scrollToLibao 滚动到动态 tab 的礼包 item
*/
public static void startGameDetailActivity(Context context, String gameId, Boolean scrollToLibao, String entrance) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_GAMEID, gameId);
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance);
if (scrollToLibao) {
bundle.putInt(EntranceUtils.KEY_TARGET, GameDetailFragment.INDEX_TRENDES);
bundle.putBoolean(EntranceUtils.KEY_SCROLL_TO_LIBAO, true);
}
context.startActivity(getTargetIntent(context, GameDetailActivity.class, GameDetailFragment.class, bundle));
}
/**
* 启动游戏详情页面 with 曝光事件
*/

View File

@ -25,13 +25,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.avoidcallback.AvoidOnResultManager;
import com.gh.common.avoidcallback.Callback;
import com.gh.common.constant.Config;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.ExposureUtils;
@ -48,6 +47,7 @@ import com.gh.common.util.DeviceTokenUtils;
import com.gh.common.util.DeviceUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.DownloadNotificationHelper;
import com.gh.common.util.EntranceUtils;
import com.gh.common.util.LogUtils;
@ -91,6 +91,7 @@ import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.suggest.SuggestSelectFragment;
import com.gh.gamecenter.suggest.SuggestType;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
@ -102,6 +103,7 @@ import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.AppManager;
import com.lightgame.utils.Util_System_Phone_State;
import com.lightgame.utils.Utils;
import com.shuyu.gsyvideoplayer.utils.StorageUtils;
import com.tencent.bugly.beta.tinker.TinkerManager;
import com.tencent.bugly.crashreport.CrashReport;
@ -109,6 +111,7 @@ import com.tencent.bugly.crashreport.CrashReport;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
@ -130,17 +133,22 @@ import java.util.UUID;
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;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import tv.danmaku.ijk.media.exo2.ExoSourceManager;
import static com.gh.common.util.EntranceUtils.ENTRANCE_BROWSER;
import static com.gh.common.util.EntranceUtils.HOST_QQ;
import static com.gh.common.util.EntranceUtils.HOST_QQ_GROUP;
import static com.gh.common.util.EntranceUtils.HOST_WEB;
import static com.gh.common.util.EntranceUtils.KEY_DATA;
import static com.gh.common.util.EntranceUtils.KEY_NEXT_TO;
import static com.gh.common.util.EntranceUtils.KEY_TO;
import static com.gh.common.util.EntranceUtils.KEY_TYPE;
import static com.gh.gamecenter.fragment.MainWrapperFragment.INDEX_PERSONAL;
@ -155,6 +163,7 @@ public class MainActivity extends BaseActivity {
public final static String SWITCH_TO_VIDEO = "switch_to_video";
private final static String IS_SKIPPED = "is_skipped";
private final static String CURRENT_PAGE = "current_page";
private PackageViewModel mPackageViewModel;
@ -170,118 +179,6 @@ public class MainActivity extends BaseActivity {
private Handler handler = new Handler();
// todo 全局监听可能不应该放这里, MainActivity 销毁后此处无法工作
// 黄壮华 添加观察者 修改2015/8/15
private DataWatcher dataWatcher = new DataWatcher() {
@Override
public void onDataChanged(DownloadEntity downloadEntity) {
if (downloadEntity.getStatus() != DownloadStatus.downloading) {
LogUtils.uploadDownloadEvent(downloadEntity);
}
if (DownloadStatus.hijack.equals(downloadEntity.getStatus())) {
// 链接被劫持
processHijack(downloadEntity);
String nameAndPlatform = downloadEntity.getName() + ":"
+ PlatformUtils.getInstance(getApplicationContext()).getPlatformName(downloadEntity.getPlatform());
DataUtils.onMtaEvent(getApplicationContext(), "下载劫持", "游戏名字", nameAndPlatform, "网络状态" + DeviceUtils.getNetwork(getApplication()));
return;
} else if (DownloadStatus.notfound.equals(downloadEntity.getStatus())) {
// 404 Not Found
// 删除任务
downloadEntity.setStatus(DownloadStatus.cancel);
DownloadManager.getInstance(getApplicationContext()).cancel(downloadEntity.getUrl());
toast("该链接已失效!请联系管理员。");
MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
"游戏", downloadEntity.getName(),
"平台", downloadEntity.getPlatform());
DialogUtils.showAlertDialog(AppManager.getInstance().currentActivity()
, "下载失败"
, "下载链接已失效,建议提交反馈"
, "立即反馈", "取消"
, () -> SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(),
SuggestType.gameQuestion, "notfound",
StringUtils.buildString(downloadEntity.getName(), ",问题反馈:下载链接失效"),
new SimpleGameEntity(downloadEntity.getGameId(), downloadEntity.getName(), "")), null);
return;
} else if (DownloadStatus.neterror.equals(downloadEntity.getStatus())
|| DownloadStatus.timeout.equals(downloadEntity.getStatus())) {
toast("网络不稳定,下载任务已暂停");
DataLogUtils.uploadNeterrorLog(MainActivity.this, downloadEntity);
MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
"游戏", downloadEntity.getName(),
"平台", downloadEntity.getPlatform());
}
if (DownloadStatus.done.equals(downloadEntity.getStatus())) {
if (downloadEntity.getName().contains(getString(R.string.app_name))) {
DataUtils.onEvent(MainActivity.this, "软件更新", "下载完成");
startActivity(PackageUtils.getInstallIntent(MainActivity.this, downloadEntity.getPath(), true));
DataLogUtils.uploadUpgradeLog(MainActivity.this, "install"); //上传更新安装数据
} else {
statDoneEvent(downloadEntity);
String platform = PlatformUtils.getInstance(getApplicationContext())
.getPlatformName(downloadEntity.getPlatform());
if (platform != null) {
if (downloadEntity.isPluggable()) {
// 弹出插件化提示框
EventBus.getDefault().post(new EBShowDialog(PLUGGABLE, downloadEntity.getPath()));
} else if (downloadEntity.isPlugin()) {
toast(downloadEntity.getName() + " - " + platform + " - 下载完成");
} else {
toast(downloadEntity.getName() + " - 下载完成");
}
} else {
toast(downloadEntity.getName() + " - 下载完成");
}
if (!downloadEntity.isPluggable()) {
// 是否是自动安装
if (mSp.getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
if (FileUtils.isEmptyFile(downloadEntity.getPath())) {
toast(R.string.install_failure_hint);
DownloadManager.getInstance(MainActivity.this).cancel(downloadEntity.getUrl());
} else {
if (PackageUtils.isCanLaunchSetup(getApplicationContext(), downloadEntity.getPath())) {
downloadEntity.getMeta().put(Constants.MARK_ALREADY_TRIGGERED_INSTALLATION, "YES");
startActivity(PackageUtils.getInstallIntent(MainActivity.this, downloadEntity.getPath()));
} else {
// 弹出卸载提示框
EventBus.getDefault().post(new EBShowDialog(PLUGGABLE, downloadEntity.getPath()));
}
}
}
}
// 统计下载完成
uploadData(downloadEntity.getGameId(), downloadEntity.getPlatform());
}
// 下载过程分析统计
PackageManager pm = getApplicationContext().getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(downloadEntity.getPath(), PackageManager.GET_ACTIVITIES);
if (packageInfo == null) {
MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析"
, "游戏名字", downloadEntity.getName() + ":"
+ PlatformUtils.getInstance(getApplicationContext()).getPlatformName(downloadEntity.getPlatform()));
MtaHelper.onEventWithBasicDeviceInfo(
"解析包错误_新",
"游戏", downloadEntity.getName() + ":" + PlatformUtils.getInstance(getApplicationContext()).getPlatformName(downloadEntity.getPlatform()));
}
}
if (downloadEntity.getStatus() == DownloadStatus.done) {
EventBus.getDefault().post(new EBDownloadStatus("done", "", "", "", "", ""));
}
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -323,9 +220,6 @@ public class MainActivity extends BaseActivity {
DataUtils.getGid();
}
// 添加观察者
DownloadManager.getInstance(this).addObserver(dataWatcher);
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
final String message = Config.getExceptionMsg();
@ -377,7 +271,7 @@ public class MainActivity extends BaseActivity {
}, 2000);
// 耗时操作
HaloApp.getInstance().getMainExecutor().execute(() -> {
AppExecutor.getIoExecutor().execute(() -> {
// 上传数据
DataCollectionManager.getInstance(getApplicationContext()).upload();
// 获取默认配置
@ -391,26 +285,49 @@ public class MainActivity extends BaseActivity {
//启动app删除视频缓存文件
AppExecutor.getIoExecutor().execute(() -> {
File cacheFileDirectory = StorageUtils.getIndividualCacheDirectory(this);
if (cacheFileDirectory.exists() && cacheFileDirectory.isDirectory()) {
for (File file : cacheFileDirectory.listFiles()) {
FileUtils.deleteFile(file.getPath());
}
}
//创建nomedia文件
File noMediaFile = new File(cacheFileDirectory.getParent(), ".nomedia");
if (!cacheFileDirectory.exists()) {
cacheFileDirectory.mkdirs();
}
try {
/*File cacheFileDirectory = StorageUtils.getIndividualCacheDirectory(this);
if (cacheFileDirectory.exists() && cacheFileDirectory.isDirectory()) {
for (File file : cacheFileDirectory.listFiles()) {
FileUtils.deleteFile(file.getPath());
}
}
//创建nomedia文件
File noMediaFile = new File(cacheFileDirectory.getParent(), ".nomedia");
if (!cacheFileDirectory.exists()) {
cacheFileDirectory.mkdirs();
}
if (!noMediaFile.exists()) {
noMediaFile.createNewFile();
}
} catch (IOException e) {
}*/
String dirPath = getCacheDir().getAbsolutePath() + File.separator + "exo";
FileUtils.deleteFolder(new File(dirPath));
} catch (Exception e) {
e.printStackTrace();
}
});
//恢复顶部视频默认静音状态
SPUtils.setBoolean(Constants.SP_TOP_VIDEO_VOICE, true);
//恢复视频流非Wifi提醒
SPUtils.setBoolean(Constants.SP_NON_WIFI_TIPS, true);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
int currentPageIndex = savedInstanceState.getInt(CURRENT_PAGE, -1);
if (currentPageIndex >= 0) {
EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, currentPageIndex));
if (currentPageIndex == MainWrapperFragment.INDEX_VIDEO) {
DisplayUtils.setLightStatusBar(this, false);
}
}
}
}
@Override
@ -437,8 +354,6 @@ public class MainActivity extends BaseActivity {
@Override
protected void onDestroy() {
super.onDestroy();
// 退出后,同样需要更新通知栏进度
// DownloadManager.getInstance(this).removeObserver(dataWatcher);
handler.removeCallbacksAndMessages(null);
}
@ -474,7 +389,14 @@ public class MainActivity extends BaseActivity {
} else {
Intent skipIntent = new Intent(MainActivity.this, clazz);
skipIntent.putExtras(bundle);
startActivity(skipIntent);
// startActivity(skipIntent);
AvoidOnResultManager.Companion.getInstance(this)
.startForResult(skipIntent, (resultCode, data) -> {
Bundle nextToBundle = getIntent().getBundleExtra(KEY_NEXT_TO);
if (nextToBundle != null) {
EntranceUtils.jumpActivity(this, nextToBundle);
}
});
}
} else {
// 使用光环进行二次跳转的页面会经过这里
@ -502,11 +424,6 @@ public class MainActivity extends BaseActivity {
private void checkNotificationPermission() {
// 仅登录后再启动光环时请求一次权限
/*if (!SPUtils.getBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS)
&& UserManager.getInstance().isLoggedIn()) {
SPUtils.setBoolean(Constants.HAS_REQUESTED_NOTIFICATION_PERMISSIONS, true);
showNotificationHintDialog();
}*/
if (UserManager.getInstance().isLoggedIn()) {
NotificationHelper.showNotificationHintDialog(NotificationUgc.LOGIN);
}
@ -525,73 +442,6 @@ public class MainActivity extends BaseActivity {
.subscribe(new Response<>());
}
// 统计下载完成事件
private void statDoneEvent(DownloadEntity downloadEntity) {
ExposureUtils.DownloadType type;
String platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(downloadEntity.getPlatform());
Map<String, Object> kv1 = new HashMap<>();
kv1.put("版本", platform);
kv1.put("状态", "下载完成");
kv1.put("用户机型", Build.MODEL);
kv1.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
kv1.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
kv1.put("光环助手版本", BuildConfig.VERSION_NAME);
if (downloadEntity.isUpdate()) {
type = ExposureUtils.DownloadType.UPDATE;
if (downloadEntity.isPlugin()) {
type = ExposureUtils.DownloadType.PLUGIN_UPDATE;
}
DataUtils.onEvent(MainActivity.this, "游戏更新", downloadEntity.getName(), kv1);
} else {
type = ExposureUtils.DownloadType.DOWNLOAD;
}
Map<String, Object> kv2 = new HashMap<>();
kv2.put("版本", downloadEntity.getPlatform());
kv2.put("状态", "下载完成");
kv2.put("位置", downloadEntity.getEntrance());
kv2.put("游戏分平台", downloadEntity.getName() + "-" + platform);
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
DataUtils.onEvent(MainActivity.this, "游戏下载位置", downloadEntity.getName(), kv2);
if (downloadEntity.isPluggable()) {
Map<String, Object> kv3 = new HashMap<>();
kv3.put("下载", "下载完成");
kv3.put("版本", downloadEntity.getPlatform());
kv3.put("位置", downloadEntity.getEntrance());
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD;
DataUtils.onEvent(MainActivity.this, "插件化", downloadEntity.getName(), kv3);
DataUtils.onMtaEvent(this,
"插件化_新",
"位置", downloadEntity.getEntrance(),
"游戏", downloadEntity.getName() + "-" + downloadEntity.getPlatform(),
"操作", "下载完成",
"网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
}
ExposureUtils.logADownloadCompleteExposureEvent(
new GameEntity(downloadEntity.getGameId(), downloadEntity.getName()),
downloadEntity.getPlatform(),
downloadEntity.getExposureTrace(),
type);
DataCollectionUtils.uploadDownload(this, downloadEntity, "完成");
}
private void processHijack(DownloadEntity downloadEntity) {
// 删除任务
downloadEntity.setStatus(DownloadStatus.cancel);
DownloadManager.getInstance(getApplicationContext()).cancel(downloadEntity.getUrl());
// 弹出提示框
EventBus.getDefault().post(new EBShowDialog(DOWNLOAD_HIJACK));
// 记录链接被劫持
DataCollectionUtils.uploadHijack(this, downloadEntity);
// 上传劫持log
DataLogUtils.uploadHijack(this, downloadEntity);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mMainWrapperFragment.onHandleBackPressed()) {
@ -656,6 +506,7 @@ public class MainActivity extends BaseActivity {
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(IS_SKIPPED, isSkipped);
outState.putInt(CURRENT_PAGE, mMainWrapperFragment.getCurrentItem());
if (mMainWrapperFragment != null) {
outState.putInt(BaseFragment_ViewPager.ARGS_INDEX, mMainWrapperFragment.getCurrentItem());
}
@ -778,24 +629,6 @@ public class MainActivity extends BaseActivity {
});
}
@SuppressLint("CheckResult")
private void showNotificationHintDialog() {
if (!SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_LOGIN)) {
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();
DialogUtils.showForceDialog(MainActivity.this, "数据同步提醒"
@ -810,7 +643,7 @@ public class MainActivity extends BaseActivity {
// 获取META-INF中的plugin_update 文件判断是否从游戏插件中下载的app是则获取游戏id启动游戏更新下载该游戏
private void getPluginUpdate() {
HaloApp.getInstance().getMainExecutor().execute(() -> {
AppExecutor.getIoExecutor().execute(() -> {
ApplicationInfo appinfo = getApplicationInfo();
String sourceDir = appinfo.sourceDir;
ZipFile zipfile = null;

View File

@ -211,7 +211,7 @@ class NetworkDiagnosisActivity : ToolBarActivity() {
builder.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = resources.getColor(R.color.theme)
ds.color = resources.getColor(R.color.theme_font)
ds.isUnderlineText = false
}

View File

@ -15,8 +15,8 @@ import com.gh.gamecenter.DisplayType.*
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.search.SearchDefaultFragment
import com.gh.gamecenter.search.SearchGameDetailFragment
import com.gh.gamecenter.search.SearchGameListFragment
import com.gh.gamecenter.search.SearchGameIndexFragment
import com.gh.gamecenter.search.SearchGameResultFragment
import com.lightgame.utils.Util_System_Keyboard
import com.qq.gdt.action.ActionType
import io.reactivex.android.schedulers.AndroidSchedulers
@ -118,6 +118,7 @@ open class SearchActivity : BaseActivity() {
val newSearchKey = editable.toString().trim { it <= ' ' }
if (newSearchKey.isEmpty()) {
updateDisplayType(DisplayType.DEFAULT)
mPublishSubject?.onNext(newSearchKey)
} else if (!mIsAutoSearchDisabled) {
mPublishSubject?.onNext(newSearchKey)
}
@ -186,13 +187,13 @@ open class SearchActivity : BaseActivity() {
transaction.replace(R.id.search_result, SearchDefaultFragment(), SearchDefaultFragment::class.java.simpleName)
}
DisplayType.GAME_DIGEST -> {
val digestListFragment = SearchGameListFragment()
digestListFragment.setParams(mSearchKey, mSearchType.value)
val digestListFragment = SearchGameIndexFragment()
digestListFragment.setParams(mSearchKey ?: "", mSearchType.value)
transaction.replace(R.id.search_result, digestListFragment)
}
DisplayType.GAME_DETAIL -> {
val detailListFragment = SearchGameDetailFragment()
detailListFragment.setParams(mSearchKey, mSearchType.value)
val detailListFragment = SearchGameResultFragment()
detailListFragment.setParams(mSearchKey ?: "", mSearchType.value)
transaction.replace(R.id.search_result, detailListFragment)
}
}

View File

@ -15,7 +15,7 @@ import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.VideoLinkEntity;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
import com.halo.assistant.HaloApp;
import com.gh.gamecenter.video.videomanager.VideoManagerActivity;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
@ -33,6 +33,7 @@ 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_UPLOAD_VIDEO;
import static com.gh.common.util.EntranceUtils.HOST_USERHOME;
import static com.gh.common.util.EntranceUtils.HOST_VIDEO;
import static com.gh.common.util.EntranceUtils.HOST_VIDEO_COLLECTION;
import static com.gh.common.util.EntranceUtils.HOST_VIDEO_MORE;
@ -91,7 +92,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToArticle(this, path, ENTRANCE_BROWSER);
break;
case HOST_GAME:
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, false);
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, false, "libao".equals(to));
break;
case HOST_COLUMN:
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER);
@ -169,13 +170,11 @@ public class SkipActivity extends BaseActivity {
String categoryId = uri.getQueryParameter("category_id");
String link = uri.getQueryParameter("link");
VideoLinkEntity linkEntity = new VideoLinkEntity(title, categoryId, link);
if (!CheckLoginUtils.isLogin()) {
HaloApp.put(HOST_UPLOAD_VIDEO, linkEntity);
}
CheckLoginUtils.checkLogin(this, EntranceUtils.ENTRANCE_BROWSER, () -> {
DirectUtils.directToVideoManager(this,linkEntity, EntranceUtils.ENTRANCE_BROWSER, "");
});
// if (!CheckLoginUtils.isLogin()) {
// HaloApp.put(HOST_UPLOAD_VIDEO, linkEntity);
// }
Bundle nextToBundle = VideoManagerActivity.getVideoManagerBundle(linkEntity, EntranceUtils.ENTRANCE_BROWSER, "");
CheckLoginUtils.checkLogin(this, nextToBundle, true, EntranceUtils.ENTRANCE_BROWSER, null);
break;
case HOST_VIDEO_SINGLE:
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.getValue(),
@ -227,6 +226,10 @@ public class SkipActivity extends BaseActivity {
case HOST_LIBAO:
DirectUtils.directToGiftDetail(this, path, ENTRANCE_BROWSER);
break;
case HOST_USERHOME:
String position = uri.getQueryParameter("position");
DirectUtils.directToHomeActivity(this, path, TextUtils.isEmpty(position) ? -1 : Integer.parseInt(position), ENTRANCE_BROWSER, "浏览器");
break;
default:
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
return;

View File

@ -15,13 +15,9 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.g00fy2.versioncompare.Version;
import com.gh.base.BaseActivity;
import com.gh.common.AppExecutor;
import com.gh.common.constant.Config;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DeviceTokenUtils;
@ -43,7 +39,6 @@ import com.gh.gamecenter.manager.FilterManager;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.user.UserRepository;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.qq.gdt.action.ActionType;
@ -56,6 +51,10 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import pub.devrel.easypermissions.AfterPermissionGranted;
@ -135,7 +134,7 @@ public class SplashScreenActivity extends BaseActivity {
launchMainActivity();
}
HaloApp.getInstance().getMainExecutor().execute(() -> {
AppExecutor.getIoExecutor().execute(() -> {
Config.getGhzsSettings();
UsageStatsHelper.checkAndPostUsageStats();
@ -243,7 +242,7 @@ public class SplashScreenActivity extends BaseActivity {
if (EasyPermissions.hasPermissions(this, mPermissions)) {
MtaHelper.onEvent("授权情况", "启动授权", "都授权");
// 检查是否有旧版本光环,有就删掉
HaloApp.getInstance().getMainExecutor().execute(this::deleteOutdatedUpdatePackage);
AppExecutor.getIoExecutor().execute(this::deleteOutdatedUpdatePackage);
} else {
ActivityCompat.requestPermissions(this, mPermissions, REQUEST_PERMISSION_TAG);
}
@ -270,7 +269,7 @@ public class SplashScreenActivity extends BaseActivity {
private void logGrantedPermission(List<String> perms) {
if (perms.size() == 1) {
MtaHelper.onEvent("授权情况", "启动授权", "只授权存储");
HaloApp.getInstance().getMainExecutor().execute(this::deleteOutdatedUpdatePackage);
AppExecutor.getIoExecutor().execute(this::deleteOutdatedUpdatePackage);
} else {
if (perms.contains(Manifest.permission.READ_PHONE_STATE)) {
MtaHelper.onEvent("授权情况", "启动授权", "都不授权");

View File

@ -815,6 +815,9 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
message = content;
if (mSuggestType == SuggestType.crash) {
params.put("log", readFromFile());
if (BuildConfig.BUILD_TIME != 0) {
message = message + " [此闪退基于" + BuildConfig.BUILD_TIME + "测试包]";
}
}
}
message = mHideHint + message;

View File

@ -11,6 +11,8 @@ import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
@ -19,17 +21,12 @@ 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.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.request.ImageRequest;
import com.gh.base.BaseActivity;
import com.gh.common.AppExecutor;
import com.gh.common.Base64ImageHolder;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
@ -49,6 +46,7 @@ import com.github.piasy.biv.view.BigImageView;
import com.github.piasy.biv.view.FrescoImageViewFactory;
import com.lightgame.utils.Utils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -60,6 +58,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;
@ -288,11 +291,36 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
}
});
}
private void loadImage(String url, final BigImageView imageView) {
// 添加GIF支持
imageView.setImageViewFactory(new FrescoImageViewFactory());
imageView.showImage(Uri.parse(url));
if (TextUtils.isEmpty(url)) return;
if (url.startsWith("data:image/png;base64")) {
AppExecutor.getIoExecutor().execute(() -> {
String base64String = url.replace("data:image/png;base64", "");
try {
File imageFile = new File(getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".png");
byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile));
bos.write(decodedString);
bos.flush();
bos.close();
AppExecutor.getUiExecutor().execute(() -> {
imageView.setImageViewFactory(new FrescoImageViewFactory());
imageView.showImage(Uri.fromFile(imageFile));
});
} catch (Exception e) {
e.printStackTrace();
}
});
} else {
// 添加GIF支持
imageView.setImageViewFactory(new FrescoImageViewFactory());
imageView.showImage(Uri.parse(url));
}
}
private class ViewImageAdapter extends PagerAdapter implements OnSingleTapListener {

View File

@ -5,8 +5,6 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import com.gh.common.constant.Constants;
import com.gh.common.util.EntranceUtils;
import com.gh.gamecenter.entity.ConcernEntity;
@ -18,6 +16,8 @@ import java.net.URLEncoder;
import java.util.Date;
import java.util.Locale;
import androidx.annotation.NonNull;
/**
* Created by khy on 2016/10/18.
*/
@ -130,7 +130,7 @@ public class WebActivity extends NormalActivity {
url = Constants.BADGE_ADDRESS;
}
url = String.format(Locale.CHINA, "%s?user_id=%s&name=%s&icon=%s&timestamp=%d", url, userId, name, URLEncoder.encode(icon), Math.round(new Date().getTime() / 1000));
url = String.format(Locale.CHINA, "%s?user_id=%s&name=%s&icon=%s&timestamp=%d", url, userId, name, URLEncoder.encode(icon), Math.round((new Date().getTime() / 1000) / 1000));
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_URL, url);
bundle.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_TITLE, true);

View File

@ -220,7 +220,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
if (gameEntity.getInstallStatus() == INSTALLED) {
holder.gameSize.setText(R.string.installed);
holder.gameSize.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
holder.gameSize.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
} else {
holder.gameSize.setText(R.string.installed_not);
holder.gameSize.setTextColor(ContextCompat.getColor(mContext, R.color.red));

View File

@ -5,6 +5,9 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.constant.ItemViewType;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CommentUtils;
@ -26,8 +29,6 @@ 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;
@ -149,13 +150,10 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
private void initCommentViewHolder(final CommentViewHolder holder, int position) {
final CommentEntity commentEntity = mCommentList.get(position);
holder.commentLine.setVisibility(View.VISIBLE);
holder.commentLineBottom.setVisibility(View.GONE);
CommentUtils.setCommentUserView(mContext, holder, commentEntity);
CommentUtils.setCommentTime(holder.commentTimeTv, commentEntity.getTime());
TextHelper.highlightTextThatIsWrappedInsideWrapperByDefault(holder.commentContentTv, commentEntity.getContent());
ArticleCommentParent parent = commentEntity.getParent();
if (parent != null && !TextUtils.isEmpty(parent.getUser().getName())) {
@ -180,16 +178,23 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
holder.quoteContainer.setVisibility(View.GONE);
}
holder.commentLikeIv.setOnClickListener(v -> CheckLoginUtils.checkLogin(mContext,
holder.commentLikeContainer.setOnClickListener(v -> CheckLoginUtils.checkLogin(mContext,
"资讯文章-评论-点赞", () ->
CommentUtils.postVote(mContext,
commentEntity, holder.commentLikeCountTv,
holder.commentLikeIv, null)));
holder.itemView.setOnClickListener(v ->
holder.itemView.setOnClickListener(v -> {
if (holder.commentReply.getVisibility() == View.VISIBLE) {
CheckLoginUtils.checkLogin(mContext, "资讯文章-评论-回复", () -> {
mOnCommentCallBackListener.onCommentCallback(commentEntity);
});
}
});
holder.commentMore.setOnClickListener(v ->
CommentUtils.showReportDialog(commentEntity,
mContext, false,
mOnCommentCallBackListener, null, "资讯文章-评论"));
mContext, false, "资讯文章-评论"));
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));

View File

@ -9,6 +9,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.constant.Config;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CommentUtils;
@ -53,8 +56,6 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
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;
@ -390,7 +391,7 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
final CommentEntity finalCommentEntity = commentEntity;
final boolean finalIsHotComment = isHotComment;
final int finalCommentPosition = commentPosition;
holder.commentLikeIv.setOnClickListener(v ->
holder.commentLikeContainer.setOnClickListener(v ->
CheckLoginUtils.checkLogin(mContext, "资讯文章详情-评论详情-点赞",
() -> CommentUtils.postVote(mContext, finalCommentEntity, holder.commentLikeCountTv,
holder.commentLikeIv, () -> {
@ -410,10 +411,17 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
})
));
holder.itemView.setOnClickListener(v ->
holder.itemView.setOnClickListener(v -> {
if (holder.commentReply.getVisibility() == View.VISIBLE) {
CheckLoginUtils.checkLogin(mContext, "资讯文章详情-评论详情-回复", () -> {
mOnCommentCallBackListener.onCommentCallback(finalCommentEntity);
});
}
});
holder.commentMore.setOnClickListener(v ->
CommentUtils.showReportDialog(finalCommentEntity,
mContext, true,
mOnCommentCallBackListener, null, "资讯文章详情-评论详情"));
mContext, true, "资讯文章详情-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
@ -472,11 +480,7 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
viewHolder.itemView.setPadding(0, DisplayUtils.dip2px(mContext, 30), 0, 0);
viewHolder.hint.setText(R.string.comment_empty);
} else {
if (mNormalCommentList.size() > 10) {
viewHolder.hint.setText(R.string.comment_nomore);
} else {
viewHolder.hint.setText("");
}
viewHolder.hint.setText(R.string.comment_nomore);
viewHolder.loading.setVisibility(View.GONE);
}

View File

@ -16,12 +16,12 @@ import butterknife.BindView;
*/
public class CommentViewHolder extends BaseRecyclerViewHolder {
@BindView(R.id.comment_line)
public View commentLine;
@BindView(R.id.comment_content)
public TextView commentContentTv;
@BindView(R.id.comment_like)
public ImageView commentLikeIv;
@BindView(R.id.comment_like_container)
public View commentLikeContainer;
@BindView(R.id.comment_like_count)
public TextView commentLikeCountTv;
@BindView(R.id.comment_time)
@ -32,8 +32,8 @@ public class CommentViewHolder extends BaseRecyclerViewHolder {
public SimpleDraweeView commentUserBadgeIv;
@BindView(R.id.comment_user_name)
public TextView commentUserNameTv;
@BindView(R.id.comment_line_bottom)
public View commentLineBottom;
@BindView(R.id.comment_author)
public TextView commentAuthorTv;
@BindView(R.id.comment_badge)
public View commentBadge;
@ -50,6 +50,12 @@ public class CommentViewHolder extends BaseRecyclerViewHolder {
public TextView badgeNameTv;
@BindView(R.id.sdv_quote_author_badge)
public SimpleDraweeView quoteAuthorBadgeSdv;
@BindView(R.id.comment_more)
public View commentMore;
@BindView(R.id.comment_reply)
public View commentReply;
@BindView(R.id.reply_dividing_line)
public View replyLine;
public CommentViewHolder(View itemView) {
super(itemView);

View File

@ -180,10 +180,7 @@ class AmwayAdapter(context: Context, private var mViewModel: AmwayViewModel, pri
binding.amwayContentTv.setTextWithHighlightedTextWrappedInsideWrapper(amway.comment.content, copyClickedText = true)
}
val exposureEvent = ExposureEvent.createEvent(
gameEntity = amway.game.toGameEntity(),
source = listOf(basicExposureSource))
itemData.exposureEvent = exposureEvent
itemData.exposureEvent = ExposureEvent.createEvent(amway.game.toGameEntity(), listOf(basicExposureSource))
binding.gameContainer.setOnClickListener {
GameDetailActivity.startGameDetailActivity(binding.root.context, amway.game.id, "(安利墙)", itemData.exposureEvent)

View File

@ -61,6 +61,9 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
if (oldItemPosition >= mEntityList.size()) return false;
if (newItemPosition >= updateData.size()) return false;
DataType oldItem = mEntityList.get(oldItemPosition);
DataType newItem = updateData.get(newItemPosition);
return ListAdapter.this.areItemsTheSame(oldItem, newItem);
@ -68,6 +71,9 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
if (oldItemPosition >= mEntityList.size()) return false;
if (newItemPosition >= updateData.size()) return false;
DataType oldItem = mEntityList.get(oldItemPosition);
DataType newItem = updateData.get(newItemPosition);
return ListAdapter.this.areContentsTheSame(oldItem, newItem);

View File

@ -1,17 +1,28 @@
package com.gh.gamecenter.collection;
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.gh.base.OnListClickListener;
import com.gh.common.constant.ItemViewType;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder;
import com.gh.gamecenter.baselist.LoadType;
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding;
import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder;
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.qa.questions.detail.AnswerViewHolder;
import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
import com.lightgame.utils.Utils;
/**
* Created by khy on 22/12/17.
@ -21,12 +32,17 @@ public class AnswerAdapter extends ListAdapter<AnswerEntity> {
private OnListClickListener mListClickListener;
private String mEntrance;
private AnswerViewModel mListViewModel;
public AnswerAdapter(Context context, OnListClickListener listClickListener, String entrance) {
private String mEntrance;
private AnswerFragment.Type mType;
public AnswerAdapter(Context context, AnswerViewModel viewModel, AnswerFragment.Type type, OnListClickListener listClickListener, String entrance) {
super(context);
mListViewModel = viewModel;
mListClickListener = listClickListener;
mEntrance = entrance;
this.mType = type;
}
@Override
@ -43,8 +59,8 @@ public class AnswerAdapter extends ListAdapter<AnswerEntity> {
view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false);
return new FooterViewHolder(view, mListClickListener);
case ItemViewType.ITEM_BODY:
view = mLayoutInflater.inflate(R.layout.ask_answer_item, parent, false);
return new AnswerViewHolder(view, mListClickListener);
view = mLayoutInflater.inflate(R.layout.community_answer_item, parent, false);
return new CommunityAnswerItemViewHolder(CommunityAnswerItemBinding.bind(view));
default:
return null;
}
@ -54,7 +70,41 @@ public class AnswerAdapter extends ListAdapter<AnswerEntity> {
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case ItemViewType.ITEM_BODY:
((AnswerViewHolder) holder).initCollectionAnswerViewHolder(mEntityList.get(position), mEntrance);
CommunityAnswerItemViewHolder viewHolder = (CommunityAnswerItemViewHolder) holder;
AnswerEntity entity = mEntityList.get(position);
String path;
if (mType == AnswerFragment.Type.COLLECTION) {
path = "我的收藏-回答列表";
} else if (mType == AnswerFragment.Type.HISTORY) {
path = "浏览记录-回答列表";
} else {
path = "插入回答-收藏回答列表";
}
viewHolder.bindAnswerItem(entity, mEntrance, path);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (entity.getActive()) {
mContext.startActivity(AnswerDetailActivity.getIntent(mContext, entity.getId(), mEntrance, path));
} else {
showDeleteDialog(entity.getId());
}
if (!entity.getRead()) {
entity.setRead(true);
notifyItemChanged(position);
mListViewModel.postCollectionAnswerRead(entity.getId());
}
}
});
viewHolder.getBinding().title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Questions questions = entity.getQuestions();
mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.getId(), mEntrance, path));
}
});
break;
case ItemViewType.ITEM_FOOTER:
FooterViewHolder footerViewHolder = (FooterViewHolder) holder;
@ -64,6 +114,26 @@ public class AnswerAdapter extends ListAdapter<AnswerEntity> {
}
}
private void showDeleteDialog(String answerId) {
DialogUtils.showCancelAlertDialog(mContext, "提示"
, "内容已被删除,是否取消收藏?"
, "取消收藏", "暂不"
, () -> CollectionUtils.INSTANCE.deleteCollection(mContext, answerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
Utils.toast(mContext, R.string.collection_cancel);
mListViewModel.load(LoadType.REFRESH);
}
@Override
public void onError() {
Utils.toast(mContext, R.string.collection_cancel_failure);
}
}), null);
}
@Override
public int getItemCount() {
return mEntityList == null || mEntityList.isEmpty() ? 0 : mEntityList.size() + FOOTER_ITEM_COUNT;

View File

@ -4,18 +4,13 @@ import android.view.View;
import com.gh.common.history.HistoryDatabase;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.baselist.ListFragment;
import com.gh.gamecenter.baselist.LoadType;
import com.gh.gamecenter.baselist.NormalListViewModel;
import com.gh.gamecenter.eventbus.EBCollectionChanged;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.greenrobot.eventbus.Subscribe;
@ -23,13 +18,14 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.Single;
/**
* Created by khy on 22/12/17.
*/
public class AnswerFragment extends ListFragment<AnswerEntity, NormalListViewModel> {
public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel> {
private AnswerAdapter mAdapter;
private Type mType;
@ -42,7 +38,7 @@ public class AnswerFragment extends ListFragment<AnswerEntity, NormalListViewMod
@Override
protected ListAdapter provideListAdapter() {
return mAdapter == null ? mAdapter = new AnswerAdapter(getContext(), this, mEntrance) : mAdapter;
return mAdapter == null ? mAdapter = new AnswerAdapter(getContext(), mListViewModel, mType, this, mEntrance) : mAdapter;
}
@Override
@ -55,49 +51,23 @@ public class AnswerFragment extends ListFragment<AnswerEntity, NormalListViewMod
}
@Override
public void onListClick(View view, int position, Object data) {
AnswerEntity entity;
switch (view.getId()) {
case R.id.footerview_item:
if (mAdapter.isNetworkError()) {
mListViewModel.load(LoadType.RETRY);
}
break;
case R.id.ask_answer_item_constraintlayout:
case R.id.ask_answer_item_content:
entity = (AnswerEntity) data;
if (entity.getActive()) {
startActivity(AnswerDetailActivity.getIntent(getContext(), entity.getId(), mEntrance, "我的收藏-回答"));
} else {
showDeleteDialog(entity.getId());
}
break;
case R.id.ask_answer_item_title:
entity = (AnswerEntity) data;
Questions questions = entity.getQuestions();
startActivity(QuestionsDetailActivity.getIntent(getContext(), questions.getId(), mEntrance, "我的收藏-回答"));
break;
protected AnswerViewModel provideListViewModel() {
AnswerViewModel viewModel = ViewModelProviders.of(this).get(AnswerViewModel.class);
// TODO 因为 mType 是从外面传进来的,所以在应用回收重构时会为空,这里设置为 Type.Collection 只是为了不闪退,会影响逻辑(譬如当前类型为历史的时候)
if (mType == null) {
mType = Type.COLLECTION;
}
viewModel.setType(mType);
return viewModel;
}
private void showDeleteDialog(String answerId) {
DialogUtils.showCancelAlertDialog(getContext(), "提示"
, "内容已被删除,是否取消收藏?"
, "取消收藏", "暂不"
, () -> CollectionUtils.INSTANCE.deleteCollection(getContext(), answerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
toast(R.string.collection_cancel);
mListViewModel.load(LoadType.REFRESH);
}
@Override
public void onError() {
toast(R.string.collection_cancel_failure);
}
}), null);
@Override
public void onListClick(View view, int position, Object data) {
if (view.getId() == R.id.footerview_item) {
if (mAdapter.isNetworkError()) {
mListViewModel.load(LoadType.RETRY);
}
}
}
// 收藏事件
@ -111,6 +81,8 @@ public class AnswerFragment extends ListFragment<AnswerEntity, NormalListViewMod
public enum Type {
COLLECTION,
COLLECTION_ANSWER,
HISTORY
}
}

View File

@ -0,0 +1,50 @@
package com.gh.gamecenter.collection
import android.annotation.SuppressLint
import android.app.Application
import com.gh.common.history.HistoryDatabase
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
class AnswerViewModel(application: Application) : ListViewModel<AnswerEntity, AnswerEntity>(application) {
private var mApi = RetrofitManager.getInstance(getApplication()).api
var type: AnswerFragment.Type = AnswerFragment.Type.COLLECTION
override fun provideDataObservable(page: Int): Observable<MutableList<AnswerEntity>>? {
return null
}
override fun provideDataSingle(page: Int): Single<List<AnswerEntity>> {
return if (type == AnswerFragment.Type.COLLECTION) {
Single.fromObservable(mApi.getCollectionAnswer(UserManager.getInstance().userId, page))
} else {
HistoryDatabase.instance.answerDao().getAnswersWithOffset(20, (page - 1) * 20)
}
}
override fun mergeResultLiveData() {
mResultLiveData.addSource<List<AnswerEntity>>(mListLiveData) { mResultLiveData.postValue(it) }
}
@SuppressLint("CheckResult")
fun postCollectionAnswerRead(answerId: String) {
mApi
.postCollectionAnswerRead(UserManager.getInstance().userId, answerId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
}
})
}
}

View File

@ -1,21 +1,21 @@
package com.gh.gamecenter.collection
import android.content.Context
import android.graphics.Paint
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CollectionComunityArticleItemBinding
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.ArticleEntity
class CommunityArticleAdapter(context: Context,
val mType: CommunityArticleFragment.Type,
private val mViewModel: CommunityArticleViewModel,
private val mEntrance: String) : ListAdapter<ArticleEntity>(context) {
@ -28,7 +28,7 @@ class CommunityArticleAdapter(context: Context,
return ItemViewType.ITEM_BODY
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
return when (viewType) {
ItemViewType.ITEM_FOOTER -> {
@ -36,8 +36,8 @@ class CommunityArticleAdapter(context: Context,
FooterViewHolder(view)
}
else -> {
view = mLayoutInflater.inflate(R.layout.collection_comunity_article_item, parent, false)
CollectionCommunityArticleViewHolder(CollectionComunityArticleItemBinding.bind(view))
view = mLayoutInflater.inflate(R.layout.community_answer_item, parent, false)
CommunityAnswerItemViewHolder(CommunityAnswerItemBinding.bind(view))
}
}
}
@ -45,19 +45,12 @@ class CommunityArticleAdapter(context: Context,
override fun getItemCount(): Int = if (mEntityList.size == 0) 0 else mEntityList.size + 1
override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) {
if (holder is CollectionCommunityArticleViewHolder) {
val path = "我的收藏-文章"
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is CommunityAnswerItemViewHolder) {
val path = if (mType == CommunityArticleFragment.Type.COLLECTION) "我的收藏-文章列表" else "浏览记录-文章列表"
val entity = mEntityList[position]
holder.binding.data = entity
holder.bindArticleItem(entity, mEntrance, path)
if (entity.active) {
holder.binding.content.paint.flags = Paint.ANTI_ALIAS_FLAG
holder.binding.content.setTextColor(ContextCompat.getColor(mContext, R.color.title))
} else {
holder.binding.content.paint.flags = Paint.STRIKE_THRU_TEXT_FLAG
holder.binding.content.setTextColor(ContextCompat.getColor(mContext, R.color.hint))
}
holder.itemView.setOnClickListener {
if (entity.active) {
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, entity.community, entity.id, mEntrance, path))
@ -66,13 +59,12 @@ class CommunityArticleAdapter(context: Context,
mViewModel.deleteCollection(entity.community.id, entity.id)
}, null)
}
}
holder.binding.userIconContainer.setOnClickListener {
DirectUtils.directToHomeActivity(mContext, entity.user.id, mEntrance, path)
}
holder.binding.userName.setOnClickListener {
DirectUtils.directToHomeActivity(mContext, entity.user.id, mEntrance, path)
if (!entity.read) {
entity.read = true
holder.binding.unreadHint.visibility = View.GONE
mViewModel.postCollectionArticleRead(entity.community.id, entity.id)
}
}
} else if (holder is FooterViewHolder) {
holder.initItemPadding()

View File

@ -16,7 +16,7 @@ class CommunityArticleFragment : ListFragment<ArticleEntity, CommunityArticleVie
override fun provideListAdapter(): CommunityArticleAdapter {
if (mAdapter == null) {
mAdapter = CommunityArticleAdapter(context!!, mListViewModel, mEntrance)
mAdapter = CommunityArticleAdapter(context!!,mType, mListViewModel, mEntrance)
}
return mAdapter!!
}

View File

@ -1,11 +1,13 @@
package com.gh.gamecenter.collection
import android.annotation.SuppressLint
import android.app.Application
import com.gh.common.history.HistoryDatabase
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
@ -66,4 +68,15 @@ class CommunityArticleViewModel(application: Application) : ListViewModel<Articl
})
}
@SuppressLint("CheckResult")
fun postCollectionArticleRead(communityId: String, articleId: String){
RetrofitManager.getInstance(getApplication()).api
.postCollectionArticleRead(UserManager.getInstance().userId, communityId, articleId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
}
})
}
}

View File

@ -52,7 +52,7 @@ class VideoAdapter(context: Context,
if (mVideoStyle == VideoFragment.VideoStyle.COLLECT.value) {
DirectUtils.directToVideoDetail(mContext, entity.id, VideoDetailContainerViewModel.Location.USER_FAVORITE_VIDEO.value, false, path = getPath())
} else {
DirectUtils.directToVideoDetail(mContext, entity.id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value, false, path = getPath())
DirectUtils.directToVideoDetail(mContext, entity.id, VideoDetailContainerViewModel.Location.VIDEO_HOT.value, false, path = getPath())
}
}
} else if (holder is FooterViewHolder) {

View File

@ -10,6 +10,7 @@ import com.gh.common.history.HistoryDatabase
import com.gh.common.util.dip2px
import com.gh.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.entity.MyVideoEntity
import com.gh.gamecenter.manager.UserManager
@ -24,7 +25,7 @@ class VideoFragment : ListFragment<MyVideoEntity, NormalListViewModel<MyVideoEnt
override fun provideListAdapter(): VideoAdapter {
if (mAdapter == null) {
mAdapter = VideoAdapter(context!!, mListViewModel,mVideoStyle)
mAdapter = VideoAdapter(context!!, mListViewModel, mVideoStyle)
}
return mAdapter!!
}
@ -66,6 +67,10 @@ class VideoFragment : ListFragment<MyVideoEntity, NormalListViewModel<MyVideoEnt
}
override fun provideDataSingle(page: Int): Single<MutableList<MyVideoEntity>>? {
if (page > 5) {
mAdapter?.loadChange(LoadStatus.LIST_OVER)
return null
}
if (mVideoStyle == VideoStyle.BROWSING_HISTORY.value) {
return HistoryDatabase.instance.videoHistoryDao().getVideoWithOffset(20, (page - 1) * 20)
}

View File

@ -51,6 +51,18 @@ public class GameTrendsDao {
}
return 0;
}
public long findInternetPostTime(String userId){
try {
GameTrendsInfo gameTrendsInfo = dao.queryForId(userId);
if (gameTrendsInfo != null) {
return gameTrendsInfo.getInternetPostTime();
}
return 0;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public void add(GameTrendsInfo info) {
try {

View File

@ -13,6 +13,7 @@ import com.facebook.drawee.view.SimpleDraweeView
import com.gh.base.fragment.BaseFragment
import com.gh.common.AppExecutor
import com.gh.common.constant.Config
import com.gh.common.runOnIoThread
import com.gh.common.util.*
import com.gh.gamecenter.*
import com.gh.gamecenter.databinding.PieceDiscoverItemBinding
@ -140,7 +141,7 @@ class DiscoverFragment : BaseFragment<Any>() {
}
private fun showDot() {
AppExecutor.ioExecutor.execute {
runOnIoThread {
val gameTrendsInfo = mGameTrendsDao.findGameTrendsInfo(UserManager.getInstance().userId)
if (gameTrendsInfo != null) {
AppExecutor.uiExecutor.execute {
@ -152,7 +153,7 @@ class DiscoverFragment : BaseFragment<Any>() {
}
private fun removeDot() {
HaloApp.getInstance().mainExecutor.execute {
runOnIoThread {
val gameTrendsInfo = mGameTrendsDao.findGameTrendsInfo(UserManager.getInstance().userId)
if (gameTrendsInfo != null) {
gameTrendsInfo.readPostTime = gameTrendsInfo.internetPostTime

View File

@ -131,7 +131,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
downloadEntity.getPath()), downloadEntity.getUrl());
// 用户焦点在下载管理页面时有任务完成,直接把所有下载完成的任务标记为已读
DownloadManager.getInstance(requireContext()).markDownloadedTaskAsRead();
DownloadManager.getInstance(HaloApp.getInstance().getApplication()).markDownloadedTaskAsRead();
} else if (DownloadStatus.cancel.equals(downloadEntity.getStatus())) { // 有可能由于网络劫持造成的
adapter.initMap();
adapter.notifyDataSetChanged();
@ -389,7 +389,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
}
DownloadManager.getInstance(getContext()).pauseAll();
mDownloadmanagerAllstartTv.setText("全部开始");
mDownloadmanagerAllstartTv.setTextColor(ContextCompat.getColor(getContext(), R.color.theme));
mDownloadmanagerAllstartTv.setTextColor(ContextCompat.getColor(getContext(), R.color.theme_font));
}
private void startAll() {

View File

@ -196,14 +196,14 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
0, LinearLayout.LayoutParams.WRAP_CONTENT);
lparams.weight = 4;
viewHolder.dmDownloads.setLayoutParams(lparams);
viewHolder.dmDownloads.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dmDownloads.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
viewHolder.dmDownloads.setText(String.format("%s(剩%s)",
SpeedUtils.getSpeed(downloadEntity.getSpeed()),
SpeedUtils.getRemainTime(downloadEntity.getSize(), downloadEntity.getProgress(), downloadEntity.getSpeed() * 1024)));
viewHolder.dmDelete.setVisibility(View.GONE);
viewHolder.dmStartorpause.setBackgroundResource(R.drawable.game_item_btn_downloading_bg);
viewHolder.dmStartorpause.setText("暂停");
viewHolder.dmStartorpause.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dmStartorpause.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
viewHolder.dmSpeed.setText(downloadEntity.getPercent() + "%");
}
} else if (status.equals(DownloadStatus.waiting)) {
@ -272,7 +272,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
0, LinearLayout.LayoutParams.WRAP_CONTENT);
lparams.weight = 4;
viewHolder.dmDownloads.setLayoutParams(lparams);
viewHolder.dmDownloads.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dmDownloads.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
viewHolder.dmDownloads.setText(String.format("%s(剩%s)",
SpeedUtils.getSpeed(downloadEntity.getSpeed()),
SpeedUtils.getRemainTime(downloadEntity.getSize(),
@ -281,7 +281,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
viewHolder.dmStartorpause.setBackgroundResource(R.drawable.game_item_btn_downloading_bg);
viewHolder.dmStartorpause.setText("暂停");
viewHolder.dmStartorpause.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dmStartorpause.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
statusMap.put(url, DownloadStatus.downloading.getStatus());
notifyItemChanged(doneList.isEmpty() ? 0 : 1 + doneList.size());
@ -399,7 +399,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
viewHolder.dm_item_head_tv_allstart.setTextColor(ContextCompat.getColor(mContext, R.color.btn_gray));
} else {
viewHolder.dm_item_head_tv_allstart.setText(R.string.download_all_start);
viewHolder.dm_item_head_tv_allstart.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dm_item_head_tv_allstart.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
}
viewHolder.dm_item_head_tv_allstart.setOnClickListener(v -> {
@ -450,7 +450,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
// DownloadManager.getInstance(mContext).pauseAll();
viewHolder.dm_item_head_tv_allstart.setText("全部开始");
viewHolder.dm_item_head_tv_allstart.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.dm_item_head_tv_allstart.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
}

View File

@ -394,7 +394,7 @@ class GameUpdateFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> implemen
}
} else {
viewHolder.guUpdate.setText(R.string.launch);
viewHolder.guUpdate.setTextColor(ContextCompat.getColor(mContext, R.color.theme));
viewHolder.guUpdate.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font));
viewHolder.guUpdate.setBackgroundResource(R.drawable.detail_downloading_normal_style);
}
} else {

View File

@ -7,7 +7,6 @@ import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.ethanhua.skeleton.Skeleton
@ -15,6 +14,7 @@ import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.base.OnRequestCallBackListener
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DownloadItemUtils
import com.gh.common.view.FixLinearLayoutManager
import com.gh.common.view.VerticalItemDecoration
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
@ -81,7 +81,7 @@ class InstalledGameFragment : NormalFragment(), OnRequestCallBackListener<Any> {
MainActivity.skipToMainActivity(getActivity(), MainWrapperFragment.INDEX_HOME)
}
mInstallRv.layoutManager = LinearLayoutManager(requireContext())
mInstallRv.layoutManager = FixLinearLayoutManager(requireContext())
(mInstallRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
mAdapter = InstalledGameFragmentAdapter(this)
mExposureListener = ExposureListener(this, mAdapter!!)

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter.download;
import android.text.TextUtils;
import android.view.ViewGroup;
import com.gh.common.AppExecutor;
import com.gh.common.constant.ItemViewType;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureSource;
@ -28,7 +29,6 @@ import com.gh.gamecenter.entity.GameInstall;
import com.gh.gamecenter.game.GameItemViewHolder;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.adapter.BaseRecyclerAdapter;
import java.util.ArrayList;
@ -97,7 +97,7 @@ public class InstalledGameFragmentAdapter extends BaseRecyclerAdapter<ViewHolder
if (sortedList.isEmpty()) {
mFragment.loadEmpty();
} else {
HaloApp.getInstance().getMainExecutor().execute(() -> {
AppExecutor.getIoExecutor().execute(() -> {
List<String> ids = new ArrayList<>();
Collections.sort(sortedList, (lhs, rhs) -> { // 按安装时间排序
if (rhs.getInstallTime() > lhs.getInstallTime()) {

View File

@ -0,0 +1,5 @@
package com.gh.gamecenter.entity
data class AddonsUnreadEntity(
var favorite: Int = 0//我的收藏未读
)

View File

@ -19,9 +19,16 @@ data class FunctionalLinkEntity(
var icon: String = "",// 客户端展示的icon
@DrawableRes
var iconRes: Int = 0, // 客户端展示的icon
var message: String = ""
@SerializedName("remind_switch")
var remind: Boolean = false,//分组提醒
var message: FunctionalMessageType? = null
) : LinkEntity()
enum class FunctionalMessageType {
NEW_VERSION,
NEW_MESSAGE
}
/*
data class FunctionalLinkEntity(

View File

@ -161,7 +161,9 @@ data class GameEntity(
@SerializedName("played_time")
val playedTime: Long = 0,
@SerializedName("played_game_id")
val playedGameId: String = "") : Parcelable {
val playedGameId: String = "",
@SerializedName("mutex_package")
val mutexPackage: List<String>? = null) : Parcelable {
@IgnoredOnParcel
private var entryMap: androidx.collection.ArrayMap<String, DownloadEntity>? = androidx.collection.ArrayMap()

View File

@ -4,6 +4,7 @@ import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class PersonalEntity(
@SerializedName("_id")
val id: String = "",
@ -13,8 +14,8 @@ data class PersonalEntity(
val count: Count = Count(),
val auth: Auth? = null,
val badge: Badge? = null,
val me: MeEntity = MeEntity()) {
val me: MeEntity = MeEntity()) : Parcelable {
@Parcelize
data class Count(
// 包括回答点赞和社区文章点赞
val vote: Int? = 0,
@ -26,7 +27,7 @@ data class PersonalEntity(
val communityArticle: Int = 0,
@SerializedName("game_comment")
val gameComment: Int = 0,
val video: Int = 0) {
val video: Int = 0) : Parcelable {
fun getQaCount() = answer + question + communityArticle
}

View File

@ -5,22 +5,23 @@ import com.gh.gamecenter.qa.entity.CommunityVideoEntity
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class PersonalHistoryEntity(
@SerializedName("_id")
val id: String = "",
val type: String = "",
val question: Question = Question(),
val brief: String = "",
var question: Question = Question(),
var brief: String = "",
var count: Count = Count(),
val time: Long = 0,
val title: String = "",
var title: String = "",
val community: CommunityEntity = CommunityEntity(),
var videos: List<CommunityVideoEntity> = ArrayList(),
var user: PersonalEntity? = null,
@SerializedName("fold_users")
var foldUsers: List<UserEntity>? = null,
val images: List<String> = ArrayList(),
val comment: Comment = Comment()) {
var comment: Comment = Comment()) :Parcelable{
fun getPassVideos(): List<CommunityVideoEntity> {
val passVideos = arrayListOf<CommunityVideoEntity>()
@ -31,23 +32,24 @@ data class PersonalHistoryEntity(
}
@Parcelize
data class Question(
@SerializedName("_id")
val id: String = "",
val title: String = "")
var title: String = ""):Parcelable
@Parcelize
data class Count(
var comment: Int = -1,
val vote: Int = -1,
val answer: Int = -1,
val reply: Int = -1)
var vote: Int = -1,
var answer: Int = -1,
var reply: Int = -1):Parcelable
@Parcelize
data class Comment(
@SerializedName("_id")
val id: String = "",
val star: Int = 0,
val content: String = "",
val game: Game = Game())
var star: Int = 0,
var content: String = "",
val game: Game = Game()):Parcelable
@Parcelize
data class Game(

View File

@ -1,7 +1,10 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
class RatingReplyEntity(@SerializedName("_id")
val id: String = "",
val content: String = "",
@ -10,7 +13,7 @@ class RatingReplyEntity(@SerializedName("_id")
val user: UserEntity = UserEntity(),
var vote: Int = 0,
val weight: Int = 0,
val parent: Parent? = null) {
class Parent(val user: UserEntity)
val parent: Parent? = null) : Parcelable {
@Parcelize
class Parent(val user: UserEntity) : Parcelable
}

View File

@ -41,6 +41,7 @@ data class SubjectRecommendEntity(
@Parcelize
data class Display(var slide: Boolean = true,
var recommend: Boolean = true) : Parcelable
var recommend: Boolean = true,
var refresh: Boolean = false) : Parcelable

View File

@ -0,0 +1,7 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
data class SubjectRefreshEntity(@SerializedName("column_id")
val columnId: String = "",
val games: List<GameEntity>)

View File

@ -0,0 +1,27 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
// "game": {},// 游戏详情数据
// "articles": [],// 游戏文章
// "toolkits": [],// 游戏工具箱
// "libao": [],// 游戏礼包
// "community": {},// 社区,无数据时,此字段不存在
// "community_column_contents": []// 社区专题内容(热门回答),无数据时,此字段不存在
@Parcelize
data class UnifiedGameDetailEntity(
var game: GameDetailEntity,
var articles: List<NewsEntity>?,
var toolkits: List<ToolBoxEntity>?,
var libao: List<LibaoEntity>?,
var community: CommunityEntity?,
@SerializedName("community_column_contents")
var communityColumnContents: List<AnswerEntity>?) : Parcelable {
companion object {
const val TAG: String = "UnifiedGameDetailEntity"
}
}

View File

@ -0,0 +1,11 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.google.gson.annotations.SerializedName
data class UnifiedUserTrendEntity(
var game: List<GameDetailEntity>?,
var toolkit: List<ToolBoxEntity>?,
var libao: List<LibaoEntity>?,
@SerializedName("community_column_content")
var communityColumnContents: List<AnswerEntity>?)

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.fragment;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
@ -93,7 +94,7 @@ public class LoginFragment extends NormalFragment implements LoginUtils.onCaptch
mLoginCaptcha.setText(arg1 + "s后重新获取");
} else {
mLoginCaptcha.setText("重新获取");
mLoginCaptcha.setTextColor(ContextCompat.getColor(getContext(), R.color.text_1383EB));
mLoginCaptcha.setTextColor(ContextCompat.getColor(getContext(), R.color.theme_font));
// mLoginCaptcha.setBackgroundResource(R.drawable.border_black_bg);
mLoginCaptcha.setEnabled(true);
}
@ -131,7 +132,7 @@ public class LoginFragment extends NormalFragment implements LoginUtils.onCaptch
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(getResources().getColor(R.color.theme));
ds.setColor(getResources().getColor(R.color.theme_font));
ds.setUnderlineText(false);
}
@ -148,7 +149,7 @@ public class LoginFragment extends NormalFragment implements LoginUtils.onCaptch
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(getResources().getColor(R.color.text_1383EB));
ds.setColor(getResources().getColor(R.color.theme_font));
ds.setUnderlineText(false);
}
@ -268,13 +269,13 @@ public class LoginFragment extends NormalFragment implements LoginUtils.onCaptch
mUserViewModel.retryCheckLogin();
}
Object videoLinkEntity = HaloApp.get(HOST_UPLOAD_VIDEO, true);
/*Object videoLinkEntity = HaloApp.get(HOST_UPLOAD_VIDEO, true);
if (videoLinkEntity instanceof VideoLinkEntity) {
startActivity(VideoManagerActivity.getIntent(
requireContext(),
(VideoLinkEntity) videoLinkEntity,
EntranceUtils.ENTRANCE_BROWSER, ""));
}
}*/
if (getActivity() != null) getActivity().finish();
}

View File

@ -51,6 +51,7 @@ import com.gh.gamecenter.game.GameFragment;
import com.gh.gamecenter.home.HomeFragment;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.message.MessageUnreadRepository;
import com.gh.gamecenter.message.MessageUnreadViewModel;
import com.gh.gamecenter.personal.PersonalFragment;
import com.gh.gamecenter.qa.CommunityFragment;
import com.gh.gamecenter.video.detail.VideoDetailContainerFragment;
@ -73,6 +74,7 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import butterknife.BindView;
import static com.gh.gamecenter.MainActivity.EB_SKIP_MAIN;
@ -85,6 +87,8 @@ import static com.gh.gamecenter.MainActivity.EB_SKIP_MAIN;
public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implements OnBackPressedListener {
@BindView(R.id.view_shadow)
View mShadowView;
@BindView(R.id.main_tab_game)
View mMainTab;
@BindView(R.id.main_iv_message_hint)
@ -121,6 +125,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
private SearchToolWrapperFragment mGameWrapperFragment;
private MainWrapperViewModel mViewModel;
private MessageUnreadViewModel mMessageUnreadViewModel;
private GameTrendsDao mGameTrendsDao;
private VideoDetailContainerFragment videoDetailContainerFragment;
private String[] resAssets = {"lottie/tab_home.json", "lottie/tab_game.json", "lottie/tab_video.json", "tab_community.gif", "tab_mine.gif"};
@ -188,8 +193,9 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
}
mViewModel = ViewModelProviders.of(this).get(MainWrapperViewModel.class);
mMessageUnreadViewModel = ViewModelProviders.of(this).get(MessageUnreadViewModel.class);
mViewModel.getNavBar().observe(this, this::updateGameBarContent);
mViewModel.getConcernData().observe(this, concernData -> {
/*mViewModel.getConcernData().observe(this, concernData -> {
if (concernData != null && concernData.size() > 0) {
ConcernEntity entity = concernData.get(0);
long internetPostTime = entity.getTime();
@ -200,7 +206,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
EventBus.getDefault().post(new EBReuse(DiscoverFragment.SHOW_DISCOVERY_DOT));
}
}
});
});*/
mViewModel.getReserveDialog().observe(this, reserveData -> {
if (reserveData != null && !reserveData.isEmpty()) {
@ -214,6 +220,9 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
MessageUnreadRepository.INSTANCE.loadMessageUnreadData();
}
});
mMessageUnreadViewModel.getUnreadMessageTotalLiveData().observe(this, isShow -> {
mMessageHintIv.setVisibility(isShow ? View.VISIBLE : View.GONE);
});
// 判断是否是第一次启动应用,不是的话不弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
@ -265,7 +274,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
@Override
public void onResume() {
super.onResume();
mViewModel.getDiscoveryData(false);
//mViewModel.getDiscoveryData(false);
MessageUnreadRepository.INSTANCE.loadMessageUnreadTotal();
}
@Override
@ -314,10 +324,12 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
private void changeColor(int toCheck) {
if (toCheck == INDEX_VIDEO) {
mShadowView.setVisibility(View.GONE);
mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.transparent));
changeTabImageColor(R.color.text_A1A5B7, PorterDuff.Mode.SRC_ATOP);
changeTabTextColor(R.color.text_A1A5B7, false);
} else {
mShadowView.setVisibility(View.VISIBLE);
mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white));
changeTabImageColor(R.color.text_50556B, PorterDuff.Mode.DST);
changeTabTextColor(R.color.tab_selector, true);
@ -516,7 +528,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
// 控制 我的光环消息未读红点
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBReuse reuse) {
if (PersonalFragment.MESSAGE_READ_OVER.equals(reuse.getType())) { // 消息阅读完成
/*if (PersonalFragment.MESSAGE_READ_OVER.equals(reuse.getType())) { // 消息阅读完成
if (mMessageHintIv != null) {
mMessageHintIv.setVisibility(View.GONE);
}
@ -524,7 +536,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
if (mMessageHintIv != null) {
mMessageHintIv.setVisibility(View.VISIBLE);
}
}/* else if (DiscoverFragment.SHOW_DISCOVERY_DOT.equals(reuse.getType())) {
} else if (DiscoverFragment.SHOW_DISCOVERY_DOT.equals(reuse.getType())) {
if (mDiscoveryHintIv != null) {
mDiscoveryHintIv.setVisibility(View.VISIBLE);
}
@ -540,7 +552,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
if (mDiscoveryHintIv != null) {
mViewModel.getDiscoveryData(true);
}
} */ else if ("Refresh".equals(reuse.getType())) {
} */
if ("Refresh".equals(reuse.getType())) {
SettingsEntity settings = Config.getSettings();
if (settings != null && !settings.showCommunityEntrance()) {
mTabCommunity.setVisibility(View.GONE);

View File

@ -12,7 +12,9 @@ import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.EntranceUtils
import com.gh.common.util.dip2px
import com.gh.common.util.toJson
import com.gh.common.util.visibleIf
import com.gh.common.view.FixLinearLayoutManager
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
@ -29,6 +31,8 @@ import com.gh.gamecenter.normal.NormalFragment
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import com.lightgame.view.CheckableImageView
import kotterknife.bindView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -37,6 +41,7 @@ class GameFragment : NormalFragment() {
private val mNoConn by bindView<View>(R.id.reuse_no_connection)
private val mLoading by bindView<View>(R.id.reuse_ll_loading)
private val mReplaceDataButton by bindView<CheckableImageView>(R.id.replace_data_button)
private lateinit var mViewModel: GameViewModel
@ -100,11 +105,20 @@ class GameFragment : NormalFragment() {
layoutManager = mLayoutManager
adapter = mListAdapter
}
var listScrollHeight = 0
mBinding.gameList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (mLayoutManager.findLastVisibleItemPosition() == mListAdapter.itemCount - 1
&& RecyclerView.SCROLL_STATE_IDLE == newState) mViewModel.getSubjectList(false)
mReplaceDataButton.isEnabled = RecyclerView.SCROLL_STATE_IDLE == newState
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
listScrollHeight += dy
mReplaceDataButton.visibleIf(mViewModel.blockData?.display?.refresh == true && listScrollHeight > 100F.dip2px())
}
})
@ -116,6 +130,14 @@ class GameFragment : NormalFragment() {
}
mNoConn.setOnClickListener { mViewModel.initData() }
mReplaceDataButton.setOnClickListener {
val firstVisiblePosition = mLayoutManager.findFirstVisibleItemPosition()
val lastVisiblePosition = mLayoutManager.findLastVisibleItemPosition()
for (position in firstVisiblePosition..lastVisiblePosition) {
val itemData = mListAdapter.getItemDataByPosition(position)
if (itemData != null && mViewModel.replaceRefreshData(itemData)) mListAdapter.notifyItemChanged(position)
}
}
mSkeleton = Skeleton.bind(mBinding.gameSkeletonContainer).shimmer(false).load(R.layout.fragment_game_skeleton).show()
}
@ -170,6 +192,7 @@ class GameFragment : NormalFragment() {
fun onEventMainThread(busNine: EBUISwitch) {
if (MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
&& MainWrapperFragment.INDEX_GAME == busNine.position) {
mBinding.gameList.stopScroll()
mLayoutManager.scrollToPosition(0)
}
}

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