Compare commits

..

120 Commits

Author SHA1 Message Date
1bc5bb3ef6 tinker_base-3.7.5 2020-04-10 11:26:12 +08:00
2719bff65f 修改视频分享统计问题 2020-04-09 14:23:21 +08:00
b87972143d 修复搜索页可能的闪退问题 2020-04-09 11:01:15 +08:00
0cdec2a226 捕抓自动安装闪退 2020-04-09 10:25:28 +08:00
545c235b24 修复游戏详情页因修复 bundle 过大而造成的页面重构闪退 2020-04-08 18:52:03 +08:00
53d3cb320b 提前 downloadService startForeground 操作避免部分设备初始化闪退 2020-04-08 18:50:09 +08:00
38682f01a8 升级 appcompat 依赖避免在5.1设备上webview闪退 2020-04-08 18:49:04 +08:00
13a76e8de7 Merge branch '3.7.5-bugfix' of gitlab.ghzhushou.com:halo/assistant-android into 3.7.5-bugfix 2020-04-08 12:39:57 +08:00
1e98fa98c3 增加应用内 webview 返回应用版本号的方法 2020-04-08 12:39:23 +08:00
20bc38add4 视频流播放错误重试一次 2020-04-02 15:00:07 +08:00
efabaafa38 20200402正式环境测试2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/817 2020-04-02 11:04:10 +08:00
26927661e7 修改视频流banner 2020-04-02 09:40:32 +08:00
15ba945751 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-04-01 16:44:31 +08:00
8e0527b777 尝试修复SyncPage快速添加/删除时数据无法同步问题 2020-04-01 16:44:21 +08:00
b9dfa0a8a9 视频流静音按钮增加防抖判断 2020-04-01 16:30:32 +08:00
c462973eb6 修复"问答-推荐精选"文章不能点赞问题 2020-04-01 15:29:21 +08:00
b8cefd69c0 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-04-01 11:56:04 +08:00
1c1537be8a 尝试修改滑动视频不播放问题 2020-04-01 11:55:57 +08:00
1dad632c70 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-04-01 11:49:24 +08:00
41600c7576 光环助手V3.7.5-前端测试问题汇总(0331)(1.4) https://gitlab.ghzs.com/pm/halo-app-issues/issues/817 2020-04-01 11:45:06 +08:00
5f0074c88d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-04-01 10:09:48 +08:00
907f2a2678 修改视频分享按钮动画 2020-04-01 10:09:28 +08:00
4a118bd51c 修复客服页面没授予权限选图片会闪退的问题 2020-04-01 10:08:21 +08:00
4919b46e5d Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-04-01 09:44:52 +08:00
034a6662f9 修复WebFragment JavascriptObject命名空间冲突问题 2020-04-01 09:44:38 +08:00
3fb1c9f315 视频流分享复制链接分享次数也+1 2020-03-31 17:14:42 +08:00
aed4610afd WebFragment分享文案改为Web端控制 2020-03-31 16:48:37 +08:00
345be8035a WebFragment分享文案改为Web端控制 2020-03-31 16:30:03 +08:00
68c7b0ddaf 正式环境改为3.7.5 2020-03-31 10:00:27 +08:00
f39ce00152 20200331测试:1 https://gitlab.ghzs.com/pm/halo-app-issues/issues/801 2020-03-31 09:51:48 +08:00
0b6d1bd6df Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-30 16:57:08 +08:00
dca7a44884 修复游戏详情由于Bundle的数据内容过大导致的闪退
引入TooLargeTool库(监控Bundle大小)
2020-03-30 16:56:47 +08:00
d90cdf341e 处理切换tab视频页面闪烁 2020-03-30 11:40:11 +08:00
7828189ea0 update LGLibrary version 2020-03-29 12:49:11 +08:00
e4cd8da65c 修复一下闪退问题 2020-03-29 12:36:39 +08:00
8cebbd3bbe Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-27 17:47:39 +08:00
63d9b354d4 update sync page 2020-03-27 17:47:26 +08:00
254944fbfc Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-27 16:56:57 +08:00
ec93080190 20200327测试1,2,4 https://gitlab.ghzs.com/pm/halo-app-issues/issues/801 2020-03-27 16:56:36 +08:00
ec638cb231 资讯文章详情播放视频增加MTA事件 2020-03-27 16:45:34 +08:00
7c72623f90 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-27 15:52:23 +08:00
2e58404e01 资讯文章详情播放视频由在Web页面改为在App视频详情播放 2020-03-27 15:52:10 +08:00
5eae896330 光环助手V3.7.5-视频详情UI优化2(2) https://gitlab.ghzs.com/pm/halo-app-issues/issues/801 2020-03-27 14:51:37 +08:00
6c2dcc7d37 回退视频流游戏名字颜色值 2020-03-27 11:54:33 +08:00
d40e4e97c1 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-27 11:48:03 +08:00
3164ed1b0e 修改SwitchButton样式 2020-03-27 11:47:48 +08:00
b49fae0384 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-27 11:43:47 +08:00
80544aff32 0326测试补充2(1),4,6 https://gitlab.ghzs.com/pm/halo-app-issues/issues/801 2020-03-27 11:43:25 +08:00
64235951c2 修复游戏详情回答点赞数量不准确问题 2020-03-27 10:40:33 +08:00
f08fe7d855 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-26 22:08:20 +08:00
ff1a9e8694 update sync page 2020-03-26 22:07:59 +08:00
2abf87628a Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-26 18:53:18 +08:00
e835482abd 0326测试补充1,3,5,8 https://gitlab.ghzs.com/pm/halo-app-issues/issues/801 2020-03-26 18:52:54 +08:00
e78882e911 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-26 18:33:50 +08:00
b021d99f78 RichEditor添加javascript提交Mta事件的接口 2020-03-26 18:33:33 +08:00
084781dc0a jenkins 打包脚本添加错误重试 2020-03-26 18:21:11 +08:00
ce83fed40d Merge branch '3.7.4-bugfix-again' into 'dev'
3.7.4 bugfix again

See merge request !12
2020-03-26 17:49:28 +08:00
24d16a234f Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-26 17:29:58 +08:00
536af50a4f 光环助手V3.7.5-视频功能优化(上传视频)0326测试:2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/808 2020-03-26 17:29:42 +08:00
9eccc459d9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-26 17:03:41 +08:00
6e8310e4c9 添加浏览器跳转视频流协议并对接活动视频接口 2020-03-26 17:03:20 +08:00
35e79f938c 微调资讯文章详情UI 2020-03-26 15:53:31 +08:00
10764ac3f4 RichEditor添加显示Dialog/获取数据/存储数据接口 2020-03-26 15:35:27 +08:00
2a6ecfa176 修改获取上传配置的链接参数 2020-03-25 16:31:31 +08:00
5b44c7f856 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-25 15:01:11 +08:00
1e5e36a8c7 社区文章/回答列表执行点赞/评论操作后即时刷新列表数据 2020-03-25 15:00:57 +08:00
92dda8e64c 修复应用外跳转只能跳一次的问题 https://gitlab.ghzs.com/pm/halo-app-issues/issues/812 2020-03-25 10:38:18 +08:00
27488e8084 Merge branch 'sync_page_data' 2020-03-24 16:49:39 +08:00
72871e55c6 数据同步模块基本完成 2020-03-24 15:28:19 +08:00
07c05b2191 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-24 11:33:24 +08:00
89d2fb98fa 修改问题列表的跳转规则 2020-03-24 11:33:09 +08:00
6d1719b877 处理闪退异常 2020-03-24 10:51:00 +08:00
51599d5bb4 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-24 10:46:28 +08:00
aedaee8d3a 光环助手V3.7.5-视频功能优化(上传视频)(2.5) https://gitlab.ghzs.com/pm/halo-app-issues/issues/808 2020-03-24 10:46:02 +08:00
c1c655fcb0 完成光环前端优化汇总(3月第3周)的1,2 https://gitlab.ghzs.com/pm/halo-app-issues/issues/812 2020-03-23 18:47:34 +08:00
fabcce9a6c 删除无用代码 2020-03-23 18:14:26 +08:00
16feb963f6 光环前端优化汇总(2020年3月第3周)(3.7.10.12) https://gitlab.ghzs.com/pm/halo-app-issues/issues/812 2020-03-23 18:12:22 +08:00
e7ae608986 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-23 13:12:21 +08:00
7ec4625d45 RichEditor添加视频库以支持在Web页面直接播放视频 2020-03-23 13:11:50 +08:00
135d717715 光环前端优化汇总(2020年3月第3周)5,6 https://gitlab.ghzs.com/pm/halo-app-issues/issues/812 2020-03-23 10:31:08 +08:00
77c3131a69 Merge branch '3.7.4-bugfix' into 'dev'
3.7.4 bugfix

See merge request !11
2020-03-20 16:35:34 +08:00
7e74cbfbd1 Merge branch 'dev' into '3.7.4-bugfix'
# Conflicts:
#   app/src/main/java/com/gh/gamecenter/help/HelpContentAdapter.kt
2020-03-20 16:35:20 +08:00
a2cd548d1e Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-20 15:56:23 +08:00
0a4d6122df 尝试解决exo内核播放完毕不回调问题 2020-03-20 15:56:17 +08:00
23d1435ed2 修复一些闪退问题 2020-03-20 15:31:28 +08:00
dd60900bcb Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-20 10:34:13 +08:00
0fbb0aa363 修改AppManager的activity出栈方式,以修复Activity销毁后会自动退出App的问题 2020-03-20 10:33:49 +08:00
23539b9316 视频详情徽章显示问题 2020-03-19 18:23:09 +08:00
a1460b07c6 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-19 17:45:03 +08:00
02b6c2733b 修复一些闪退问题 2020-03-19 17:44:47 +08:00
1d29d68aa2 解决进入首页视频流未选中的tab页面播放视频 2020-03-19 15:23:07 +08:00
aa76a20065 完成视频流广告 2020-03-19 10:43:56 +08:00
ec945919ba 广告banner添加indicator 2020-03-18 18:09:08 +08:00
e626e82945 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-18 17:26:31 +08:00
6e238379f2 播放界面UI优化 2020-03-18 17:26:26 +08:00
7a4ae83a2b 光环助手V3.7.5-视频功能优化(上传视频)(1) https://gitlab.ghzs.com/pm/halo-app-issues/issues/808 2020-03-18 17:00:21 +08:00
46827b1489 光环前端优化汇总(2020年3月第2周)(11) https://gitlab.ghzs.com/pm/halo-app-issues/issues/805 2020-03-18 15:56:29 +08:00
762897521b 光环助手V3.7.5-视频数据相关 https://gitlab.ghzs.com/pm/halo-app-issues/issues/809 2020-03-18 14:25:09 +08:00
b8d74357b5 显示版本号改为 3.7.5 2020-03-18 10:31:28 +08:00
21c116ea5b 完成前端优化汇总(3月第2周)的第4点 https://gitlab.ghzs.com/pm/halo-app-issues/issues/805 2020-03-18 10:30:49 +08:00
2cf23b9a32 对接最新Tab视频流接口 2020-03-17 17:24:27 +08:00
6b03098ac7 Merge branch 'upgrade_dependencies' into dev
# Conflicts:
#	dependencies.gradle
2020-03-17 09:55:41 +08:00
bcd846024e 视频流分享统计 2020-03-17 09:53:49 +08:00
d98edc8f77 光环前端优化汇总(2020年3月第2周)8 https://gitlab.ghzs.com/pm/halo-app-issues/issues/805 2020-03-17 09:20:47 +08:00
faef2a5e4d 使用帮助Web页面避免缩放 2020-03-16 18:18:01 +08:00
3d88792d11 视频流广告banner 2020-03-16 16:54:46 +08:00
f7fe7a5153 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev 2020-03-15 19:16:05 +08:00
9aeb1624a6 修改视频流详情UI(未完) 2020-03-15 19:15:42 +08:00
ec9c282618 Merge branch 'dev' of gitlab.ghzhushou.com:halo/assistant-android into dev 2020-03-13 16:59:04 +08:00
7e1da213d5 光环前端优化汇总(2020年3月第2周)(7.9.10)https://gitlab.ghzs.com/pm/halo-app-issues/issues/805 2020-03-13 16:58:47 +08:00
8d9fd482b9 视频流增加最新Tab 2020-03-13 16:28:47 +08:00
c87bf1e613 update 2020-03-12 14:19:45 +08:00
81dc17530f update 2020-03-11 17:56:10 +08:00
b53f769a0d update 2020-03-11 17:22:44 +08:00
aadd2071b9 update 2020-03-10 18:16:44 +08:00
fc7566d2c9 整理并更新版本依赖 2020-03-10 17:56:53 +08:00
7f082b7a36 update 2020-03-10 10:27:51 +08:00
bebda2de70 update 2020-03-05 15:59:56 +08:00
3e0887b5f9 Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into sync_page_data 2020-03-05 11:52:15 +08:00
a8894cc464 init sync page data 2020-03-02 17:04:30 +08:00
181 changed files with 3355 additions and 1189 deletions

View File

@ -23,6 +23,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
dexOptions {
// jumboMode = true
javaMaxHeapSize "4g"
@ -183,6 +187,7 @@ dependencies {
debugImplementation "com.facebook.stetho:stetho:${stetho}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stetho}"
debugImplementation "com.squareup.okhttp3:logging-interceptor:${okHttp}"
debugImplementation "com.gu.android:toolargetool:${toolargetool}"
implementation "androidx.core:core:${core}"
implementation "androidx.fragment:fragment:${fragment}"
@ -192,14 +197,18 @@ dependencies {
implementation "androidx.annotation:annotation:${annotation}"
implementation "androidx.constraintlayout:constraintlayout:${constraintLayout}"
implementation "androidx.recyclerview:recyclerview:${recyclerView}"
implementation "androidx.lifecycle:lifecycle-runtime:${lifeCycle}"
implementation "androidx.lifecycle:lifecycle-extensions:${lifeCycle}"
kapt "androidx.lifecycle:lifecycle-compiler:${lifeCycle}"
// implementation "androidx.lifecycle:lifecycle-runtime:${lifeCycle}"
// implementation "androidx.lifecycle:lifecycle-extensions:${lifeCycle}"
// kapt "androidx.lifecycle:lifecycle-compiler:${lifeCycle}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifeCycle"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifeCycle"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifeCycle"
implementation "androidx.room:room-runtime:${room}"
implementation "androidx.room:room-rxjava2:${room}"
implementation "androidx.core:core-ktx:${ktx}"
implementation "androidx.viewpager2:viewpager2:${viewpager2}"
kapt "androidx.room:room-compiler:${room}"
kapt "androidx.databinding:databinding-compiler:${databinding}"
// kapt "androidx.databinding:databinding-compiler:${databinding}"
implementation "com.google.android.material:material:${material}"
@ -241,13 +250,13 @@ dependencies {
// bugly with tinker support
implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
implementation 'com.google.android:flexbox:1.1.0'
implementation "com.google.android:flexbox:${flexbox}"
implementation "pub.devrel:easypermissions:${easypermissions}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.contrarywind:Android-PickerView:4.1.8'
implementation "com.contrarywind:Android-PickerView:${pickerView}"
implementation "com.scwang.smartrefresh:SmartRefreshLayout:${smartRefreshLayout}"
implementation "net.cachapa.expandablelayout:expandablelayout:${expandableLayout}"
@ -271,20 +280,20 @@ dependencies {
implementation "android.arch.work:work-runtime:${workManager}"
implementation "com.llew.huawei:verifier:1.0.6"
implementation "com.llew.huawei:verifier:${verifier}"
implementation "com.github.tbruyelle:rxpermissions:${rxPermissions}"
implementation 'com.ethanhua:skeleton:1.1.1'
implementation 'io.supercharge:shimmerlayout:2.1.0'
implementation "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.3.1"
implementation 'com.walkud.rom.checker:RomChecker:1.0.0'
implementation "com.ethanhua:skeleton:${skeleton}"
implementation "io.supercharge:shimmerlayout:${shimmerlayout}"
implementation "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:${mta}"
implementation "com.walkud.rom.checker:RomChecker:${romChecker}"
debugImplementation "com.github.nichbar.chucker:library:$chucker"
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.2'
implementation "com.aliyun.dpa:oss-android-sdk:${oss}"
implementation "com.airbnb.android:lottie:$lottie"

View File

@ -4,6 +4,7 @@ import android.app.Application;
import com.facebook.stetho.Stetho;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.gu.toolargetool.TooLargeTool;
import com.squareup.leakcanary.LeakCanary;
import okhttp3.OkHttpClient;
@ -29,7 +30,7 @@ public class Injection {
// init stetho
Stetho.initializeWithDefaults(application);
TooLargeTool.startLogging(application);
return true;
}

View File

@ -6,13 +6,16 @@
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">
<!-- <link rel="stylesheet" href="https://static-web.ghzs.com/website-static/lib/video-js.min.css">--> <!--在web页面播放视频-->
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body>
<body style="overflow-x: hidden; word-break: break-all;">
<div id="editor" contenteditable="false"></div>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="video.min.js"></script>
<!--<script src="https://static-web.ghzs.com/website-static/lib/video.min.js"></script>--> <!--在web页面播放视频-->
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -624,3 +624,18 @@ function customLinkgo(self) {
// console.log(datas)
window.OnLinkClickListener.onClick(datas)
}
// 在web页面播放视频
//RE.initArticleVideo = function(){
// initArticleVideo()
//}
function showNativeDialog(title, message, positive, negative, callback) {
var jsCallbackCode = "(" + function (v) {
window.onNativeDialogCallback(v);
delete window.onNativeDialogCallback;
}.toString() + ")";
window.onNativeDialogCallback = callback;
window.NativeCallBack.showDialog(title, message, positive, negative, jsCallbackCode);
}

View File

@ -65,7 +65,9 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
@Override
public void onActivityDestroyed(Activity activity) {
AppManager.getInstance().finishActivity(activity);
if (activity.isFinishing()) {
AppManager.getInstance().finishActivity(activity);
}
}
}

View File

@ -9,9 +9,20 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.OnListClickListener;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.constant.Constants;
import com.gh.common.syncpage.ISyncAdapterHandler;
import com.gh.common.syncpage.SyncDataEntity;
import com.gh.common.syncpage.SyncPageRepository;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.eventbus.EBMiPush;
import com.lightgame.OnTitleClickListener;
@ -23,18 +34,14 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import kotlin.Pair;
import static com.gh.common.util.EntranceUtils.KEY_ENTRANCE;
@ -141,6 +148,49 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
ButterKnife.bind(this, mCachedView);
initView(mCachedView);
if (addSyncPageObserver()) {
initSyncPageObserver();
}
}
private void initSyncPageObserver() {
SyncPageRepository.INSTANCE.getSyncPageLiveData().observe(this, syncDataEntities -> {
try {
Utils.log("SyncPageRepository initSyncPageObserver->" + syncDataEntities);
List<SyncDataEntity> readyRemoveList = new ArrayList<>();
if (syncDataEntities == null || syncDataEntities.isEmpty()) return;
RecyclerView.Adapter adapter = provideSyncAdapter();
if (!(adapter instanceof ISyncAdapterHandler)) return;
for (int i = 0; i < adapter.getItemCount(); i++) {
Pair<String, Object> syncKey = ((ISyncAdapterHandler) adapter).getSyncData(i);
if (syncKey == null) continue;
for (SyncDataEntity syncDataEntity : syncDataEntities) {
if (syncDataEntity.getSyncId().equals(syncKey.getFirst())) {
boolean isSuccess = SyncPageRepository.INSTANCE.handleSyncData(syncKey.getSecond(), syncDataEntity);
if (isSuccess) {
if (BuildConfig.DEBUG) {
Utils.log("SyncPageRepository notify position->" + i);
}
adapter.notifyItemChanged(i);
if (syncDataEntity.getRemove()) {
readyRemoveList.add(syncDataEntity);
}
}
}
}
}
mBaseHandler.postDelayed(() -> SyncPageRepository.removeSyncData(readyRemoveList), 2000);
} catch (Exception e) {
if (BuildConfig.DEBUG) {
throw e;
} else {
e.printStackTrace();
}
}
});
}
// 必须的有subscribe才能register
@ -183,11 +233,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
}
public void toast(String msg) {
try {
Utils.toast(getContext(), msg);
} catch (Exception ignore) {
}
Utils.toast(getContext(), msg);
}
public void toastLong(@StringRes int msg) {
@ -255,4 +301,12 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
return this;
}
@Nullable
protected RecyclerView.Adapter provideSyncAdapter() {
return null;
}
protected boolean addSyncPageObserver() {
return false;
}
}

View File

@ -12,10 +12,10 @@ abstract class BaseLazyFragment : NormalFragment() {
private var isViewCreated = false
private var isSupportVisible = false
protected var isSupportVisible = false
/**
* 用于分发可见时间的时候获取 fragment 是否隐藏
* 用于分发可见时间的时候获取 fragment 是否隐藏
*
* @return true fragment 不可见, false 父 fragment 可见
*/

View File

@ -6,9 +6,11 @@ import android.webkit.JavascriptInterface
import androidx.annotation.Keep
import com.gh.base.CurrentActivityHolder
import com.gh.common.util.*
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.LoginActivity
import com.gh.gamecenter.ViewImageActivity
import com.gh.gamecenter.entity.Badge
import com.gh.gamecenter.entity.MtaEvent
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
@ -76,6 +78,11 @@ class DefaultJsApi(var context: Context) {
return HaloApp.getInstance().channel
}
@JavascriptInterface
fun getAppVersion(msg: Any): String {
return BuildConfig.VERSION_NAME
}
@JavascriptInterface
fun bindWechat(msg: Any, handler: CompletionHandler<Any>) {
context.ifLogin("浏览器") {
@ -144,9 +151,6 @@ class DefaultJsApi(var context: Context) {
context?.startActivity(ViewImageActivity.getBase64ViewImageIntent(context, true))
}
@Keep
internal data class MtaEvent(var name: String = "", var key: String = "", var value: String = "")
@Keep
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)

View File

@ -8,6 +8,7 @@ import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.util.EntranceUtils.ENTRANCE_BROWSER
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.LibaoDetailActivity
import com.gh.gamecenter.NewsDetailActivity
@ -15,7 +16,9 @@ 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.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.lightgame.utils.Utils
import com.moor.imkf.requesturl.RequestUrl.type
object DefaultWebViewUrlHandler {
@ -124,8 +127,17 @@ object DefaultWebViewUrlHandler {
}
EntranceUtils.HOST_USERHOME -> {
val position = uri.getQueryParameter("position")
DirectUtils.directToHomeActivity(context, id, if(position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
DirectUtils.directToHomeActivity(context, id, if (position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
}
EntranceUtils.HOST_VIDEO_MORE -> {
val referer = uri.getQueryParameter("referer") ?: ""
val type = uri.getQueryParameter("type") ?: ""
val act = uri.getQueryParameter("act") ?: ""
val loaction = if (TextUtils.isEmpty(act)) id else VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value
DirectUtils.directToVideoDetail(context, id, loaction, false, "", entrance, "", referer, type, act)
}
else -> DialogUtils.showLowVersionDialog(context)
}
return true

View File

@ -0,0 +1,16 @@
package com.gh.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标记那些不需要检查的同步字段
*
* 同步字段冲突时使用
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SyncIgnore {
}

View File

@ -0,0 +1,12 @@
package com.gh.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SyncPage {
String[] syncNames();
}

View File

@ -5,8 +5,6 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
@ -25,6 +23,7 @@ import org.greenrobot.eventbus.EventBus;
import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

View File

@ -62,6 +62,8 @@ public class Constants {
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";
//首页视频最新tab提示
public static final String SP_HOME_NEW_VIDEO_TIPS = "home_new_video";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";

View File

@ -37,7 +37,7 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
titleTv.text = mNotificationHint?.title
contentContainer.removeAllViews()
for (item in mNotificationHint?.content!!) {
for (item in mNotificationHint?.content ?: arrayListOf()) {
val tv = TextView(context)
tv.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {

View File

@ -0,0 +1,12 @@
package com.gh.common.syncpage
interface ISyncAdapterHandler {
/**
* @param position position to query
* @return Pair first: item sync id
* Pair second: item data entity
*/
fun getSyncData(position: Int): Pair<String, Any>?
}

View File

@ -0,0 +1,43 @@
package com.gh.common.syncpage
import androidx.annotation.Keep
@Keep
data class SyncDataEntity(
/**
* 标识一条数据的唯一ID
*
* 与[ISyncAdapterHandler.getSyncData]返回的Pair first一致
*/
val syncId: String,
/**
* 需要同步的字段名
*
* 与@SyncPage注解的值一致
*/
val syncFieldName: String?,
/**
* 需要同步的具体内容
*/
val syncFieldValue: Any?,
/**
* 同步完一次是否自动删除
*/
val remove: Boolean = true,
/**
* 是否需要查询同步实体的父级字段
*
* 由于反射可能会导致较大的性能消耗,默认关闭,具体按实际情况开启
*/
val checkInherited: Boolean = false,
/**
* 是否需要查询同步实体的嵌套实体内容
*
* 由于反射可能会导致较大的性能消耗,默认关闭,具体按实际情况开启
*/
val checkFieldEntity: Boolean = false)

View File

@ -0,0 +1,17 @@
package com.gh.common.syncpage
object SyncFieldConstants {
// 是否点赞
const val ANSWER_VOTE = "ANSWER_VOTE"
const val ARTICLE_VOTE = "ARTICLE_VOTE"
// 赞同数量
const val ANSWER_VOTE_COUNT = "ANSWER_VOTE_COUNT"
const val ARTICLE_VOTE_COUNT = "ARTICLE_VOTE_COUNT"
// 评论数量
const val ANSWER_COMMENT_COUNT = "ANSWER_COMMENT_COUNT"
const val ARTICLE_COMMENT_COUNT = "ARTICLE_COMMENT_COUNT"
}

View File

@ -0,0 +1,154 @@
package com.gh.common.syncpage
import androidx.lifecycle.MutableLiveData
import com.gh.common.annotation.SyncIgnore
import com.gh.common.annotation.SyncPage
import com.gh.common.util.debugOnly
import com.gh.common.util.toJson
import com.gh.common.util.tryCatchInRelease
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import java.lang.reflect.Field
/**
* 页面之间实现数据同步(主要是单个字段的同步)
*
* 实现思路:
* 1.把需要同步的数据以一个特殊ID作为唯一标识并存于一个全局的仓库
* 2.利用LiveData进行页面回调,再通过[ISyncAdapterHandler.getSyncData]找到需要被同步的数据
* 3.最后利用反射进行数据替换,具体请见[SyncPageRepository.replaceSyncData]
*
* 具体的接入方式(以列表为例)
* 1.通过[SyncPageRepository.postSyncData]提交同步数据
* 2.在Fragment重写[BaseFragment.addSyncPageObserver]开启同步事件监听
* 3.在Fragment重写[BaseFragment.provideSyncAdapter]提供获取数据的来源
* - [BaseFragment.provideSyncAdapter]提供的Adapter必须实现[ISyncAdapterHandler]接口
*
*/
object SyncPageRepository {
// 只有在新增操作时,才需要进行页面刷新
val syncPageLiveData = MutableLiveData<List<SyncDataEntity>>()
val syncDataList = ArrayList<SyncDataEntity>()
// size: 防止删除刚刚添加的数据
@JvmStatic
fun clearSyncData() {
tryCatchInRelease {
synchronized(syncDataList) {
if (syncDataList.size > 0) {
debugOnly {
Utils.log("SyncPageRepository clearSyncData 存在" + syncDataList.size + "条数据尚未处理,即将删除")
}
syncDataList.clear()
}
}
}
}
@JvmStatic
fun removeSyncData(list: List<SyncDataEntity>) {
tryCatchInRelease {
synchronized(syncDataList) {
for (syncDataEntity in list) {
val remove = syncDataList.remove(syncDataEntity)
debugOnly {
Utils.log("SyncPageRepository removeSyncData ->" + syncDataEntity.syncId +
", fieldName->" + syncDataEntity.syncFieldName +
", remove->" + remove)
}
}
}
}
debugOnly {
Utils.log("SyncPageRepository removeSyncData ->" + syncDataList.size)
}
}
// 提交同步数据
fun postSyncData(entity: SyncDataEntity) {
tryCatchInRelease {
synchronized(syncDataList) {
// 检查是否存在重复操作
for (syncDataEntity in syncDataList) {
if (syncDataEntity.syncId == entity.syncId && syncDataEntity.syncFieldName == entity.syncFieldName) {
syncDataList.remove(syncDataEntity)
debugOnly {
Utils.log("SyncPageRepository postSyncData 存在重复操作->" + entity.toJson())
}
break
}
}
syncDataList.add(entity)
syncPageLiveData.postValue(syncDataList)
debugOnly {
Utils.log("SyncPageRepository postSyncData->" + entity.toJson())
}
}
}
}
fun handleSyncData(rawData: Any, syncData: SyncDataEntity): Boolean {
val fields = if (syncData.checkInherited) {
getAllFieldsList(rawData::class.java)
} else rawData::class.java.declaredFields.toList()
var isNeedNotify = false
for (field in fields) {
isNeedNotify = replaceSyncData(field, rawData, syncData)
if (isNeedNotify) break
}
if (!isNeedNotify) {
debugOnly {
Utils.log("SyncPageRepository sync failure-> " + syncData.syncFieldName)
}
}
return isNeedNotify
}
private fun replaceSyncData(field: Field, extractObject: Any, syncData: SyncDataEntity): Boolean {
field.getAnnotation(SyncPage::class.java)?.syncNames?.forEach { syncName ->
if (syncName == syncData.syncFieldName && field.getAnnotation(SyncIgnore::class.java) == null) {
field.isAccessible = true
debugOnly {
Utils.log("SyncPageRepository sync success-> " + syncData.syncFieldName + ", fieldName->" + field.name + ", fieldValue->" + field.get(extractObject))
}
field.set(extractObject, syncData.syncFieldValue)
return true
}
}
if (syncData.checkFieldEntity) {
// 递归查询
val pkgName = field.type.getPackage()?.name ?: return false
if (pkgName.contains(HaloApp.getInstance().application.packageName) && field.getAnnotation(SyncIgnore::class.java) == null) {
field.isAccessible = true
val extractEntityObject = field.get(extractObject) ?: return false
field.type.declaredFields.forEach {
if (replaceSyncData(it, extractEntityObject, syncData)) return true
}
}
}
return false
}
// 包括父类 Field 对象
private fun getAllFieldsList(cls: Class<*>?): List<Field> {
if (cls == null) return arrayListOf()
val allFields = arrayListOf<Field>()
var currentClass = cls
while (currentClass != null) {
val declaredFields = currentClass.declaredFields
allFields.addAll(declaredFields)
currentClass = currentClass.superclass
}
return allFields
}
}

View File

@ -0,0 +1,98 @@
package com.gh.common.syncpage.example
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
class ExampleAdapter(context: Context) : ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
override fun areItemsTheSame(oldItem: AnswerEntity?, newItem: AnswerEntity?): Boolean {
return oldItem?.id == newItem?.id
}
override fun getItemViewType(position: Int): Int {
if (position == itemCount - 1) return ItemViewType.ITEM_FOOTER
return ItemViewType.ITEM_BODY
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
return when (viewType) {
ItemViewType.ITEM_FOOTER -> {
view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
FooterViewHolder(view)
}
else -> {
view = mLayoutInflater.inflate(R.layout.community_answer_item, parent, false)
CommunityAnswerItemViewHolder(CommunityAnswerItemBinding.bind(view))
}
}
}
override fun getItemCount(): Int {
return if (mEntityList.isNotEmpty()) mEntityList.size + FOOTER_ITEM_COUNT else 0
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
ItemViewType.ITEM_BODY -> {
val answer = mEntityList[position]
if ("community_article" == answer.type) {
val questions = Questions()
questions.title = answer.articleTitle
answer.questions = questions
}
val answerViewHolder = holder as CommunityAnswerItemViewHolder
val binding = answerViewHolder.binding
answerViewHolder.bindAnswerItem(answer, "", getPath())
binding.title.setOnClickListener {
if ("community_article" == answer.type) {
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, UserManager.getInstance().community, answer.id!!, "", getPath()))
} else {
val questions = answer.questions
mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.id, "", getPath()))
}
}
answerViewHolder.itemView.setOnClickListener {
if ("community_article" == answer.type) {
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, UserManager.getInstance().community, answer.id!!, "", getPath()))
} else {
mContext.startActivity(AnswerDetailActivity.getIntent(mContext, answer.id, "", getPath()))
}
}
}
ItemViewType.ITEM_FOOTER -> {
val footerViewHolder = holder as FooterViewHolder
footerViewHolder.initItemPadding()
footerViewHolder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint)
}
}
}
override fun getSyncData(position: Int): Pair<String, AnswerEntity>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
fun getPath(): String {
return "问答-推荐-按时间"
}
}

View File

@ -0,0 +1,65 @@
package com.gh.common.syncpage.example
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.view.VerticalItemDecoration
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
class ExampleFragment : ListFragment<AnswerEntity, NormalListViewModel<AnswerEntity>>() {
private var mAdapter: ExampleAdapter? = null
override fun provideListAdapter(): ExampleAdapter {
if (mAdapter == null) {
mAdapter = ExampleAdapter(requireContext())
}
return mAdapter!!
}
override fun getItemDecoration(): RecyclerView.ItemDecoration {
return VerticalItemDecoration(context, 8F, false)
}
override fun provideDataObservable(page: Int): Observable<MutableList<AnswerEntity>> {
return RetrofitManager.getInstance(context).api.getCommunitiesRecommendNewest(UserManager.getInstance().community.id, page)
}
override fun provideListViewModel(): NormalListViewModel<AnswerEntity> {
val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this)
return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel<AnswerEntity>
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// SyncPageRepository.syncPageLiveData.observe(this, Observer {
// it ?: return@Observer
// val adapter = mListRv.adapter
// if (adapter !is ISyncAdapterHandler) return@Observer
// for(position in 0 until adapter.itemCount) {
// val syncKey = adapter.getSyncData(position)
// for (syncDataEntity in it) {
// if (syncDataEntity.syncId == syncKey?.first) {
// val isSuccess = SyncPageRepository.handleSyncData(syncKey.second, syncDataEntity)
// if (isSuccess) adapter.notifyItemChanged(position)
// }
// }
// }
// })
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mListRv.adapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -1237,6 +1237,7 @@ public class DialogUtils {
return context;
}
// currentActivity 是否存在 isDestroyed 的情况?
return AppManager.getInstance().currentActivity();
}

View File

@ -528,7 +528,7 @@ object DirectUtils {
* @param fromLocation 可见 [VideoDetailContainerViewModel.Location]
*/
@JvmStatic
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null, path: String? = "", referer: String = "") {
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null, path: String? = "", referer: String = "", type: String = "", act: String = "") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
@ -539,12 +539,19 @@ object DirectUtils {
bundle.putString(KEY_LOCATION, fromLocation)
bundle.putBoolean(KEY_SHOW_COMMENT, showComment)
bundle.putString(KEY_REFERER, referer)
bundle.putString(KEY_TYPE, type)
bundle.putString(KEY_ACTIVITY_NAME, act)
jumpActivity(context, bundle)
} else {
DialogUtils.showLowSystemVersionDialog(context)
}
}
@JvmStatic
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null, path: String? = "", referer: String = "") {
directToVideoDetail(context, videoId, fromLocation, showComment, gameId, entrance, path, referer, "", "")
}
/**
* 跳转至安利墙
* @param fixedTopAmwayCommentId 需要置顶的安利Id

View File

@ -85,7 +85,10 @@ object DownloadObserver {
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))
tryWithDefaultCatch {
// 会有 ActivityNotFoundException 异常catch 掉不管了
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path, true))
}
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
} else {
statDoneEvent(downloadEntity)
@ -111,7 +114,9 @@ object DownloadObserver {
} else {
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
tryWithDefaultCatch {
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
}
} else {
// 弹出卸载提示框
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))

View File

@ -147,8 +147,11 @@ public class EntranceUtils {
public static final String KEY_IS_HOME_VIDEO = "isHomeVideo";
public static final String KEY_IS_HOME = "isHome";
public static final String KEY_WEB_SHARE = "webShare";
public static final String KEY_ACTIVITY_NAME = "activityName";//活动名称
public static final String KEY_REQUIRE_REDIRECT = "require_redirect"; // 标记需要再跳转
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
//TODO 把其他类似的跳转启动逻辑也处理掉
if (RunningUtils.isRunning(context)
@ -173,6 +176,7 @@ public class EntranceUtils {
public static void jumpActivity(Context context, Bundle nextToBundle, Bundle bundle, Callback callback) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
//TODO 把其他类似的跳转启动逻辑也处理掉
if (RunningUtils.isRunning(context)

View File

@ -8,6 +8,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
@ -170,6 +171,9 @@ public class PackageUtils {
public static boolean compareSignatureBetweenInstalledAppWithApk(Context context, String packageName, String apkFilePath) {
try {
Signature sig = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
// Fuck HUAWEI, 华为系统调用 getPackageArchiveInfo 获取魔羯 apk 的签名时会耗时超过5秒造成 ANR没有找到解决方法
// 如果可以的话尽量避免调用 getPackageArchiveInfo 方法
Signature releaseSig = context.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES).signatures[0];
return sig.hashCode() == releaseSig.hashCode();
} catch (Exception e) {
@ -217,8 +221,9 @@ public class PackageUtils {
}
}
/*
* 根据apk路径获取apk包名、签名 根据包名 判断 是否已安装游戏 根据签名 判断 是否一致
/**
* 根据 path 获取 apk 信息确定处理方式
* @return true 为直接唤起系统 PackageInstaller, false 为需要插件化
*/
public static boolean isCanLaunchSetup(Context context, String path) {
String packageName = getPackageNameByPath(context, path);
@ -236,13 +241,13 @@ public class PackageUtils {
return true;
}
// 由于新增了非插件的也能更新的功能,倘若两个签名一样的话就不走下面的光环签名判断了
if (compareSignatureBetweenInstalledAppWithApk(context, packageName, path)) {
// 判断当前已安装应用是否为光环签名
if (publicKey.equals(getApkSignatureByPackageName(context, packageName))) {
return true;
}
String signature = getApkSignatureByPackageName(context, packageName);
return publicKey.equals(signature);
// 若已安装的应用的签名与即将要安装的签名一致也返回 true
return compareSignatureBetweenInstalledAppWithApk(context, packageName, path);
}
/*

View File

@ -18,7 +18,6 @@ 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;
@ -32,6 +31,7 @@ import com.facebook.imagepipeline.image.CloseableImage;
import com.gh.common.constant.Config;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WeiBoShareActivity;
import com.gh.gamecenter.eventbus.EBShare;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.WbSdk;
import com.sina.weibo.sdk.auth.AuthInfo;
@ -46,6 +46,8 @@ import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import org.greenrobot.eventbus.EventBus;
import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@ -53,7 +55,6 @@ import java.util.List;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.jvm.functions.Function0;
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
@ -99,6 +100,7 @@ public class ShareUtils {
private PopupWindow popupWindow;
private ShareType mShareType;
public static ShareType shareType;//全局保存shareType分享成功后判断分享的类型
private WeakReference<Activity> mActivity;
@ -108,6 +110,7 @@ public class ShareUtils {
@Override
public void onComplete(Object o) {
Utils.toast(mContext, R.string.share_success_hint);
EventBus.getDefault().post(new EBShare(ShareUtils.shareType));
}
@Override
@ -150,7 +153,7 @@ public class ShareUtils {
return false;
}
public void showShareWindowsCancelCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType, Function0 function) {
public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType, ShareCallBack callBack) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
@ -158,6 +161,7 @@ public class ShareUtils {
this.mSummary = shareSummary;
this.mTitle = shareTitle;
this.mShareType = shareType;
ShareUtils.shareType = mShareType;
View contentView = View.inflate(activity, R.layout.share_popup_layout, null);
contentView.setFocusable(true);
@ -178,8 +182,12 @@ public class ShareUtils {
ShareRecyclerViewAdapter shareRecyclerViewAdapter = new ShareRecyclerViewAdapter();
shareRecyclerView.setAdapter(shareRecyclerViewAdapter);
shareRecyclerViewAdapter.setOnItemClickListener(position -> {
if ("取消".equals(arrLabel[position])) {
function.invoke();
if (callBack != null) {
if (position == arrLabel.length - 1) {
callBack.onCancel();
} else {
callBack.onSuccess(arrLabel[position]);
}
}
});
@ -221,7 +229,9 @@ public class ShareUtils {
&& event.getRepeatCount() == 0
&& popupWindow != null
&& popupWindow.isShowing()) {
function.invoke();
if (callBack != null) {
callBack.onCancel();
}
popupWindow.dismiss();
}
return false;
@ -230,74 +240,7 @@ public class ShareUtils {
public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType) {
if (activity.isFinishing()) return;
this.mActivity = new WeakReference<>(activity);
this.shareIcon = icon;
this.shareUrl = url;
this.mSummary = shareSummary;
this.mTitle = shareTitle;
this.mShareType = shareType;
View contentView = View.inflate(activity, R.layout.share_popup_layout, null);
contentView.setFocusable(true);
contentView.setFocusableInTouchMode(true);
RecyclerView shareRecyclerView = contentView.findViewById(R.id.share_rv);
shareRecyclerView.setPadding(DisplayUtils.dip2px(mContext, 20), DisplayUtils.dip2px(mContext, 10), DisplayUtils.dip2px(mContext, 20), 0);
//RecyclerView禁止滑动
GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 4) {
@Override
public boolean canScrollVertically() {
return false;
}
};
shareRecyclerView.setLayoutManager(gridLayoutManager);
shareRecyclerView.setAdapter(new ShareRecyclerViewAdapter());
if (mShareType == ShareType.shareGh) {
RelativeLayout layout = (RelativeLayout) view;
layout.addView(contentView);
arrLabel[6] = "邮件";
arrLogo[6] = R.drawable.share_email_logo;
arrLabel[7] = "复制链接";
arrLogo[7] = R.drawable.share_copyfont_logo;
return;
} else {
arrLabel[6] = "复制链接";
arrLogo[6] = R.drawable.share_copyfont_logo;
arrLabel[7] = "取消";
arrLogo[7] = R.drawable.share_cancel_logo;
}
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.NO_GRAVITY, 0, bottomLocation);
} catch (Exception e) {
e.printStackTrace();
}
contentView.setOnClickListener(v -> popupWindow.dismiss());
contentView.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0
&& popupWindow != null
&& popupWindow.isShowing()) {
popupWindow.dismiss();
}
return false;
});
showShareWindowsCallback(activity, view, url, icon, shareTitle, shareSummary, shareType, null);
}
//QQ分享
@ -707,4 +650,10 @@ public class ShareUtils {
void onItemClick(int position);
}
public interface ShareCallBack {
void onSuccess(String label);
void onCancel();
}
}

View File

@ -0,0 +1,216 @@
package com.gh.common.view
import android.content.Context
import android.util.AttributeSet
import android.view.*
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.gh.common.util.DisplayUtils
import com.gh.common.util.ImageUtils
import com.gh.common.util.rxTimer
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SettingsEntity
import io.reactivex.disposables.Disposable
import kotlin.math.abs
/**
* 视频流广告轮播控件
*/
class AdBannerView : LinearLayout {
private lateinit var mViewPager2: ViewPager2
private var mDatas = ArrayList<SettingsEntity.Advertisement>()
var isAutoPlay = true
private var currentPage = 0
private var autoDurationTime = 6000L
private var mRxTimer: Disposable? = null
private var lastX: Float = 0F
private var lastY: Float = 0F
private var startX: Float = 0F
private var startY: Float = 0F
private val mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
private val bannerWidth = DisplayUtils.dip2px(52f)
var onItemClick: ((position: Int) -> Unit)? = null
private lateinit var mIndicatorLayout: LinearLayout
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
initViews()
}
private fun initViews() {
orientation = VERTICAL
mViewPager2 = ViewPager2(context).apply {
layoutParams = ViewGroup.LayoutParams(bannerWidth, bannerWidth)
orientation = ViewPager2.ORIENTATION_HORIZONTAL
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
currentPage = position
slideIndicator(currentPage % mDatas.size)
}
})
}
val recyclerView = mViewPager2.getChildAt(0) as RecyclerView
recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_NEVER
addView(mViewPager2)
mIndicatorLayout = LinearLayout(context).apply {
orientation = HORIZONTAL
gravity = Gravity.CENTER
val params = LayoutParams(LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(5F))
params.topMargin = DisplayUtils.dip2px(8f)
layoutParams = params
visibility = View.GONE
}
addView(mIndicatorLayout)
}
fun start(datas: ArrayList<SettingsEntity.Advertisement>) {
if (datas.isNullOrEmpty()) throw IllegalArgumentException("广告列表不能为空")
val adapter = mViewPager2.adapter
mDatas = datas
if (adapter == null) {
val bannerAdapter = AdBannerAdapter()
mViewPager2.adapter = bannerAdapter
} else {
adapter.notifyDataSetChanged()
}
currentPage = (mViewPager2.adapter as AdBannerAdapter).getActualFirstPositionInCenter()
mViewPager2.setCurrentItem(currentPage, false)
if (mDatas.size > 1) {
addIndicator()
slideIndicator(currentPage % mDatas.size)
autoPlay()
}
}
private fun autoPlay() {
if (isAutoPlay && mDatas.size > 1) {
if (mRxTimer != null && !mRxTimer!!.isDisposed) {
mRxTimer?.dispose()
mRxTimer = null
}
mRxTimer = rxTimer(autoDurationTime) {
slidePage()
}
}
}
private fun slidePage() {
currentPage++
mViewPager2.setCurrentItem(currentPage, true)
}
fun resumePage() {
autoPlay()
}
fun pausePage() {
if (mRxTimer != null && !mRxTimer!!.isDisposed) {
mRxTimer?.dispose()
mRxTimer = null
}
}
private fun addIndicator() {
mIndicatorLayout.removeAllViews()
mDatas.forEach { _ ->
val view = View(context).apply {
background = ContextCompat.getDrawable(context, R.drawable.selector_video_detail_ad_indicator)
val params = LayoutParams(DisplayUtils.dip2px(4F), DisplayUtils.dip2px(4F))
params.leftMargin = DisplayUtils.dip2px(2F)
params.rightMargin = DisplayUtils.dip2px(2F)
layoutParams = params
}
mIndicatorLayout.addView(view)
}
}
private fun slideIndicator(position: Int) {
for (i in 0 until mIndicatorLayout.childCount) {
val childAt = mIndicatorLayout.getChildAt(i)
childAt.isSelected = i == position
}
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
val action = ev.action
if (action == MotionEvent.ACTION_DOWN) {
lastX = ev.rawX
startX = lastX
lastY = ev.rawY
startY = lastY
} else if (action == MotionEvent.ACTION_MOVE) {
lastX = ev.rawX
lastY = ev.rawY
val distanceX = abs(lastX - startX)
val distanceY = abs(lastY - startY)
val disallowIntercept: Boolean
disallowIntercept = if (mViewPager2.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
distanceX > mTouchSlop && distanceX > distanceY
} else {
distanceY > mTouchSlop && distanceY > distanceX
}
parent.requestDisallowInterceptTouchEvent(disallowIntercept)
} else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
return abs(lastX - startX) > mTouchSlop || abs(lastY - startY) > mTouchSlop
}
return super.onInterceptTouchEvent(ev)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
if (mRxTimer != null && !mRxTimer!!.isDisposed) {
mRxTimer?.dispose()
mRxTimer = null
}
}
fun getAdDatas(): ArrayList<SettingsEntity.Advertisement> {
return mDatas
}
private inner class AdBannerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return object : RecyclerView.ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_ad_banner, parent, false)) {}
}
override fun getItemCount(): Int = if (mDatas.size == 1) mDatas.size else Int.MAX_VALUE
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val ad = mDatas[position % mDatas.size]
val view = holder.itemView as SimpleDraweeView
ImageUtils.addLimitWidthAndLoad(view, ad.image, bannerWidth, object : ImageUtils.OnImageloadListener {
override fun onLoadFinal(imageInfo: ImageInfo?) {
if (mIndicatorLayout.visibility == View.GONE) {
mIndicatorLayout.visibility = View.VISIBLE
}
}
})
holder.itemView.setOnClickListener {
onItemClick?.invoke(position % mDatas.size)
}
}
fun getActualFirstPositionInCenter(): Int {
if (mDatas.size == 1) return 0
var index = itemCount / 2
if (index % mDatas.size != 0) {
index -= (index % mDatas.size)
}
return index - 1
}
}
}

View File

@ -14,17 +14,24 @@ import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.gh.common.DefaultJsApi;
import com.gh.common.constant.Config;
import com.gh.common.util.DeviceUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.HtmlUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MtaHelper;
import com.gh.common.util.NetworkUtils;
import com.gh.common.util.RichEditorUtils;
import com.gh.common.util.SPUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.entity.MtaEvent;
import com.gh.gamecenter.entity.MyVideoEntity;
import com.gh.gamecenter.qa.entity.EditorInsertEntity;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
import org.json.JSONObject;
@ -509,6 +516,10 @@ public class RichEditor extends WebView {
return HtmlUtils.stripHtml(mContents);
}
// 在web页面播放视频
// public void initArticleVideo() {
// exec("javascript:RE.initArticleVideo();");
// }
private String convertHexColorString(int color) {
return String.format("#%06X", (0xFFFFFF & color));
@ -615,5 +626,98 @@ public class RichEditor extends WebView {
public boolean isInputEnabled() {
return mInputEnabled;
}
/**
* 获取网络状态
*
* @return "WIFI", "2G", "3G", "4G","无网络","未知"
*/
@JavascriptInterface
public String getNetworkStatus() {
return DeviceUtils.getNetwork(HaloApp.getInstance().getApplication());
}
/**
* 显示toast
*
* @param text toast 内容
*/
@JavascriptInterface
public void toast(String text) {
Utils.toast(HaloApp.getInstance().getApplication(), text);
}
/**
* 显示Dialog弹窗
*
* @param title 标题
* @param message 内容
* @param positive 确认按钮文本
* @param negative 取消按钮文本
*/
@JavascriptInterface
public void showDialog(String title, String message, String positive, String negative, String jsCallbackCode) {
DialogUtils.showAlertDialog(getContext(), title, message, positive, negative,
() -> post(() -> loadUrl("javascript:" + jsCallbackCode + "(" + true + ")")),
() -> post(() -> loadUrl("javascript:" + jsCallbackCode + "(" + false + ")")));
}
/**
* Javascript向App存储数据
*
* @param isPermanent true永久存储 false临时存储于内存中(注意:数据是不互通的)
*/
@JavascriptInterface
public void setDataToNative(String key, String value, boolean isPermanent) {
key += "-RichEditor";
if (!TextUtils.isEmpty(key)) {
if (isPermanent) {
if (value == null) {
SPUtils.remove(key);
} else {
SPUtils.setString(key, value);
}
} else {
if (value == null) {
HaloApp.remove(key);
} else {
HaloApp.put(key, value);
}
}
}
}
/**
* Javascript向App获取数据
*
* @param isPermanent 获取永久数据还是临时数据(注意:数据是不互通的)
*/
@JavascriptInterface
public String getDataFromNative(String key, boolean isPermanent) {
key += "-RichEditor";
if (!TextUtils.isEmpty(key)) {
if (isPermanent) {
return SPUtils.getString(key);
} else {
Object object = HaloApp.get(key, false);
if (object != null) return object.toString();
}
}
return "";
}
@JavascriptInterface
public void logMtaEvent(String event) {
try {
MtaEvent mtaEvent = GsonUtils.fromJson(event, MtaEvent.class);
MtaHelper.onEvent(mtaEvent.getName(), mtaEvent.getKey(), mtaEvent.getValue());
} catch (Exception e) {
if (BuildConfig.DEBUG) {
throw e;
} else {
e.printStackTrace();
}
}
}
}
}

View File

@ -0,0 +1,24 @@
package com.gh.common.view.vertical_recycler
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.recyclerview.widget.RecyclerView
/**
* 列表在滑动过程中拦截事件
*/
class CustomRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :RecyclerView(context, attrs) {
override fun onInterceptTouchEvent(e: MotionEvent?): Boolean {
if(isScrolling()){
return true
}
return super.onInterceptTouchEvent(e)
}
private fun isScrolling():Boolean{
return scrollState != SCROLL_STATE_IDLE
}
}

View File

@ -179,6 +179,10 @@ public class PagerLayoutManager extends LinearLayoutManager {
return super.scrollHorizontallyBy(dx, recycler, state);
}
public boolean isSlideDown() {
return mDrift >= 0;
}
/**
* 设置监听
*

View File

@ -8,8 +8,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
@ -30,10 +28,8 @@ 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;
import com.gh.common.exposure.meta.MetaUtil;
import com.gh.common.im.ImManager;
import com.gh.common.repository.ReservationRepository;
@ -41,14 +37,12 @@ import com.gh.common.util.ActivationHelper;
import com.gh.common.util.ClassUtils;
import com.gh.common.util.ConcernUtils;
import com.gh.common.util.DataCollectionUtils;
import com.gh.common.util.DataLogUtils;
import com.gh.common.util.DataUtils;
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;
import com.gh.common.util.LunchType;
@ -59,23 +53,17 @@ import com.gh.common.util.PlatformUtils;
import com.gh.common.util.PushHelper;
import com.gh.common.util.SPUtils;
import com.gh.common.util.ShareUtils;
import com.gh.common.util.StringUtils;
import com.gh.common.util.ThirdPartyPackageHelper;
import com.gh.common.util.UrlFilterUtils;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.download.DownloadFragment;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.GameDigestEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
import com.gh.gamecenter.entity.NotificationHint;
import com.gh.gamecenter.entity.NotificationUgc;
import com.gh.gamecenter.entity.SimpleGameEntity;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBShowDialog;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import com.gh.gamecenter.manager.DataCollectionManager;
@ -85,33 +73,26 @@ import com.gh.gamecenter.normal.NormalFragment;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.gamecenter.packagehelper.PackageViewModel;
import com.gh.gamecenter.qa.CommunityFragment;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.EmptyResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
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;
import com.halo.assistant.fragment.SettingsFragment;
import com.lightgame.config.CommonDebug;
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 com.shuyu.gsyvideoplayer.utils.StorageUtils;
import com.tencent.bugly.beta.tinker.TinkerManager;
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;
@ -129,19 +110,16 @@ import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
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;
@ -173,9 +151,7 @@ public class MainActivity extends BaseActivity {
// 黄壮华 按连续按返回键两次才退出应用
private long[] mHits = new long[2];
private boolean isSkipped = false;
public static boolean isNewFirstLaunch;
public String uuid = UUID.randomUUID().toString();
private Handler handler = new Handler();
@ -186,10 +162,6 @@ public class MainActivity extends BaseActivity {
mSp = PreferenceManager.getDefaultSharedPreferences(this);
if (savedInstanceState != null) {
isSkipped = savedInstanceState.getBoolean(IS_SKIPPED);
}
mMainWrapperFragment = new MainWrapperFragment();
if (savedInstanceState != null) {
mMainWrapperFragment.setArguments(savedInstanceState);
@ -229,7 +201,6 @@ public class MainActivity extends BaseActivity {
DialogUtils.showWarningDialog(this, "发生闪退", "光环助手刚刚发生了闪退,马上反馈以帮助我们更好地修复问题?(只需简单描述你刚才的操作)"
, "暂不", "马上反馈",
() -> {
// SuggestionActivity.startSuggestionActivity(MainActivity.this, SuggestType.crash, "APP闪退");
startActivityForResult(SuggestionActivity.getIntent(MainActivity.this, SuggestType.crash, "APP闪退"), 100);
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
@ -262,7 +233,9 @@ public class MainActivity extends BaseActivity {
}
// 跳转至其它页面
if (getIntent() != null && getIntent().getExtras() != null && !isSkipped) {
if (getIntent() != null
&& getIntent().getExtras() != null
&& getIntent().getBooleanExtra(EntranceUtils.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
}
@ -366,8 +339,10 @@ public class MainActivity extends BaseActivity {
}
private void doSkip() {
if (getIntent() != null && getIntent().getExtras() != null) {
getIntent().getExtras().putBoolean(EntranceUtils.KEY_REQUIRE_REDIRECT, false);
}
handler.postDelayed(() -> {
isSkipped = true;
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String to = bundle.getString(KEY_TO);
@ -505,7 +480,6 @@ public class MainActivity extends BaseActivity {
@Override
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());
@ -521,6 +495,13 @@ public class MainActivity extends BaseActivity {
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 跳转至其它页面
if (getIntent() != null
&& getIntent().getExtras() != null
&& getIntent().getBooleanExtra(EntranceUtils.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
}
// 跳转到问答社区并刷新
if (getIntent().getBooleanExtra(SWITCH_TO_COMMUNITY, false)) {
switchToCommunityTabAndRefresh();

View File

@ -181,8 +181,10 @@ public class SkipActivity extends BaseActivity {
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
break;
case HOST_VIDEO_MORE:
DirectUtils.directToVideoDetail(this, path, path,
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer);
String act = uri.getQueryParameter("act");
String loaction = TextUtils.isEmpty(act) ? path : VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.getValue();
DirectUtils.directToVideoDetail(this, path, loaction,
false, "", ENTRANCE_BROWSER, "浏览器", TextUtils.isEmpty(referer) ? "" : referer, type, act);
break;
case HOST_VIDEO_STREAMING_HOME:
// 把切换放到 MainActivity 处理

View File

@ -182,6 +182,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
private int mFunctionType = -1;
private String mCollectCancelPkgName = "";
@NonNull
public static Intent getIntent(Context context, SuggestType suggestType) {
Intent intent = new Intent(context, SuggestionActivity.class);
@ -714,6 +716,10 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
back.setOnClickListener(v -> {
MtaHelper.onEvent("意见反馈", "意见反馈-游戏收录弹窗", "点击返回");
dialog.dismiss();
if (mSelectGameEntity != null) {
mCollectCancelPkgName = mSelectGameEntity.getPackageName();
}
});
forcePost.setOnClickListener(v -> {
MtaHelper.onEvent("意见反馈", "意见反馈-游戏收录弹窗", "点击不是我要的游戏,继续提交");
@ -1023,6 +1029,10 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
@Override
protected boolean handleBackPressed() {
if (mSelectGameEntity != null && mCollectCancelPkgName.equals(mSelectGameEntity.getPackageName())) {
return super.handleBackPressed();
}
if (!TextUtils.isEmpty(mSuggestContentEt.getText().toString()) ||
!TextUtils.isEmpty(mSuggestGameName.getText().toString()) ||
!TextUtils.isEmpty(mLinkEt.getText().toString()) ||

View File

@ -13,6 +13,7 @@ import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.ShareUtils;
import com.gh.gamecenter.eventbus.EBShare;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.api.ImageObject;
import com.sina.weibo.sdk.api.TextObject;
@ -24,6 +25,8 @@ import com.sina.weibo.sdk.utils.Utility;
import androidx.annotation.NonNull;
import org.greenrobot.eventbus.EventBus;
/**
* Created by khy on 2016/11/23.
* <p>
@ -149,6 +152,7 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
@Override
public void onWbShareSuccess() {
Utils.toast(this, R.string.share_success_hint);
EventBus.getDefault().post(new EBShare(ShareUtils.shareType));
finish();
}

View File

@ -209,6 +209,7 @@ class AmwayAdapter(context: Context, private var mViewModel: AmwayViewModel, pri
if (amway.comment.me.isVoted) {
binding.likeIv.setImageResource(R.drawable.ic_amway_liked)
binding.likeCountTv.setTextColor(R.color.theme_font.toColor())
binding.likeCountTv.setOnClickListener { binding.likeIv.performClick() }
binding.likeIv.setOnClickListener {
debounceActionWithInterval(binding.likeIv.id, 1000L) {
@ -220,6 +221,7 @@ class AmwayAdapter(context: Context, private var mViewModel: AmwayViewModel, pri
}
} else {
binding.likeIv.setImageResource(R.drawable.ic_amway_like)
binding.likeCountTv.setTextColor(R.color.text_B3B3B3.toColor())
binding.likeCountTv.setOnClickListener { binding.likeIv.performClick() }
binding.likeIv.setOnClickListener {
debounceActionWithInterval(binding.likeIv.id, 1000L) {

View File

@ -3,12 +3,14 @@ package com.gh.gamecenter.collection;
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.Pair;
import android.view.View;
import android.view.ViewGroup;
import com.gh.base.OnListClickListener;
import com.gh.common.constant.ItemViewType;
import com.gh.common.syncpage.ISyncAdapterHandler;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.R;
@ -24,11 +26,13 @@ import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
import com.lightgame.utils.Utils;
import org.jetbrains.annotations.Nullable;
/**
* Created by khy on 22/12/17.
*/
public class AnswerAdapter extends ListAdapter<AnswerEntity> {
public class AnswerAdapter extends ListAdapter<AnswerEntity> implements ISyncAdapterHandler {
private OnListClickListener mListClickListener;
@ -138,4 +142,12 @@ public class AnswerAdapter extends ListAdapter<AnswerEntity> {
public int getItemCount() {
return mEntityList == null || mEntityList.isEmpty() ? 0 : mEntityList.size() + FOOTER_ITEM_COUNT;
}
@Nullable
@Override
public Pair<String, Object> getSyncData(int position) {
if (position >= mEntityList.size()) return null;
AnswerEntity entity = mEntityList.get(position);
return new Pair(entity.getId(), entity);
}
}

View File

@ -2,24 +2,20 @@ package com.gh.gamecenter.collection;
import android.view.View;
import com.gh.common.history.HistoryDatabase;
import com.gh.common.util.CollectionUtils;
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.eventbus.EBCollectionChanged;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.Single;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by khy on 22/12/17.
@ -41,14 +37,14 @@ public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel>
return mAdapter == null ? mAdapter = new AnswerAdapter(getContext(), mListViewModel, mType, this, mEntrance) : mAdapter;
}
@Override
/*@Override
public Single<List<AnswerEntity>> provideDataSingle(int page) {
if (mType == Type.COLLECTION) {
return Single.fromObservable(RetrofitManager.getInstance(getContext()).getApi().getCollectionAnswer(UserManager.getInstance().getUserId(), page));
} else {
return HistoryDatabase.Companion.getInstance().answerDao().getAnswersWithOffset(20, (page - 1) * 20);
}
}
}*/
@Override
protected AnswerViewModel provideListViewModel() {
@ -85,4 +81,15 @@ public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel>
HISTORY
}
@Override
protected boolean addSyncPageObserver() {
return true;
}
@Nullable
@Override
protected RecyclerView.Adapter provideSyncAdapter() {
return mAdapter;
}
}

View File

@ -28,7 +28,12 @@ class AnswerViewModel(application: Application) : ListViewModel<AnswerEntity, An
return if (type == AnswerFragment.Type.COLLECTION) {
Single.fromObservable(mApi.getCollectionAnswer(UserManager.getInstance().userId, page))
} else {
HistoryDatabase.instance.answerDao().getAnswersWithOffset(20, (page - 1) * 20)
if (page > 5) {
Single.create { it.onSuccess(arrayListOf()) }
} else {
HistoryDatabase.instance.answerDao().getAnswersWithOffset(20, (page - 1) * 20)
}
}
}

View File

@ -1,8 +1,6 @@
package com.gh.gamecenter.collection;
import android.app.Application;
import androidx.lifecycle.LiveData;
import androidx.annotation.NonNull;
import com.gh.common.history.HistoryDatabase;
import com.gh.gamecenter.baselist.ListViewModel;
@ -12,8 +10,11 @@ import com.gh.gamecenter.info.NewsViewsRepository;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.retrofit.RetrofitManager;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import io.reactivex.Observable;
import io.reactivex.Single;
@ -74,6 +75,9 @@ public class ArticleViewModel extends ListViewModel<NewsEntity, NewsEntity> {
if (type == ArticleFragment.Type.COLLECTION) {
return Single.fromObservable(RetrofitManager.getInstance(getApplication()).getApi().getCollectionArticle(UserManager.getInstance().getUserId(), page));
} else {
if (page > 5) {
return Single.create(emitter -> emitter.onSuccess(new ArrayList<>()));
}
return HistoryDatabase.Companion.getInstance().newsDao().getNewsWithOffset(20, (page - 1) * 20);
}
}

View File

@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
@ -12,12 +13,13 @@ import com.gh.gamecenter.baselist.ListAdapter
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.AnswerEntity
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) {
private val mEntrance: String) : ListAdapter<ArticleEntity>(context), ISyncAdapterHandler {
override fun areItemsTheSame(oldItem: ArticleEntity?, newItem: ArticleEntity?): Boolean {
return oldItem?.id == newItem?.id
@ -71,4 +73,10 @@ class CommunityArticleAdapter(context: Context,
holder.initFooterViewHolder(mViewModel, mIsLoading, isNetworkError, mIsOver)
}
}
override fun getSyncData(position: Int): Pair<String, ArticleEntity>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id, entity)
}
}

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.collection
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.CollectionUtils
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.baselist.LoadType
@ -16,7 +17,7 @@ class CommunityArticleFragment : ListFragment<ArticleEntity, CommunityArticleVie
override fun provideListAdapter(): CommunityArticleAdapter {
if (mAdapter == null) {
mAdapter = CommunityArticleAdapter(context!!,mType, mListViewModel, mEntrance)
mAdapter = CommunityArticleAdapter(requireContext(), mType, mListViewModel, mEntrance)
}
return mAdapter!!
}
@ -34,6 +35,14 @@ class CommunityArticleFragment : ListFragment<ArticleEntity, CommunityArticleVie
}
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
companion object {
@JvmStatic
fun getInstance(type: Type): CommunityArticleFragment {

View File

@ -31,7 +31,11 @@ class CommunityArticleViewModel(application: Application) : ListViewModel<Articl
return if (type == CommunityArticleFragment.Type.COLLECTION) {
Single.fromObservable(RetrofitManager.getInstance(getApplication()).api.getCollectionCommunityArticle(UserManager.getInstance().userId, page))
} else {
HistoryDatabase.instance.articleDao().getArticleWithOffset(20, (page - 1) * 20)
if (page > 5) {
Single.create { it.onSuccess(arrayListOf()) }
} else {
HistoryDatabase.instance.articleDao().getArticleWithOffset(20, (page - 1) * 20)
}
}
}
@ -69,7 +73,7 @@ class CommunityArticleViewModel(application: Application) : ListViewModel<Articl
}
@SuppressLint("CheckResult")
fun postCollectionArticleRead(communityId: String, articleId: String){
fun postCollectionArticleRead(communityId: String, articleId: String) {
RetrofitManager.getInstance(getApplication()).api
.postCollectionArticleRead(UserManager.getInstance().userId, communityId, articleId)
.subscribeOn(Schedulers.io())

View File

@ -1,6 +1,8 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.common.annotation.SyncPage
import com.gh.common.syncpage.SyncFieldConstants
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@ -14,6 +16,7 @@ class MeEntity(@SerializedName("is_community_voted")
@SerializedName("is_user_invite")
var isUserInvite: Boolean = false,
@SyncPage(syncNames = [SyncFieldConstants.ANSWER_VOTE])
@SerializedName("is_answer_voted")
var isAnswerVoted: Boolean = false,
@ -50,10 +53,10 @@ class MeEntity(@SerializedName("is_community_voted")
@SerializedName("is_toolkit_favorite")
var isToolkitFavorite: Boolean = false,
@SerializedName("is_comment_own", alternate = ["is_answer_commented", "is_community_article_commented", "is_video_commented"])
@SerializedName("is_comment_own", alternate = ["is_answer_commented", "is_community_article_commented", "is_video_commented"])
var isCommentOwner: Boolean = false, // 是否是当前评论的拥有者
@SerializedName("is_comment_voted", alternate = ["is_answer_comment_voted","is_video_comment_voted", "is_community_article_comment_voted"])
@SerializedName("is_comment_voted", alternate = ["is_answer_comment_voted", "is_video_comment_voted", "is_community_article_comment_voted"])
var isCommentVoted: Boolean = false, // 是否已经点赞过当前评论
@SerializedName("is_version_requested")
@ -65,6 +68,7 @@ class MeEntity(@SerializedName("is_community_voted")
@SerializedName("is_favorite")
var isCommunityArticleFavorite: Boolean = false,
@SyncPage(syncNames = [SyncFieldConstants.ARTICLE_VOTE])
@SerializedName("is_vote")
var isCommunityArticleVote: Boolean = false,

View File

@ -0,0 +1,3 @@
package com.gh.gamecenter.entity
data class MtaEvent(var name: String = "", var key: String = "", var value: String = "")

View File

@ -27,7 +27,7 @@ data class SettingsEntity(
@SerializedName("article_entrance")
private var articleEntrance: String = "",
@SerializedName("video_advertisement")
var videoAdvertisement: Advertisement? = null //新增字段video_advertisement,可能为空,代表广告关闭
var videoAdvertisement: VideoAds? = null //新增字段video_advertisement,可能为空,代表广告关闭
) {
fun setCommunityEntrance(communityEntrance: String) {
@ -165,6 +165,12 @@ data class SettingsEntity(
}
}
data class VideoAds(
var center: ArrayList<Advertisement>? = null,
var left: ArrayList<Advertisement>? = null,
var right: ArrayList<Advertisement>? = null
)
data class Advertisement(
var duration: Int = -1, //广告总显示秒数
var frequency: Int = -1,//广告出现频率

View File

@ -36,6 +36,8 @@ open class VideoEntity(
@SerializedName("game_active")
val gameActive: Boolean = false,//游戏是否被隐藏 false隐藏
var game: GameEntity? = null,
@SerializedName("share")
var shareCount: Int = 0,//分享数量 v3.7.5新增
var videoIsMuted: Boolean = false//是否静音标记
) : Parcelable {

View File

@ -0,0 +1,5 @@
package com.gh.gamecenter.entity
data class WebShareEntity(var title: String = "",
val description: String = "",
val icon: String = "")

View File

@ -0,0 +1,19 @@
package com.gh.gamecenter.eventbus;
import com.gh.common.util.ShareUtils;
public class EBShare {
public ShareUtils.ShareType shareType;
public EBShare(ShareUtils.ShareType shareType) {
this.shareType = shareType;
}
public ShareUtils.ShareType getShareType() {
return shareType;
}
public void setShareType(ShareUtils.ShareType shareType) {
this.shareType = shareType;
}
}

View File

@ -11,6 +11,12 @@ import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.ColorRes;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import com.airbnb.lottie.LottieAnimationView;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
@ -26,6 +32,7 @@ import com.facebook.imagepipeline.image.ImageInfo;
import com.gh.base.OnDoubleTapListener;
import com.gh.base.fragment.BaseFragment_ViewPager_Checkable;
import com.gh.common.constant.Config;
import com.gh.common.syncpage.SyncPageRepository;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
@ -35,12 +42,8 @@ import com.gh.common.util.ImageUtils;
import com.gh.common.view.ReserveDialog;
import com.gh.common.view.WelcomeDialog;
import com.gh.download.DownloadManager;
import com.gh.gamecenter.MainActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.db.GameTrendsDao;
import com.gh.gamecenter.db.info.GameTrendsInfo;
import com.gh.gamecenter.discover.DiscoverFragment;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.eventbus.EBConcernChanged;
@ -49,13 +52,11 @@ import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.eventbus.EBUISwitch;
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;
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
import com.gh.gamecenter.video.detail.HomeVideoFragment;
import com.halo.assistant.HaloApp;
import com.lightgame.listeners.OnBackPressedListener;
import com.lightgame.view.CheckableImageView;
@ -69,12 +70,6 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import androidx.annotation.ColorRes;
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;
@ -110,9 +105,6 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
@BindView(R.id.main_tab_game_name)
TextView mTabGameName;
// @BindView(R.id.iv_discovery_hint_dot)
// protected View mDiscoveryHintIv;
public static final int INDEX_HOME = 0;
public static final int INDEX_GAME = 1;
public static final int INDEX_VIDEO = 2;
@ -127,7 +119,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
private MainWrapperViewModel mViewModel;
private MessageUnreadViewModel mMessageUnreadViewModel;
private GameTrendsDao mGameTrendsDao;
private VideoDetailContainerFragment videoDetailContainerFragment;
private HomeVideoFragment homeVideoFragment;
private String[] resAssets = {"lottie/tab_home.json", "lottie/tab_game.json", "lottie/tab_video.json", "tab_community.gif", "tab_mine.gif"};
@Override
@ -161,17 +153,15 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
mGameWrapperFragment.setArguments(homeArgs);
fragments.add(mGameWrapperFragment);
videoDetailContainerFragment = new VideoDetailContainerFragment();
homeVideoFragment = new HomeVideoFragment();
Bundle videoArgs = new Bundle();
videoArgs.putString(EntranceUtils.KEY_LOCATION, VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.getValue());
videoArgs.putString(EntranceUtils.KEY_PATH, "视频总入口");
videoArgs.putString(EntranceUtils.KEY_UUID, ((MainActivity) requireContext()).uuid);
//videoArgs.putString(EntranceUtils.KEY_PATH, "视频总入口");
videoArgs.putBoolean(EntranceUtils.KEY_IS_HOME_VIDEO, true);
videoDetailContainerFragment.setArguments(videoArgs);
fragments.add(videoDetailContainerFragment);
homeVideoFragment.setArguments(videoArgs);
fragments.add(homeVideoFragment);
fragments.add(new CommunityFragment());
//fragments.add(new DiscoverFragment());
fragments.add(new PersonalFragment());
}
@ -272,10 +262,9 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
}
@Override
public void onResume() {
super.onResume();
//mViewModel.getDiscoveryData(false);
MessageUnreadRepository.INSTANCE.loadMessageUnreadTotal();
public void onPause() {
super.onPause();
SyncPageRepository.clearSyncData();
}
@Override
@ -582,8 +571,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
@Override
public boolean onHandleBackPressed() {
if (videoDetailContainerFragment != null) {
return videoDetailContainerFragment.onHandleBackPressed();
if (homeVideoFragment.getCurrentFragment() != null) {
return homeVideoFragment.getCurrentFragment().onHandleBackPressed();
}
return false;
}

View File

@ -31,7 +31,6 @@ 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
@ -96,9 +95,9 @@ class GameFragment : NormalFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mBinding = FragmentGameBinding.bind(view)
mBinding.gameRefresh.setColorSchemeColors(ContextCompat.getColor(context!!, R.color.theme))
mBinding.gameRefresh.setColorSchemeColors(ContextCompat.getColor(requireContext(), R.color.theme))
mLayoutManager = FixLinearLayoutManager(context)
mListAdapter = GameFragmentAdapter(context!!, mViewModel, mLayoutManager)
mListAdapter = GameFragmentAdapter(requireContext(), mViewModel, mLayoutManager)
mBinding.gameList.run {
(itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
@ -133,6 +132,9 @@ class GameFragment : NormalFragment() {
mReplaceDataButton.setOnClickListener {
val firstVisiblePosition = mLayoutManager.findFirstVisibleItemPosition()
val lastVisiblePosition = mLayoutManager.findLastVisibleItemPosition()
if (firstVisiblePosition == RecyclerView.NO_POSITION
|| lastVisiblePosition == RecyclerView.NO_POSITION) return@setOnClickListener
for (position in firstVisiblePosition..lastVisiblePosition) {
val itemData = mListAdapter.getItemDataByPosition(position)
if (itemData != null && mViewModel.replaceRefreshData(itemData)) mListAdapter.notifyItemChanged(position)
@ -167,7 +169,7 @@ class GameFragment : NormalFragment() {
//下载被删除事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
if ("delete" == status.status) {
if (::mListAdapter.isInitialized && "delete" == status.status) {
mListAdapter.notifyItemAndRemoveDownload(status)
}
}
@ -175,23 +177,26 @@ class GameFragment : NormalFragment() {
//安装、卸载事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
val data = mListAdapter.getGameEntityByPackage(busFour.packageName)
for (gameAndPosition in data) {
mListAdapter.notifyChildItem(gameAndPosition.position)
if (::mListAdapter.isInitialized) {
val data = mListAdapter.getGameEntityByPackage(busFour.packageName)
for (gameAndPosition in data) {
mListAdapter.notifyChildItem(gameAndPosition.position)
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
if ("Refresh" == reuse.type) {
if (::mListAdapter.isInitialized && "Refresh" == reuse.type) {
mListAdapter.notifyDataSetChanged()
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNine: EBUISwitch) {
if (MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
&& MainWrapperFragment.INDEX_GAME == busNine.position) {
if (::mLayoutManager.isInitialized &&
MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from &&
MainWrapperFragment.INDEX_GAME == busNine.position) {
mBinding.gameList.stopScroll()
mLayoutManager.scrollToPosition(0)
}

View File

@ -8,7 +8,6 @@ import androidx.lifecycle.*
import com.gh.common.TimeElapsedHelper
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.baselist.LoadStatus
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.game.data.GameItemData
@ -20,7 +19,7 @@ import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import java.util.HashMap
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.set
@ -88,7 +87,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<LinkEntity>>() {
override fun onResponse(response: List<LinkEntity>?) {
if (response != null) mSlideList.addAll(response)
if (response != null) mSlideList = response as ArrayList<LinkEntity>
if (initData) getSubjectDigest(initData)
}
@ -110,7 +109,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<SubjectRecommendEntity>>() {
override fun onResponse(response: List<SubjectRecommendEntity>?) {
if (response != null) mSubjectDigestList.addAll(response)
if (response != null) mSubjectDigestList = response as ArrayList<SubjectRecommendEntity>
transformationItemData()
if (initData) {
getSubjectList(initData)

View File

@ -197,7 +197,7 @@ class GameDetailFragment : NormalFragment() {
checkReadPhoneStatePermissionBeforeAction {
ifLogin("游戏详情-[关注]") {
if (mGameDetailEntity != null && mGameDetailEntity!!.me.isGameConcerned) {
DialogUtils.showCancelDialog(context!!, { mViewModel.concernCommand(false) }, null)
DialogUtils.showCancelDialog(requireContext(), { mViewModel.concernCommand(false) }, null)
} else {
mViewModel.concernCommand(true)
}
@ -271,6 +271,9 @@ class GameDetailFragment : NormalFragment() {
}
mAppBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
// requireContext():not attached to context
if (!isAdded) return@OnOffsetChangedListener
val absVerticalOffset = abs(verticalOffset)
val total = appBarLayout.totalScrollRange
@ -368,7 +371,6 @@ class GameDetailFragment : NormalFragment() {
GdtHelper.CONTENT_TYPE, "GAME",
GdtHelper.CONTENT_ID, mGameEntity!!.id)
data.game.id = mGameEntity!!.id
mGameDetailEntity = data.game
downloadAddWord = data.game.getDownloadAddWord()
downloadOffText = data.game.downloadOffText
@ -376,7 +378,6 @@ class GameDetailFragment : NormalFragment() {
showAlertDialogIfNeeded(data.game)
val bundle = Bundle()
bundle.putParcelable(UnifiedGameDetailEntity.TAG, data)
bundle.putParcelable(GameEntity.TAG, mGameEntity)
bundle.putString(EntranceUtils.KEY_ENTRANCE, mEntrance)
bundle.putBoolean(EntranceUtils.KEY_SCROLL_TO_LIBAO, arguments?.getBoolean(EntranceUtils.KEY_SCROLL_TO_LIBAO) ?: false)

View File

@ -84,6 +84,8 @@ class GameDetailViewModel(application: Application,
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<UnifiedGameDetailEntity>() {
override fun onSuccess(data: UnifiedGameDetailEntity) {
data.game.id = game?.id
// 过滤过期公告
if (!data.game.notice.isNullOrEmpty()) {
val l = System.currentTimeMillis()
@ -197,6 +199,7 @@ class GameDetailViewModel(application: Application,
for (originalAnswer in unifiedGameDetailEntity.communityColumnContents!!) {
if (originalAnswer.id == answer.id) {
originalAnswer.me = answer.me
originalAnswer.vote = answer.vote
break
}
}

View File

@ -14,11 +14,11 @@ import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameDetailEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.UnifiedGameDetailEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.GameDetailFragment.Companion.OPEN_APPBAR
import com.gh.gamecenter.gamedetail.GameDetailFragment.Companion.SKIP_DESC
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.EventBus
@ -66,20 +66,25 @@ class DescFragment : BaseFragment<Any>() {
override fun onCreate(savedInstanceState: Bundle?) {
mGameEntity = arguments?.getParcelable(GameEntity.TAG)
mDetailEntity = (arguments?.getParcelable(UnifiedGameDetailEntity.TAG) as UnifiedGameDetailEntity).game
openVideoStreaming = arguments?.getBoolean(EntranceUtils.KEY_OPEN_VIDEO_STREAMING, false)
?: false
val factory = DescViewModel.Factory(HaloApp.getInstance().application,
mGameEntity,
mDetailEntity)
val gameDetailFactory = GameDetailViewModel.Factory(HaloApp.getInstance().application, mGameEntity?.id, mGameEntity)
val gameDetailViewModel: GameDetailViewModel = viewModelProviderFromParent(gameDetailFactory)
mDetailEntity = gameDetailViewModel.unifiedGameDetailLiveData.value?.data?.game
val factory = DescViewModel.Factory(HaloApp.getInstance().application, mGameEntity)
mViewModel = viewModelProvider(factory)
gameDetailViewModel.unifiedGameDetailLiveData.observeNonNull(this) {
mViewModel.constructList(it.data!!.game)
}
mViewModel.list.observe(this, Observer { descItemDataList ->
descItemDataList?.let {
mAdapter.updateDescItemList(it)
}
descItemDataList.forEach {
if (openVideoStreaming && it.intro?.video != null&& !RunningUtils.isEqualsTop(context, VideoDetailActivity::class.java.name)) {
if (openVideoStreaming && it.intro?.video != null && !RunningUtils.isEqualsTop(context, VideoDetailActivity::class.java.name)) {
DirectUtils.directToVideoDetail(requireContext(), it.intro?.video?.videoId
?: "", it.intro?.video?.videoId ?: "", path = "游戏详情-介绍视频")
return@forEach

View File

@ -22,18 +22,20 @@ import okhttp3.ResponseBody
import retrofit2.HttpException
class DescViewModel(application: Application,
var game: GameEntity?,
var gameDetail: GameDetailEntity?) : AndroidViewModel(application) {
var game: GameEntity?) : AndroidViewModel(application) {
private var mDataList = arrayListOf<DescItemData>()
private var mRelatedGameList = arrayListOf<GameEntity>()
private var mGameDetail: GameDetailEntity? = null
var list = MutableLiveData<ArrayList<DescItemData>>()
var gameId = game?.id
init {
fun constructList(gameDetailEntity: GameDetailEntity) {
mGameDetail = gameDetailEntity
// 构建列表
gameDetail?.let {
mGameDetail?.let {
// 这里的高、低优先级是指相对于游戏介绍区域的位置,高在上面低在下面
val highPriorityCustomColumnList = arrayListOf<GameDetailEntity.CustomColumn>()
@ -98,7 +100,7 @@ class DescViewModel(application: Application,
list.postValue(mDataList)
if (gameDetail?.showComment == true) {
if (mGameDetail?.showComment == true) {
retrieveComment()
}
}
@ -109,14 +111,14 @@ class DescViewModel(application: Application,
*/
fun generateRecommendedGamesItem() {
// 看游戏详情有没有相关游戏,没有就拿 3个 热门卡牌
if (gameDetail == null
|| gameDetail!!.relatedGames == null
|| gameDetail!!.relatedGames!!.isEmpty()) {
if (mGameDetail == null
|| mGameDetail!!.relatedGames == null
|| mGameDetail!!.relatedGames!!.isEmpty()) {
assembleListWithRecommendedGames()
return
}
val relatedGames = gameDetail!!.relatedGames
val relatedGames = mGameDetail!!.relatedGames
val idList = ArrayList<String>()
for (relatedGame in relatedGames!!) {
val size = relatedGame.game!!.size
@ -267,10 +269,9 @@ class DescViewModel(application: Application,
}
class Factory(private val mApplication: Application,
private val game: GameEntity?,
private val gameDetail: GameDetailEntity?) : ViewModelProvider.NewInstanceFactory() {
private val game: GameEntity?) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return DescViewModel(mApplication, game, gameDetail) as T
return DescViewModel(mApplication, game) as T
}
}

View File

@ -46,6 +46,8 @@ class FuLiAdapter(context: Context,
private var mIsUpdateInfoFirstTimeLayout = true
var answerAdapter: GameDetailAnswerAdapter? = null
override fun getItemViewType(position: Int): Int {
if (itemList == null || itemList!!.isEmpty()) {
return NO_DATA
@ -160,7 +162,8 @@ class FuLiAdapter(context: Context,
}
answerItemList.layoutManager = LinearLayoutManager(mContext)
answerItemList.adapter = GameDetailAnswerAdapter(mContext, mFuLiViewModel!!, itemList?.get(position)?.answer!!, mEntrance)
answerAdapter = GameDetailAnswerAdapter(mContext, mFuLiViewModel!!, itemList?.get(position)?.answer!!, mEntrance)
answerItemList.adapter = answerAdapter
answerItemMore.setOnClickListener {
answerItemHint.visibility = View.GONE
mSharedPreferences.edit().putBoolean(mAnswerHintKey, false).apply()

View File

@ -18,7 +18,6 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.LibaoEntity
import com.gh.gamecenter.entity.ServerCalendarEntity
import com.gh.gamecenter.entity.UnifiedGameDetailEntity
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.GameDetailViewModel
@ -102,7 +101,6 @@ class FuLiFragment : BaseFragment<Any>() {
super.onCreate(savedInstanceState)
val gameEntity = arguments?.getParcelable(GameEntity.TAG) as GameEntity
val unifiedGameDetailEntity = arguments?.getParcelable(UnifiedGameDetailEntity.TAG) as UnifiedGameDetailEntity
val gameDetailFactory = GameDetailViewModel.Factory(HaloApp.getInstance().application, gameEntity.id, gameEntity)
shouldScroolToLibao = arguments?.getBoolean(EntranceUtils.KEY_SCROLL_TO_LIBAO) ?: false
@ -110,7 +108,9 @@ class FuLiFragment : BaseFragment<Any>() {
mGameDetailViewModel = viewModelProviderFromParent(gameDetailFactory)
mFuLiViewModel?.updateGameEntity(gameEntity)
mFuLiViewModel?.updateUnifiedGameDetailEntity(unifiedGameDetailEntity)
mGameDetailViewModel?.unifiedGameDetailLiveData?.value?.data?.let {
mFuLiViewModel?.updateUnifiedGameDetailEntity(it)
}
mFuLiViewModel?.fuFiDataLD?.observe(this, Observer {
reuse_ll_loading.visibility = View.GONE
@ -133,7 +133,7 @@ class FuLiFragment : BaseFragment<Any>() {
super.onViewCreated(view, savedInstanceState)
mViewSkeletonScreen = Skeleton.bind(game_detail_skeleton).shimmer(false).load(R.layout.fragment_gamedongtai_skeleton).show()
mAdapter = FuLiAdapter(context!!, this, mFuLiViewModel, mEntrance)
mAdapter = FuLiAdapter(requireContext(), this, mFuLiViewModel, mEntrance)
mRecyclerView.adapter = mAdapter
layoutManager = object : androidx.recyclerview.widget.LinearLayoutManager(context) {
override fun canScrollVertically(): Boolean {
@ -223,4 +223,12 @@ class FuLiFragment : BaseFragment<Any>() {
}
}
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter?.answerAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter.gamedetail.fuli.answer
import android.content.Context
import android.view.ViewGroup
import com.gh.common.constant.Constants
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.MtaHelper
import com.gh.common.util.StringUtils
import com.gh.common.util.visibleIf
@ -23,7 +24,7 @@ class GameDetailAnswerAdapter(context: Context,
var mViewModel: FuLiViewModel,
private val mAnswerList: List<AnswerEntity>,
private val mEntrance: String)
: BaseRecyclerAdapter<CommunityAnswerItemViewHolder>(context) {
: BaseRecyclerAdapter<CommunityAnswerItemViewHolder>(context), ISyncAdapterHandler {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommunityAnswerItemViewHolder {
val view = mLayoutInflater.inflate(R.layout.community_answer_item, parent, false)
@ -47,7 +48,7 @@ class GameDetailAnswerAdapter(context: Context,
MtaHelper.onEvent("进入问答", "游戏详情", mViewModel.gameCommunity?.name + "+" + mViewModel.game?.name)
if ("community_article" == entity.type) {
MtaHelper.onEvent("游戏详情_新", "点击社区文章", mViewModel.game?.name + "->" + entity.questions.title)
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(entity.communityId!!, ""), entity.id!!, mEntrance, path))
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(entity.articleCommunityId, ""), entity.id!!, mEntrance, path))
} else {
MtaHelper.onEvent("游戏详情_新", "点击问题", mViewModel.game?.name + "->" + entity.questions.title)
mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, entity.questions.id, mEntrance, path))
@ -59,7 +60,7 @@ class GameDetailAnswerAdapter(context: Context,
MtaHelper.onEvent("进入问答", "游戏详情", mViewModel.gameCommunity?.name + "+" + mViewModel.game?.name)
if ("community_article" == entity.type) {
MtaHelper.onEvent("游戏详情_新", "点击社区文章", mViewModel.game?.name + "->" + entity.questions.title)
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(entity.communityId!!, ""), entity.id!!, mEntrance, path))
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(entity.articleCommunityId, ""), entity.id!!, mEntrance, path))
} else {
MtaHelper.onEvent("游戏详情_新", "点击答案", mViewModel.game?.name + "->" + StringUtils.shrinkStringWithDot(entity.brief, 10))
mContext.startActivity(AnswerDetailActivity.getIntent(mContext, entity.id, mEntrance, path))
@ -67,4 +68,9 @@ class GameDetailAnswerAdapter(context: Context,
}
}
override fun getSyncData(position: Int): Pair<String, AnswerEntity>? {
if (position >= mAnswerList.size) return null
val entity = mAnswerList[position]
return Pair(entity.id ?: "", entity)
}
}

View File

@ -56,7 +56,7 @@ class HelpContentAdapter(context: Context,
if (entity.content.startsWith("http")) {
mContext.startActivity(WebActivity.getIntent(mContext, entity.content, false))
} else {
val content = "<html><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" /><meta name=\"renderer\" content=\"webkit\"></head><body><div style=\"color:#333;font-size:18px;font-weight:bold;\">${entity.title}</div>${entity.content}</body></html>"
val content = "<html><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" /><meta name=\"renderer\" content=\"webkit\"></head><body style=\"overflow-x: hidden; word-break: break-all;\"><div style=\"color:#333;font-size:18px;font-weight:bold;\">${entity.title}</div>${entity.content}</body></html>"
mContext.startActivity(WebActivity.getIntent(mContext, content, false))
}
val category = mFragment.getHelpCategory()

View File

@ -14,12 +14,16 @@ class HistoryGameListViewModel(application: Application) : ListViewModel<GameEnt
}
override fun provideDataSingle(page: Int): Single<List<GameEntity>> {
return HistoryDatabase.instance.gameDao().getGamesWithOffset(20, (page - 1) * 20).map {
val gameEntityList = arrayListOf<GameEntity>()
for (history in it) {
gameEntityList.add(history.convertHistoryGameEntityToGameEntity())
return if (page > 5) {
Single.create { it.onSuccess(arrayListOf()) }
} else {
HistoryDatabase.instance.gameDao().getGamesWithOffset(20, (page - 1) * 20).map {
val gameEntityList = arrayListOf<GameEntity>()
for (history in it) {
gameEntityList.add(history.convertHistoryGameEntityToGameEntity())
}
gameEntityList
}
gameEntityList
}
}

View File

@ -46,6 +46,7 @@ class HomeFragment : BaseFragment<Any>() {
mListAdapter.notifyItemByDownload(downloadEntity)
}
}
override fun getLayoutId(): Int {
return R.layout.fragment_game
}
@ -145,7 +146,8 @@ class HomeFragment : BaseFragment<Any>() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNine: EBUISwitch) {
if (MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
if (::mLayoutManager.isInitialized
&& MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
&& MainWrapperFragment.INDEX_HOME == busNine.position) {
mBinding.gameList.stopScroll()
mLayoutManager.scrollToPosition(0)

View File

@ -8,6 +8,7 @@ import android.widget.RelativeLayout;
import com.gh.base.BaseActivity;
import com.gh.base.BaseRecyclerViewHolder;
import com.gh.base.OnListClickListener;
import com.gh.common.util.ClickUtils;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.ImageUtils;
@ -123,7 +124,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
mBinding.messageOriginalTitle.setText(messageEntity.getQuestion().getTitle());
images = messageEntity.getAnswer().getImages();
if (images.size() > 0) {
targetUrl=images.get(0);
targetUrl = images.get(0);
mBinding.messageAskIcon.setVisibility(View.VISIBLE);
mBinding.messageArticleIcon.setVisibility(View.GONE);
}
@ -373,7 +374,9 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
mBinding.messageUserMore.setOnClickListener(v -> {
MessageEntity.Fold fold = messageEntity.getFold();
if (fold != null) getFoldList(context, messageEntity.getFold().getResourceId());
if (fold != null && !ClickUtils.isFastDoubleClick(mBinding.messageUserMore.getId(), 1000)) {
getFoldList(context, messageEntity.getFold().getResourceId());
}
});
mBinding.messageUserIcon.setOnClickListener(v -> {
MtaHelper.onEvent("消息中心", mOuterInfo, "点击头像");

View File

@ -24,6 +24,7 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.DefaultJsApi;
import com.gh.common.constant.Config;
import com.gh.common.history.HistoryHelper;
import com.gh.common.util.CheckLoginUtils;
@ -62,8 +63,10 @@ import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.CommentnumEntity;
import com.gh.gamecenter.entity.CommunityEntity;
import com.gh.gamecenter.entity.GameEntity;
import com.gh.gamecenter.entity.MtaEvent;
import com.gh.gamecenter.entity.NewsDetailEntity;
import com.gh.gamecenter.entity.NewsEntity;
import com.gh.gamecenter.qa.editor.OnLinkClickListener;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.subject.SubjectActivity;
@ -225,12 +228,15 @@ public class NewsDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
mRichEditor = viewHolder.contentTv;
if (viewHolder.contentTv.getTag() == null) {
MtaEvent mtaEvent = new MtaEvent("阅读文章", "视频", mNewsDetailEntity.getTitle());
viewHolder.contentTv.addJavascriptInterface(new OnLinkClickListener(mContext, mEntrance, "新闻详情", mtaEvent), "OnLinkClickListener");
viewHolder.contentTv.addJavascriptInterface(new JsInterface(viewHolder.contentTv), "imagelistener");
mWebSettings = viewHolder.contentTv.getSettings();
mWebSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
mWebSettings.setTextZoom(defaultTextZoom + sp.getInt(SettingsFragment.FONT_SIZE_SP_KEY, 1) * 15);
viewHolder.contentTv.setHtml(mNewsDetailEntity.getContent(), true);
// viewHolder.contentTv.initArticleVideo();
viewHolder.contentTv.setInputEnabled(false);
viewHolder.contentTv.setChromeClientListener(new RichEditor.WebChromeClientListener() {
@Override

View File

@ -13,6 +13,16 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.databind.BindingAdapters;
@ -48,7 +58,6 @@ import com.gh.gamecenter.eventbus.EBConcernChanged;
import com.gh.gamecenter.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.eventbus.EBUISwitch;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.message.MessageUnreadRepository;
@ -77,16 +86,6 @@ import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -449,13 +448,13 @@ public class PersonalFragment extends BaseFragment implements Observer<ApiRespon
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBUISwitch busNine) {
if (MainWrapperFragment.EB_MAIN_SCROLL_TOP.equals(busNine.getFrom())
&& INDEX_PERSONAL == busNine.getPosition()) {
//mScrollView.fullScroll(ScrollView.FOCUS_UP);
}
}
// @Subscribe(threadMode = ThreadMode.MAIN)
// public void onEventMainThread(EBUISwitch busNine) {
// if (MainWrapperFragment.EB_MAIN_SCROLL_TOP.equals(busNine.getFrom())
// && INDEX_PERSONAL == busNine.getPosition()) {
// //mScrollView.fullScroll(ScrollView.FOCUS_UP);
// }
// }
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(EBReuse reuse) {

View File

@ -100,7 +100,7 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
notifyDataSetChanged()
}
MtaHelper.onEvent("我的光环_新", "功能入口", "$groupName+${linkEntity.type}")
MtaHelper.onEvent("我的光环_新", "功能入口", "$groupName+${linkEntity.name}")
when (linkEntity.type) {
"我的游戏" -> {
if (UserManager.getInstance().isLoggedIn) {

View File

@ -41,11 +41,9 @@ class PersonalFunctionGroupAdapter(val context: Context) : BaseRecyclerAdapter<R
val groupNameTv = holder.itemView.findViewById<TextView>(R.id.tv_group_name)
val funcRv = holder.itemView.findViewById<RecyclerView>(R.id.funcRv)
groupNameTv.text = groupEntity.name
val mPersonalFunctionAdapter: PersonalFunctionAdapter
funcRv.apply {
if (adapter == null) {
mPersonalFunctionAdapter = PersonalFunctionAdapter(context, groupEntity.name, groupEntity.addons)
adapter = mPersonalFunctionAdapter
adapter = PersonalFunctionAdapter(context, groupEntity.name, groupEntity.addons)
} else {
(adapter as PersonalFunctionAdapter).checkResetData(groupEntity)
}

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.FunctionalGroupEntity
import com.gh.gamecenter.entity.FunctionalLinkEntity
@ -51,9 +50,7 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ArrayList<FunctionalGroupEntity>>() {
override fun onSuccess(data: ArrayList<FunctionalGroupEntity>) {
if (!BuildConfig.DEBUG) {
haloAddData.postValue(data)
}
haloAddData.postValue(data)
}
})
}

View File

@ -396,6 +396,7 @@ class CommunityFragment : BaseFragment_TabLayout() {
false)
val window = dialog.window
window?.setGravity(Gravity.BOTTOM)
window?.setWindowAnimations(R.style.community_publication_animation)
dialog.setContentView(contentView, params)
dialog.show()
contentView.findViewById<View>(R.id.community_edit_article).setOnClickListener {

View File

@ -46,7 +46,7 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener
if (entity.type == "community_article") {
val communityId = if (!entity.communityId.isNullOrEmpty()) entity.communityId!!
val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
else UserManager.getInstance().community.id
val intent = CommentActivity.getArticleCommentIntent(itemView.context,
entity.id!!,
@ -210,8 +210,8 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
playVoteAnimation()
val voteObservable = if (entity.type == "community_article") {
val communityId = if (entity.communityId.isNullOrEmpty()) UserManager.getInstance().community.id
else entity.communityId
val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
else UserManager.getInstance().community.id
RetrofitManager.getInstance(itemView.context).api
.postCommunityArticleVote(communityId, entity.id)
} else {
@ -223,7 +223,11 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<VoteEntity>() {
override fun onResponse(response: VoteEntity?) {
entity.me.isAnswerVoted = true
if (entity.type == "community_article") {
entity.me.isCommunityArticleVote = true
} else {
entity.me.isAnswerVoted = true
}
Utils.toast(itemView.context, "已赞同")
}
@ -242,7 +246,11 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
true
} else {
entity.vote = entity.vote - 1
entity.me.isAnswerVoted = false
if (entity.type == "community_article") {
entity.me.isCommunityArticleVote = true
} else {
entity.me.isAnswerVoted = true
}
binding.voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
setVoteAndCommentStyle(entity)
false
@ -254,17 +262,21 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
private fun cancelAnswerVote(entity: AnswerEntity) {
entity.vote = entity.vote - 1
entity.me.isAnswerVoted = false
binding.voteIcon.isChecked = false
binding.voteCount.setTextColor(R.color.text_999999.toColor())
binding.voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
val unVoteObservable = if (entity.type == "community_article") {
val communityId = if (entity.communityId.isNullOrEmpty()) UserManager.getInstance().community.id
else entity.communityId
entity.me.isCommunityArticleVote = false
val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
else UserManager.getInstance().community.id
RetrofitManager.getInstance(itemView.context).api
.postCommunityArticleUnVote(communityId, entity.id)
} else {
entity.me.isAnswerVoted = false
RetrofitManager.getInstance(itemView.context).api
.postAnswerUnvote(entity.id)
}
@ -291,7 +303,11 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
true
} else {
entity.vote = entity.vote + 1
entity.me.isAnswerVoted = true
if (entity.type == "community_article") {
entity.me.isCommunityArticleVote = true
} else {
entity.me.isAnswerVoted = true
}
binding.voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
setVoteAndCommentStyle(entity)
false

View File

@ -6,6 +6,9 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.history.HistoryHelper
import com.gh.common.syncpage.SyncDataEntity
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SpecialColumn
@ -88,6 +91,8 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
val apiResponse = ApiResponse<VoteEntity>()
apiResponse.data = response
mVoteLiveData.postValue(apiResponse)
syncVoteData(answerId)
}
override fun onFailure(e: HttpException?) {
@ -111,6 +116,8 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
val apiResponse = ApiResponse<VoteEntity>()
apiResponse.data = response
mVoteLiveData.postValue(apiResponse)
syncVoteData(answerId)
}
override fun onFailure(e: HttpException?) {
@ -134,6 +141,8 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
answerDetail?.me?.isAnswerVoted = false
dislike.postValue(true)
syncVoteData(answerId)
}
override fun onFailure(e: HttpException?) {
@ -150,6 +159,8 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
override fun onResponse(response: ResponseBody?) {
answerDetail?.me?.isAnswerOpposed = false
dislike.postValue(false)
syncVoteData(answerId)
}
override fun onFailure(e: HttpException?) {
@ -158,6 +169,16 @@ class AnswerDetailViewModel(application: Application) : AndroidViewModel(applica
})
}
private fun syncVoteData(answerId: String) {
SyncPageRepository.postSyncData(SyncDataEntity(answerId,
SyncFieldConstants.ANSWER_VOTE_COUNT,
answerDetail!!.vote))
SyncPageRepository.postSyncData(SyncDataEntity(answerId,
SyncFieldConstants.ANSWER_VOTE,
answerDetail?.me?.isAnswerVoted,
checkFieldEntity = true))
}
fun collectAnswer(answerId: String) {
CollectionUtils.postCollection(getApplication(), answerId, CollectionUtils.CollectionType.answer, object : CollectionUtils.OnCollectionListener {
override fun onSuccess() {

View File

@ -6,6 +6,7 @@ import android.view.ViewGroup;
import com.gh.base.OnListClickListener;
import com.gh.common.constant.ItemViewType;
import com.gh.common.syncpage.ISyncAdapterHandler;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder;
import com.gh.gamecenter.baselist.ListAdapter;
@ -14,13 +15,16 @@ import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder;
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
import com.gh.gamecenter.qa.entity.AnswerEntity;
import org.jetbrains.annotations.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.Pair;
/**
* Created by khy on 11/12/17.
*/
public class AnswerFoldAdapter extends ListAdapter<AnswerEntity> {
public class AnswerFoldAdapter extends ListAdapter<AnswerEntity> implements ISyncAdapterHandler {
private OnListClickListener mListClickListener;
@ -59,8 +63,8 @@ public class AnswerFoldAdapter extends ListAdapter<AnswerEntity> {
switch (getItemViewType(position)) {
case ItemViewType.ITEM_BODY:
AnswerEntity answer = mEntityList.get(position);
((CommunityAnswerItemViewHolder) holder).bindAnswerItem(answer,true, mEntrance, "折叠答案");
((CommunityAnswerItemViewHolder) holder).getBinding().getRoot().setOnClickListener( view -> {
((CommunityAnswerItemViewHolder) holder).bindAnswerItem(answer, true, mEntrance, "折叠答案");
((CommunityAnswerItemViewHolder) holder).getBinding().getRoot().setOnClickListener(view -> {
mContext.startActivity(AnswerDetailActivity.getIntent(mContext, answer.getId(), mEntrance, "折叠答案"));
});
@ -77,4 +81,12 @@ public class AnswerFoldAdapter extends ListAdapter<AnswerEntity> {
public int getItemCount() {
return mEntityList == null || mEntityList.isEmpty() ? 0 : mEntityList.size() + FOOTER_ITEM_COUNT;
}
@Nullable
@Override
public Pair<String, Object> getSyncData(int position) {
if (position >= mEntityList.size()) return null;
AnswerEntity entity = mEntityList.get(position);
return new Pair(entity.getId(), entity);
}
}

View File

@ -1,8 +1,10 @@
package com.gh.gamecenter.qa.answer.fold;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import com.gh.common.util.EntranceUtils;
@ -97,4 +99,15 @@ public class AnswerFoldFragment extends ListFragment<AnswerEntity, NormalListVie
break;
}
}
@Nullable
@Override
protected RecyclerView.Adapter provideSyncAdapter() {
return mAdapter;
}
@Override
protected boolean addSyncPageObserver() {
return true;
}
}

View File

@ -36,7 +36,7 @@ class MyArticleFragment : ListFragment<ArticleEntity, NormalListViewModel<Articl
return mAdapter!!
}
override fun provideDataObservable(page: Int): Observable<MutableList<ArticleEntity>> {
override fun provideDataObservable(page: Int): Observable<MutableList<ArticleEntity>>? {
return RetrofitManager.getInstance(HaloApp.getInstance().application).api.getMyArticle(mTargetUserId, page)
}

View File

@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
@ -15,7 +16,7 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.qa.entity.Questions
class SimpleArticleListAdapter(context: Context) : ListAdapter<ArticleEntity>(context) {
class SimpleArticleListAdapter(context: Context) : ListAdapter<ArticleEntity>(context), ISyncAdapterHandler {
override fun areItemsTheSame(oldItem: ArticleEntity?, newItem: ArticleEntity?): Boolean {
return oldItem?.id == newItem?.id
@ -72,4 +73,10 @@ class SimpleArticleListAdapter(context: Context) : ListAdapter<ArticleEntity>(co
}
}
override fun getSyncData(position: Int): Pair<String, Any>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id, entity)
}
}

View File

@ -86,4 +86,12 @@ class SimpleArticleListFragment : ListFragment<ArticleEntity, SimpleArticleListV
mBaseHandler.postDelayed({ mListViewModel.load(LoadType.REFRESH) }, 100)
}
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -4,6 +4,9 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.syncpage.SyncDataEntity
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.common.syncpage.SyncPageRepository
import com.gh.common.util.CollectionUtils
import com.gh.common.util.ErrorHelper
import com.gh.gamecenter.R
@ -79,6 +82,8 @@ class ArticleDetailViewModel(application: Application) : AndroidViewModel(applic
detailEntity!!.count.vote--
like.postValue(response)
syncVoteData()
}
override fun onFailure(e: HttpException?) {
@ -99,6 +104,8 @@ class ArticleDetailViewModel(application: Application) : AndroidViewModel(applic
detailEntity!!.count.vote++
like.postValue(response)
syncVoteData()
}
override fun onFailure(e: HttpException?) {
@ -119,6 +126,8 @@ class ArticleDetailViewModel(application: Application) : AndroidViewModel(applic
detailEntity?.me?.isCommunityArticleVote = false
dislike.postValue(true)
syncVoteData()
}
override fun onFailure(e: HttpException?) {
@ -135,6 +144,8 @@ class ArticleDetailViewModel(application: Application) : AndroidViewModel(applic
detailEntity?.me?.isCommunityArticleOppose = false
dislike.postValue(false)
syncVoteData()
}
override fun onFailure(e: HttpException?) {
@ -143,6 +154,19 @@ class ArticleDetailViewModel(application: Application) : AndroidViewModel(applic
})
}
private fun syncVoteData() {
articleId?.apply {
SyncPageRepository.postSyncData(SyncDataEntity(this,
SyncFieldConstants.ARTICLE_VOTE_COUNT,
detailEntity?.count?.vote,
checkFieldEntity = true))
SyncPageRepository.postSyncData(SyncDataEntity(this,
SyncFieldConstants.ARTICLE_VOTE,
detailEntity?.me?.isCommunityArticleVote,
checkFieldEntity = true))
}
}
fun collectionCommand(isCollection: Boolean, callback: (isFollow: Boolean) -> Unit) {
val observable = if (isCollection) {
mApi.postCommunityArticleFavorites(UserManager.getInstance().userId, community?.id, articleId)

View File

@ -4,6 +4,7 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.ImageUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
@ -21,7 +22,7 @@ import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
class HotAdapter(context: Context,
private val mEntrance: String,
private val mPath: String,
private val mSpecialColumn: SpecialColumn) : ListAdapter<AnswerEntity>(context) {
private val mSpecialColumn: SpecialColumn) : ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
override fun getItemViewType(position: Int): Int {
return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY
@ -87,4 +88,10 @@ class HotAdapter(context: Context,
}
}
override fun getSyncData(position: Int): Pair<String, AnswerEntity>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
}

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.qa.column.detail.hot
import androidx.lifecycle.ViewModelProviders
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.entity.SpecialColumn
@ -25,16 +26,16 @@ class HotFragment : ListFragment<AnswerEntity, HotViewModel>() {
mSpecialColumn.type = "社区专栏"
"专栏-热门"
}
mAdapter = HotAdapter(context!!, mEntrance, path, mSpecialColumn)
mAdapter = HotAdapter(requireContext(), mEntrance, path, mSpecialColumn)
}
return mAdapter
}
override fun provideListViewModel(): HotViewModel {
val tag = arguments!!.getString(EntranceUtils.KEY_ASK_TAG)
val entity = arguments!!.getParcelable<AskTagGroupsEntity>(EntranceUtils.KEY_ASK_COLUMN_TAG)
val tag = requireArguments().getString(EntranceUtils.KEY_ASK_TAG)
val entity = requireArguments().getParcelable<AskTagGroupsEntity>(EntranceUtils.KEY_ASK_COLUMN_TAG)
val factory = HotViewModel.Factory(HaloApp.getInstance().application
, if (tag.isNullOrEmpty()) entity else tag, arguments!!.getParcelable(EntranceUtils.KEY_COMMUNITY_DATA))
, if (tag.isNullOrEmpty()) entity else tag, requireArguments().getParcelable(EntranceUtils.KEY_COMMUNITY_DATA))
return ViewModelProviders.of(this, factory).get(HotViewModel::class.java)
}
@ -48,4 +49,12 @@ class HotFragment : ListFragment<AnswerEntity, HotViewModel>() {
mListRv.visibility = View.VISIBLE
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -4,6 +4,7 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.ImageUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
@ -21,7 +22,7 @@ import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
class RecommendsAdapter(context: Context,
private val mEntrance: String,
private val mPath: String,
private val mSpecialColumn: SpecialColumn) : ListAdapter<AnswerEntity>(context) {
private val mSpecialColumn: SpecialColumn) : ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
override fun getItemViewType(position: Int): Int {
return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY
@ -85,4 +86,9 @@ class RecommendsAdapter(context: Context,
}
}
override fun getSyncData(position: Int): Pair<String, AnswerEntity>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
}

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.qa.column.detail.recommends
import androidx.lifecycle.ViewModelProviders
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.EntranceUtils
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.entity.SpecialColumn
@ -25,16 +26,16 @@ class RecommendsFragment : ListFragment<AnswerEntity, RecommendsViewModel>() {
mSpecialColumn.type = "社区专栏"
"专栏-精华"
}
mAdapter = RecommendsAdapter(context!!, mEntrance, path, mSpecialColumn)
mAdapter = RecommendsAdapter(requireContext(), mEntrance, path, mSpecialColumn)
}
return mAdapter
}
override fun provideListViewModel(): RecommendsViewModel {
val tag = arguments!!.getString(EntranceUtils.KEY_ASK_TAG)
val entity = arguments!!.getParcelable<AskTagGroupsEntity>(EntranceUtils.KEY_ASK_COLUMN_TAG)
val tag = requireArguments().getString(EntranceUtils.KEY_ASK_TAG)
val entity = requireArguments().getParcelable<AskTagGroupsEntity>(EntranceUtils.KEY_ASK_COLUMN_TAG)
val factory = RecommendsViewModel.Factory(HaloApp.getInstance().application
, if (tag.isNullOrEmpty()) entity else tag, arguments!!.getParcelable(EntranceUtils.KEY_COMMUNITY_DATA))
, if (tag.isNullOrEmpty()) entity else tag, requireArguments().getParcelable(EntranceUtils.KEY_COMMUNITY_DATA))
return ViewModelProviders.of(this, factory).get(RecommendsViewModel::class.java)
}
@ -48,4 +49,11 @@ class RecommendsFragment : ListFragment<AnswerEntity, RecommendsViewModel>() {
mListRv.visibility = View.VISIBLE
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -42,7 +42,6 @@ class UnansweredAdapter(context: Context,
if (holder is CommunityQuestionViewHolder) {
val questions = mEntityList[position]
holder.bindQuestionViewHolder(questions, mEntrance, mPath)
holder.binding.endDesc.setOnClickListener { holder.itemView.performClick() }
holder.itemView.setOnClickListener {
mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.id, mEntrance, mPath, mSpecialColumn))
}

View File

@ -21,6 +21,9 @@ import butterknife.BindView
import butterknife.OnClick
import butterknife.Optional
import com.gh.base.fragment.BaseDialogWrapperFragment
import com.gh.common.syncpage.SyncDataEntity
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.common.view.VerticalItemDecoration
import com.gh.gamecenter.R
@ -93,6 +96,17 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
mCommentListener?.onCommentDraftChange("")
}
commentEt.postDelayed({ setSoftInput(false) }, 100)
if (mCommentType == CommentType.COMMUNITY_ARTICLE) {
SyncPageRepository.postSyncData(SyncDataEntity(mArticleId,
SyncFieldConstants.ARTICLE_COMMENT_COUNT,
mCommentCount,
checkFieldEntity = true))
} else if (mCommentType == CommentType.ANSWER) {
SyncPageRepository.postSyncData(SyncDataEntity(mAnswerId,
SyncFieldConstants.ANSWER_COMMENT_COUNT,
mCommentCount))
}
}
apiResponse.httpException != null -> {
mSendingDialog?.dismiss()

View File

@ -4,11 +4,14 @@ import android.content.Context
import android.webkit.JavascriptInterface
import com.gh.base.BaseActivity
import com.gh.common.AppExecutor
import com.gh.common.DefaultJsApi
import com.gh.common.util.DirectUtils
import com.gh.common.util.GsonUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.tryWithDefaultCatch
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.MtaEvent
import com.gh.gamecenter.entity.MyVideoEntity
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
@ -21,7 +24,8 @@ import com.lightgame.utils.Utils
*/
class OnLinkClickListener(val context: Context,
val entrance: String,
val path: String) {
val path: String,
val mtaEvent: MtaEvent? = null) {
@JavascriptInterface
fun onClick(content: String) {
AppExecutor.uiExecutor.execute {
@ -58,6 +62,7 @@ class OnLinkClickListener(val context: Context,
fun onVideoClick(content: String) {
AppExecutor.uiExecutor.execute {
tryWithDefaultCatch {
if (mtaEvent != null) MtaHelper.onEvent(mtaEvent.name, mtaEvent.key, mtaEvent.value)
val videoEntity = GsonUtils.fromJson(content, MyVideoEntity::class.java)
if (videoEntity.status == "pass") {
DirectUtils.directToVideoDetail(context,

View File

@ -7,6 +7,9 @@ import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.gh.common.annotation.SyncIgnore
import com.gh.common.annotation.SyncPage
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.entity.MeEntity
import com.gh.gamecenter.entity.UserEntity
import com.gh.gamecenter.room.converter.AnswerUserConverter
@ -25,8 +28,11 @@ class AnswerEntity() : Parcelable {
@PrimaryKey
var primaryKey: String = "" // db key
var communityId: String? = null // communityId + userId 社区推荐数据库存储专用,社区推荐接口不能给该字段
@Ignore
@SerializedName("community_id")
var communityId: String? = null // 社区推荐接口不能给该字段,否则和数据库分类(根据社区分类)数据有冲突
var articleCommunityId: String = "" // 一般情况,只有该数据是文章时接口才会给该字段
var orderTag: Long = 0
@ -47,11 +53,13 @@ class AnswerEntity() : Parcelable {
@TypeConverters(CommunityVideoConverter::class)
var videos: List<CommunityVideoEntity> = ArrayList()
@SyncPage(syncNames = [SyncFieldConstants.ANSWER_VOTE_COUNT, SyncFieldConstants.ARTICLE_VOTE_COUNT])
var vote: Int = 0
@TypeConverters(AnswerUserConverter::class)
var user: UserEntity = UserEntity()
@SyncIgnore // questions里的vote当前entity的vote冲突
@TypeConverters(QuestionsConverter::class)
@SerializedName("question")
var questions: Questions = Questions()
@ -59,6 +67,7 @@ class AnswerEntity() : Parcelable {
@SerializedName("community_name")
var communityName: String? = null
@SyncPage(syncNames = [SyncFieldConstants.ANSWER_COMMENT_COUNT, SyncFieldConstants.ARTICLE_COMMENT_COUNT])
@SerializedName("comment_count")
var commentCount: Int = 0
@ -87,7 +96,7 @@ class AnswerEntity() : Parcelable {
constructor(parcel: Parcel) : this() {
primaryKey = parcel.readString()
communityId = parcel.readString()
articleCommunityId = parcel.readString()
orderTag = parcel.readLong()
id = parcel.readString()
brief = parcel.readString()
@ -105,7 +114,7 @@ class AnswerEntity() : Parcelable {
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(primaryKey)
parcel.writeString(communityId)
parcel.writeString(articleCommunityId)
parcel.writeLong(orderTag)
parcel.writeString(id)
parcel.writeString(brief)

View File

@ -5,6 +5,8 @@ import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.gh.common.annotation.SyncPage
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.MeEntity
import com.gh.gamecenter.entity.UserEntity
@ -69,7 +71,9 @@ data class ArticleEntity(
@Parcelize
data class Count(
@SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_COUNT])
var comment: Int = 0,
@SyncPage(syncNames = [SyncFieldConstants.ARTICLE_VOTE_COUNT])
var vote: Int = 0,
var answer: Int = 0) : Parcelable

View File

@ -68,12 +68,14 @@ class AskFollowAdapter(val context: Context, val viewModel: AskFollowViewModel)
userDesc.text = highlightedString
userDesc.visibility = View.VISIBLE
userDesc.setOnClickListener {
val dialog = AskFollowMoreDialog().apply {
userList = ArrayList(historyEntity.foldUsers)
this.type = "赞同$type"
this.path = "问答首页-关注折叠"
debounceActionWithInterval(userDesc.id, 1000) {
val dialog = AskFollowMoreDialog().apply {
userList = ArrayList(historyEntity.foldUsers)
this.type = "赞同$type"
this.path = "问答首页-关注折叠"
}
dialog.show((context as AppCompatActivity).supportFragmentManager, "more")
}
dialog.show((context as AppCompatActivity).supportFragmentManager, "more")
}
userCommand.text = "赞同了$type"
} else {

View File

@ -65,7 +65,6 @@ public class AskQuestionsNewBodyAdapter extends ListAdapter<Questions> {
case ItemViewType.ITEM_BODY:
Questions questions = mEntityList.get(position);
((CommunityQuestionViewHolder) holder).bindQuestionViewHolder(questions, mEntrance, "问答-问题");
((CommunityQuestionViewHolder) holder).getBinding().endDesc.setOnClickListener(v -> holder.itemView.performClick());
holder.itemView.setOnClickListener(v -> mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.getId(), mEntrance, "问答-问题")));
break;
case ItemViewType.ITEM_FOOTER:

View File

@ -1,5 +1,8 @@
package com.gh.gamecenter.qa.questions
import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.NewsUtils
@ -11,6 +14,7 @@ import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.lightgame.utils.Utils
class CommunityQuestionViewHolder(val binding: CommunityQuestionItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
@ -24,6 +28,7 @@ class CommunityQuestionViewHolder(val binding: CommunityQuestionItemBinding) : B
binding.endDesc.text = questions.communityName
}
@SuppressLint("ClickableViewAccessibility")
private fun bindViewHolder(questions: Questions, entrance: String, path: String) {
binding.title.text = questions.title
if (questions.answerCount > 0) {
@ -38,16 +43,28 @@ class CommunityQuestionViewHolder(val binding: CommunityQuestionItemBinding) : B
"回答")
}
binding.answerCountContainer.setOnClickListener {
if (questions.answerCount > 0) {
itemView.context.startActivity(QuestionsDetailActivity.getIntent(itemView.context, questions.id, entrance, path))
} else {
// 虽然很丑陋但是没有想到其它好的办法实现https://gitlab.ghzs.com/pm/halo-app-issues/issues/812 (7)
if (questions.answerCount <= 0 && questions.me.myAnswerId.isNullOrEmpty()) {
binding.answerCountContainer.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_MOVE) {
binding.answerCountContainer.setBackgroundResource(R.drawable.reuse_listview_item_style)
} else {
binding.answerCountContainer.background = null
}
false
}
binding.answerCountContainer.setOnClickListener {
CheckLoginUtils.checkLogin(itemView.context, entrance) {
val communityName = if (questions.communityName.isNullOrEmpty()) UserManager.getInstance().community.name
else questions.communityName
itemView.context.startActivity(AnswerEditActivity.getIntent(itemView.context, questions, communityName))
}
}
binding.answerCountContainer.isClickable = true
} else {
binding.answerCountContainer.isClickable = false
binding.answerCountContainer.setOnTouchListener(null)
}
}
}

View File

@ -16,6 +16,7 @@ import butterknife.BindView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.base.OnListClickListener
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.*
import com.gh.common.view.DrawableView
import com.gh.gamecenter.R
@ -27,6 +28,7 @@ import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.InviteEntity
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
import com.gh.gamecenter.qa.questions.invite.QuestionsInviteAdapter
@ -38,7 +40,7 @@ class QuestionsDetailAdapter(
private var mListClickListener: OnListClickListener,
private var mQuestionEntity: QuestionsDetailEntity? = null,
private val mViewModel: QuestionsDetailViewModel,
private val mEntrance: String) : ListAdapter<QuestionDetailItemData>(context) {
private val mEntrance: String) : ListAdapter<QuestionDetailItemData>(context), ISyncAdapterHandler {
private var mIsNoneData: Boolean = false
@ -415,6 +417,16 @@ class QuestionsDetailAdapter(
}
}
override fun getSyncData(position: Int): Pair<String, AnswerEntity>? {
val index = position - TOP_ITEM_COUNT
if (index < 0 || index >= mEntityList.size) return null
val itemData = mEntityList[index]
var entity = itemData.answer
if (entity == null) entity = itemData.similarAnswer
if (entity == null) return null
return Pair(entity.id ?: "", entity)
}
class SimpleInviteAdapter(context: Context, onListClickListener: OnListClickListener, entrance: String)
: QuestionsInviteAdapter(context, onListClickListener, entrance, "问题详情-邀请列表") {
override fun getItemViewType(position: Int): Int {

View File

@ -301,9 +301,9 @@ class QuestionsDetailFragment :
}
R.id.questionsdetail_concern, R.id.questionsdetail_concern_container -> CheckLoginUtils.checkLogin(context, "问题详情-[关注问题]") {
if (mQuestionsDetailEntity!!.me.isContentOwner) {
startActivityForResult(QuestionEditActivity.getIntent(context!!, mQuestionsDetailEntity!!), QUESTIONS_EDIT_REQUEST)
startActivityForResult(QuestionEditActivity.getIntent(requireContext(), mQuestionsDetailEntity!!), QUESTIONS_EDIT_REQUEST)
} else if (!mQuestionsDetailEntity!!.me.isQuestionFollowed) {
ConcernUtils.postConcernQuestions(context!!, mQuestionsId!!, object : ConcernUtils.onConcernListener {
ConcernUtils.postConcernQuestions(requireContext(), mQuestionsId!!, object : ConcernUtils.onConcernListener {
override fun onSuccess() {
mQuestionsDetailEntity!!.me.isQuestionFollowed = true
mQuestionsDetailEntity!!.setFollowCount(mQuestionsDetailEntity!!.getFollowCount() + 1)
@ -381,7 +381,7 @@ class QuestionsDetailFragment :
R.id.menu_more -> showMoreItemDialog()
R.id.menu_question_and_answer -> {
HaloApp.remove(GAME_DETAIL_COME_IN)
DirectUtils.directToCommunity(context!!, it.community)
DirectUtils.directToCommunity(requireContext(), it.community)
LogUtils.qaAccess("问题详情-进入问答", it.community)
MtaHelper.onEvent("进入问答", "问题详情", it.community.name + "+" + StringUtils.combineTwoString(it.title, it.id))
}
@ -511,7 +511,7 @@ class QuestionsDetailFragment :
itemTv.setBackgroundResource(R.drawable.textview_white_style)
itemTv.layoutParams = LinearLayout.LayoutParams(widthPixels * 9 / 10,
LinearLayout.LayoutParams.WRAP_CONTENT)
itemTv.setPadding(DisplayUtils.dip2px(context!!, 20f), pad, 0, pad)
itemTv.setPadding(DisplayUtils.dip2px(requireContext(), 20f), pad, 0, pad)
container.addView(itemTv)
itemTv.setOnClickListener {
@ -644,6 +644,14 @@ class QuestionsDetailFragment :
return super.onBackPressed()
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
companion object {
const val QUESTIONS_DETAIL_ANSWER_REQUEST = 110
const val QUESTIONS_EDIT_REQUEST = 111

View File

@ -5,12 +5,14 @@ import android.content.Context;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import kotlin.Pair;
import android.view.View;
import android.view.ViewGroup;
import com.gh.base.OnListClickListener;
import com.gh.common.constant.ItemViewType;
import com.gh.common.syncpage.ISyncAdapterHandler;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.MtaHelper;
import com.gh.gamecenter.R;
@ -27,6 +29,8 @@ import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@ -34,7 +38,7 @@ import java.util.List;
* Created by khy on 2/12/17.
*/
public class AskQuestionsRecommendsAdapter extends ListAdapter<RecommendItemData> {
public class AskQuestionsRecommendsAdapter extends ListAdapter<RecommendItemData> implements ISyncAdapterHandler {
private OnListClickListener mListClickListener;
private AskQuestionsRecommendsViewModel mListViewModel;
@ -187,4 +191,13 @@ public class AskQuestionsRecommendsAdapter extends ListAdapter<RecommendItemData
public boolean isOver() {
return mIsOver;
}
@Nullable
@Override
public Pair<String, Object> getSyncData(int position) {
if (position >= mEntityList.size()) return null;
AnswerEntity entity = mEntityList.get(position).getAnswer();
if (entity != null) return new Pair(entity.getId(), entity);
return null;
}
}

View File

@ -26,13 +26,8 @@ import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBTypeChange;
import com.gh.gamecenter.eventbus.EBUserFollow;
import com.gh.gamecenter.fragment.MainWrapperFragment;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.CommunityFragment;
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity;
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.qa.questions.edit.QuestionEditActivity;
import org.greenrobot.eventbus.EventBus;
@ -289,4 +284,15 @@ public class AskQuestionsRecommendsFragment extends ListFragment<RecommendItemDa
}
return parentFragment;
}
@Nullable
@Override
protected RecyclerView.Adapter provideSyncAdapter() {
return mAdapter;
}
@Override
protected boolean addSyncPageObserver() {
return true;
}
}

View File

@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
@ -16,8 +17,9 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.lightgame.utils.Utils
open class RecommendNewestAdapter(context: Context) : ListAdapter<AnswerEntity>(context) {
open class RecommendNewestAdapter(context: Context) : ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
override fun areItemsTheSame(oldItem: AnswerEntity?, newItem: AnswerEntity?): Boolean {
return oldItem?.id == newItem?.id
@ -88,4 +90,9 @@ open class RecommendNewestAdapter(context: Context) : ListAdapter<AnswerEntity>(
return "问答-推荐-按时间"
}
override fun getSyncData(position: Int): Pair<String, Any>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
}

View File

@ -29,7 +29,7 @@ class RecommendNewestFragment : ListFragment<AnswerEntity, NormalListViewModel<A
override fun provideListAdapter(): RecommendNewestAdapter {
if (mAdapter == null) {
mAdapter = RecommendNewestAdapter(context!!)
mAdapter = RecommendNewestAdapter(requireContext())
}
return mAdapter!!
}
@ -130,4 +130,12 @@ class RecommendNewestFragment : ListFragment<AnswerEntity, NormalListViewModel<A
return (parentFragment as? AskRecommendWrapperFragment)?.refreshLayout
?: DumbRefreshLayout(context)
}
override fun provideSyncAdapter(): RecyclerView.Adapter<*>? {
return mAdapter
}
override fun addSyncPageObserver(): Boolean {
return true
}
}

View File

@ -25,7 +25,7 @@ class ArticleFragment : BaseAskSearchFragment<ArticleEntity, NormalListViewModel
} else {
"问答-搜索-文章"
}
mAdapter = ArticleAdapter(context!!, mEntrance, path, mListViewModel)
mAdapter = ArticleAdapter(requireContext(), mEntrance, path, mListViewModel)
}
return mAdapter!!
}

View File

@ -1,7 +1,7 @@
package com.gh.gamecenter.qa.search.hottest
import androidx.lifecycle.ViewModelProviders
import android.text.TextUtils
import androidx.lifecycle.ViewModelProviders
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.manager.UserManager
@ -24,7 +24,7 @@ class HottestFragment : BaseAskSearchFragment<SearchHottestEntity, NormalListVie
} else {
"问答-搜索-最热"
}
mAdapter = HottestAdapter(context!!, mEntrance, path, mListViewModel)
mAdapter = HottestAdapter(requireContext(), mEntrance, path, mListViewModel)
}
return mAdapter!!
}

View File

@ -1,7 +1,7 @@
package com.gh.gamecenter.qa.search.newest
import androidx.lifecycle.ViewModelProviders
import android.text.TextUtils
import androidx.lifecycle.ViewModelProviders
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.manager.UserManager
@ -24,7 +24,7 @@ class NewestFragment : BaseAskSearchFragment<SearchNewestEntity, NormalListViewM
} else {
"问答-搜索-最新"
}
mAdapter = NewestAdapter(context!!, mEntrance, path, mListViewModel)
mAdapter = NewestAdapter(requireContext(), mEntrance, path, mListViewModel)
}
return mAdapter!!
}

View File

@ -1,7 +1,7 @@
package com.gh.gamecenter.qa.search.question
import androidx.lifecycle.ViewModelProviders
import android.text.TextUtils
import androidx.lifecycle.ViewModelProviders
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.manager.UserManager
@ -24,7 +24,7 @@ class QuestionFragment : BaseAskSearchFragment<Questions, NormalListViewModel<Qu
} else {
"问答-搜索-问题"
}
mAdapter = QuestionAdapter(context!!, mEntrance, path, mListViewModel)
mAdapter = QuestionAdapter(requireContext(), mEntrance, path, mListViewModel)
}
return mAdapter!!
}

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