Compare commits

..

2 Commits

Author SHA1 Message Date
811e1bf875 tinker_base-3.7.3-splash 2020-02-19 17:17:59 +08:00
5c929ba308 更换引导图 2020-02-19 16:46:08 +08:00
510 changed files with 5747 additions and 9235 deletions

View File

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

View File

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

View File

@ -2,7 +2,6 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

@ -178,23 +178,12 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
@Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
onFinish();
}
}
@Override
protected void onResume() {
super.onResume();
}
/**
* 可凭借此回调确定当前 activity 已经执行了 finish() 处于 isFinishing 状态
* 可在后续进行
*/
protected void onFinish() {
}
@Override
public void onRequestPermissionsResult(int requestCode,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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;
@ -203,13 +202,8 @@ public class ShareUtils {
popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
//解决PopupWindow无法覆盖状态栏
popupWindow.setClippingEnabled(false);
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
if (!DisplayUtils.isNavigationBarShow(activity)) {
bottomLocation = 0;
}
try {
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
} catch (Exception e) {
e.printStackTrace();
}
@ -274,15 +268,8 @@ public class ShareUtils {
popupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.MATCH_PARENT, true);
popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
//解决PopupWindow无法覆盖状态栏
popupWindow.setClippingEnabled(false);
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
if (!DisplayUtils.isNavigationBarShow(activity)) {
bottomLocation = 0;
}
try {
// popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
} catch (Exception e) {
e.printStackTrace();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -243,17 +243,6 @@ public class DownloadManager implements DownloadStatusListener {
}
}
// 插件版本下载互斥弹窗
List<String> mutexPackage = gameEntity.getMutexPackage();
if (mutexPackage != null && mutexPackage.size() > 0) {
for (String pkg : mutexPackage) {
if (PackagesManager.isInstalled(pkg)) {
DialogUtils.showDownloadMutexDialog(context);
break;
}
}
}
DownloadEntity downloadEntity = new DownloadEntity();
downloadEntity.setUrl(apkEntity.getUrl());
downloadEntity.setName(gameEntity.getName());
@ -650,7 +639,7 @@ public class DownloadManager implements DownloadStatusListener {
Intent serviceIntent = new Intent(mContext, DownloadService.class);
// 当满足系统版本大于 8.0 、应用在后台运行时以前台服务开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !HaloApp.getInstance().isRunningForeground) {
&& !HaloApp.getInstance().isRunningForeground) {
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
mContext.startForegroundService(serviceIntent);
} else {
@ -745,7 +734,7 @@ public class DownloadManager implements DownloadStatusListener {
public void markDownloadedTaskAsRead() {
AppExecutor.getIoExecutor().execute(() -> {
boolean markHasChanged = false;
List<DownloadEntity> all = getAll();
for (DownloadEntity downloadEntity : all) {
DownloadStatus status = downloadEntity.getStatus();
@ -758,20 +747,20 @@ public class DownloadManager implements DownloadStatusListener {
}
}
}
if (markHasChanged) {
EventBus.getDefault().post(new EBDownloadStatus("download", "", "", "", "", ""));
}
});
}
/**
* 标记可用更新为已读 (用于下载管理页入口的 toolbar 红点显示)
*/
public void markUpdatableTaskAsRead() {
AppExecutor.getIoExecutor().execute(() -> {
boolean markHasChanged = false;
ArrayList<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
for (GameUpdateEntity update : updates) {
String mark = update.getId() + update.getPackageName();
@ -780,7 +769,7 @@ public class DownloadManager implements DownloadStatusListener {
if (!markHasChanged) markHasChanged = true;
}
}
if (markHasChanged) {
saveUpdateMarkToStorage();
EventBus.getDefault().post(new EBDownloadStatus("download", "", "", "", "", ""));

View File

@ -226,14 +226,9 @@ public class CacheManager {
}
private List<File> getAllFile() {
try {
if (cacheDirectory.exists() && cacheDirectory.isDirectory()) {
File[] files = cacheDirectory.listFiles();
return Arrays.asList(files);
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
if (cacheDirectory.exists()) {
File[] files = cacheDirectory.listFiles();
return Arrays.asList(files);
}
return new ArrayList<>();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,8 +11,6 @@ import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
@ -26,7 +24,6 @@ import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.request.ImageRequest;
import com.gh.base.BaseActivity;
import com.gh.common.AppExecutor;
import com.gh.common.Base64ImageHolder;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.EntranceUtils;
@ -46,7 +43,6 @@ import com.github.piasy.biv.view.BigImageView;
import com.github.piasy.biv.view.FrescoImageViewFactory;
import com.lightgame.utils.Utils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -291,35 +287,15 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
}
});
}
private void loadImage(String url, final BigImageView imageView) {
if (TextUtils.isEmpty(url)) return;
if (url.startsWith("data:image/png;base64")) {
AppExecutor.getIoExecutor().execute(() -> {
String base64String = url.replace("data:image/png;base64", "");
try {
File imageFile = new File(getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".png");
byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile));
bos.write(decodedString);
bos.flush();
bos.close();
AppExecutor.getUiExecutor().execute(() -> {
imageView.setImageViewFactory(new FrescoImageViewFactory());
imageView.showImage(Uri.fromFile(imageFile));
});
} catch (Exception e) {
e.printStackTrace();
}
});
} else {
// 添加GIF支持
// 添加GIF支持
try {
imageView.setImageViewFactory(new FrescoImageViewFactory());
imageView.showImage(Uri.parse(url));
} catch (Exception ignored) {
// parse Uri 可能会有异常 java.lang.NullPointerException
// url 为 null? 暂时不管了,统一捕抓异常
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,13 +4,18 @@ import android.view.View;
import com.gh.common.history.HistoryDatabase;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.baselist.ListAdapter;
import com.gh.gamecenter.baselist.ListFragment;
import com.gh.gamecenter.baselist.LoadType;
import com.gh.gamecenter.baselist.NormalListViewModel;
import com.gh.gamecenter.eventbus.EBCollectionChanged;
import com.gh.gamecenter.manager.UserManager;
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
import com.gh.gamecenter.retrofit.RetrofitManager;
import org.greenrobot.eventbus.Subscribe;
@ -18,14 +23,13 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.Single;
/**
* Created by khy on 22/12/17.
*/
public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel> {
public class AnswerFragment extends ListFragment<AnswerEntity, NormalListViewModel> {
private AnswerAdapter mAdapter;
private Type mType;
@ -38,7 +42,7 @@ public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel>
@Override
protected ListAdapter provideListAdapter() {
return mAdapter == null ? mAdapter = new AnswerAdapter(getContext(), mListViewModel, mType, this, mEntrance) : mAdapter;
return mAdapter == null ? mAdapter = new AnswerAdapter(getContext(), this, mEntrance) : mAdapter;
}
@Override
@ -51,19 +55,49 @@ public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel>
}
@Override
protected AnswerViewModel provideListViewModel() {
AnswerViewModel viewModel = ViewModelProviders.of(this).get(AnswerViewModel.class);
viewModel.setType(mType);
return viewModel;
public void onListClick(View view, int position, Object data) {
AnswerEntity entity;
switch (view.getId()) {
case R.id.footerview_item:
if (mAdapter.isNetworkError()) {
mListViewModel.load(LoadType.RETRY);
}
break;
case R.id.ask_answer_item_constraintlayout:
case R.id.ask_answer_item_content:
entity = (AnswerEntity) data;
if (entity.getActive()) {
startActivity(AnswerDetailActivity.getIntent(getContext(), entity.getId(), mEntrance, "我的收藏-回答"));
} else {
showDeleteDialog(entity.getId());
}
break;
case R.id.ask_answer_item_title:
entity = (AnswerEntity) data;
Questions questions = entity.getQuestions();
startActivity(QuestionsDetailActivity.getIntent(getContext(), questions.getId(), mEntrance, "我的收藏-回答"));
break;
}
}
@Override
public void onListClick(View view, int position, Object data) {
if (view.getId() == R.id.footerview_item) {
if (mAdapter.isNetworkError()) {
mListViewModel.load(LoadType.RETRY);
}
}
private void showDeleteDialog(String answerId) {
DialogUtils.showCancelAlertDialog(getContext(), "提示"
, "内容已被删除,是否取消收藏?"
, "取消收藏", "暂不"
, () -> CollectionUtils.INSTANCE.deleteCollection(getContext(), answerId
, CollectionUtils.CollectionType.answer, new CollectionUtils.OnCollectionListener() {
@Override
public void onSuccess() {
toast(R.string.collection_cancel);
mListViewModel.load(LoadType.REFRESH);
}
@Override
public void onError() {
toast(R.string.collection_cancel_failure);
}
}), null);
}
// 收藏事件
@ -77,8 +111,6 @@ public class AnswerFragment extends ListFragment<AnswerEntity, AnswerViewModel>
public enum Type {
COLLECTION,
COLLECTION_ANSWER,
HISTORY
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -389,7 +389,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
}
DownloadManager.getInstance(getContext()).pauseAll();
mDownloadmanagerAllstartTv.setText("全部开始");
mDownloadmanagerAllstartTv.setTextColor(ContextCompat.getColor(getContext(), R.color.theme_font));
mDownloadmanagerAllstartTv.setTextColor(ContextCompat.getColor(getContext(), R.color.theme));
}
private void startAll() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,6 @@ import com.gh.common.exposure.IExposable
import com.gh.common.util.*
import com.gh.gamecenter.BlockActivity
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.ImagePagerAdapter
import com.gh.gamecenter.adapter.viewholder.*
@ -109,14 +108,10 @@ class GameFragmentAdapter(context: Context,
GameHorizontalSlideListViewHolder(binding)
}
ItemViewType.GAME_NORMAL -> {
val binding = GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false))
if (mContext is MainActivity) binding.gameIcon.setTag(R.id.tag_show_gif, false)
GameItemViewHolder(binding)
GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false)))
}
ItemViewType.GAME_IMAGE -> {
val binding = GameImageItemBinding.bind(mLayoutInflater.inflate(R.layout.game_image_item, parent, false))
if (mContext is MainActivity) binding.gameIcon.setTag(R.id.tag_show_gif, false)
GameImageViewHolder(binding)
GameImageViewHolder(GameImageItemBinding.bind(mLayoutInflater.inflate(R.layout.game_image_item, parent, false)))
}
ItemViewType.COLUMN_HEADER -> {
GameHeadViewHolder(GameHeadItemBinding.bind(mLayoutInflater.inflate(R.layout.game_head_item, parent, false)))
@ -196,7 +191,7 @@ class GameFragmentAdapter(context: Context,
val verticalSlide = mItemDataList[position].verticalSlide!!
val binding = holder.binding
val snapHelper = holder.bindVerticalSlide(verticalSlide, clickClosure, mContext !is MainActivity)
val snapHelper = holder.bindVerticalSlide(verticalSlide, clickClosure)
val exposureEventList = arrayListOf<ExposureEvent>()
val exposureClosure: (Int) -> Unit = {
@ -250,12 +245,12 @@ class GameFragmentAdapter(context: Context,
DirectUtils.directToLinkPage(mContext, linkEntity, "(游戏-专题:" + entity?.name + "-大图)", "首页游戏")
}
holder.bindImageSlide(entity!!, imageClickListener, "游戏-专题", mContext !is MainActivity)
holder.bindImageSlide(entity!!, imageClickListener, "游戏-专题")
}
private fun bindGameHorizontalListView(holder: GameHorizontalListViewHolder, position: Int) {
val subjectEntity = mItemDataList[position].horizontalColumn
val subjectAdapter = holder.bindHorizontalList(subjectEntity!!, mContext !is MainActivity)
val subjectAdapter = holder.bindHorizontalList(subjectEntity!!)
if (subjectEntity.type != "game_horizontal") {
holder.binding.horizontalRv.doOnScrolledSpecificDistance(distanceX = DisplayUtils.dip2px(24f), singleTimeEvent = true) {
@ -266,44 +261,41 @@ class GameFragmentAdapter(context: Context,
val exposureEventList = arrayListOf<ExposureEvent>()
subjectEntity.data?.let {
val positionOffset = subjectAdapter.getIndex()
tryCatchInRelease {
for (i in positionOffset until subjectAdapter.itemCount + positionOffset) {
// TODO 不知为何 i 会比专题 size 大
if (i > it.size) break
// java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
it[i].sequence = i
val event = ExposureEvent.createEvent(gameEntity = it[i],
source = listOf(mBasicExposureSource, ExposureSource("专题", subjectEntity.name!!)),
eTrace = null,
event = ExposureType.EXPOSURE)
exposureEventList.add(event)
}
mItemDataList[position].exposureEventList = exposureEventList
subjectAdapter.exposureEventList = exposureEventList
for (i in positionOffset until subjectAdapter.itemCount + positionOffset) {
// TODO 不知为何 i 会比专题 size 大
if (i > it.size) break
it[i].sequence = i
val event = ExposureEvent.createEvent(gameEntity = it[i],
source = listOf(mBasicExposureSource, ExposureSource("专题", subjectEntity.name!!)),
eTrace = null,
event = ExposureType.EXPOSURE)
exposureEventList.add(event)
}
mItemDataList[position].exposureEventList = exposureEventList
subjectAdapter.exposureEventList = exposureEventList
}
}
private fun bindGameHorizontalSlideListView(holder: GameHorizontalSlideListViewHolder, position: Int) {
val subjectEntity = mItemDataList[position].horizontalSlide
val subjectAdapter = holder.bindHorizontalSlideList(subjectEntity!!, mContext !is MainActivity)
val subjectAdapter = holder.bindHorizontalSlideList(subjectEntity!!)
val exposureEventList = arrayListOf<ExposureEvent>()
subjectEntity.data?.let {
val positionOffset = subjectAdapter.getIndex()
tryCatchInRelease {
for (i in positionOffset until subjectAdapter.itemCount + positionOffset) {
it[i].sequence = i
val event = ExposureEvent.createEvent(gameEntity = it[i],
source = listOf(mBasicExposureSource, ExposureSource("专题", subjectEntity.name!!)),
eTrace = null,
event = ExposureType.EXPOSURE)
exposureEventList.add(event)
}
mItemDataList[position].exposureEventList = exposureEventList
subjectAdapter.exposureEventList = exposureEventList
for (i in positionOffset until subjectAdapter.itemCount + positionOffset) {
it[i].sequence = i
val event = ExposureEvent.createEvent(gameEntity = it[i],
source = listOf(mBasicExposureSource, ExposureSource("专题", subjectEntity.name!!)),
eTrace = null,
event = ExposureType.EXPOSURE)
exposureEventList.add(event)
}
mItemDataList[position].exposureEventList = exposureEventList
subjectAdapter.exposureEventList = exposureEventList
}
}
@ -328,8 +320,7 @@ class GameFragmentAdapter(context: Context,
val linkEntity = LinkEntity()
linkEntity.link = link
linkEntity.type = entity.type
DirectUtils.directToLinkPage(mContext, linkEntity, "(游戏-专题:$name-大图)", mViewModel.blockData?.name
?: "", mItemDataList[position].exposureEvent)
DirectUtils.directToLinkPage(mContext, linkEntity, "(游戏-专题:$name-大图)", mViewModel.blockData?.name ?: "", mItemDataList[position].exposureEvent)
}
}
@ -607,11 +598,6 @@ class GameFragmentAdapter(context: Context,
return mItemDataList[pos].exposureEventList
}
fun getItemDataByPosition(position: Int): GameItemData? {
if (position >= mItemDataList.size) return null
return mItemDataList[position]
}
}
data class GameAndPosition(val entity: GameEntity?, val position: Int, val index: Int = 0)

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