Merge branch 'dev' into merge_dev_to_dev-5.33.0
# Conflicts: # app/src/main/java/com/gh/common/databind/BindingAdapters.java # app/src/main/java/com/gh/gamecenter/cloudarchive/CloudArchiveManagerActivity.kt # app/src/main/java/com/gh/gamecenter/cloudarchive/CloudArchiveManagerViewModel.kt # app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt # app/src/main/java/com/gh/gamecenter/gamedetail/fuli/kaifu/ServersDetailReportViewHolder.kt # app/src/main/java/com/gh/gamecenter/gamedetail/fuli/kaifu/ServersDetailViewHolder.kt # app/src/main/java/com/gh/vspace/VHelper.kt # app/src/main/res/layout/dialog_servers_calendear_detail.xml # app/src/main/res/layout/dialog_servers_calendear_detail_item.xml # app/src/main/res/layout/dialog_servers_calendear_detail_report.xml # module_common/src/main/res/drawable/download_button_normal_style.xml
This commit is contained in:
@ -22,6 +22,7 @@ import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.ActionMenuView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
@ -59,7 +60,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
|
||||
protected TextView mAdLabelTv;
|
||||
|
||||
protected LinearLayout mTitleContainer;
|
||||
protected ConstraintLayout mTitleContainer;
|
||||
|
||||
protected LinearLayout mIconTitleContainer;
|
||||
|
||||
|
||||
@ -74,10 +74,14 @@ public class Constants {
|
||||
|
||||
public static final String EXTRA_DOWNLOAD_TYPE = "extra_download_type";
|
||||
public static final String SILENT_UPDATE = "静默更新";
|
||||
public static final String SILENT_DOWNLOAD = "silent_download"; // 静默下载(不需要显示在下载管理里)
|
||||
public static final String SIMULATOR_DOWNLOAD = "下载模拟器";
|
||||
public static final String SIMULATOR_GAME = "simulator_game";
|
||||
public static final String SIMULATOR = "simulator";
|
||||
public static final String SMOOTH_GAME = "smooth_game"; // 畅玩类型的游戏
|
||||
public static final String VGAME = "smooth_game"; // 畅玩类型的游戏
|
||||
|
||||
public static final String DUAL_DOWNLOAD_VGAME = "dual_download_vgame"; // 双下载模式,触发的时候是畅玩
|
||||
public static final String DUAL_DOWNLOAD_LOCAL = "dual_download_local"; // 双下载模式,触发的时候是普通游戏
|
||||
public static final String VSPACE_32_DOWNLOAD_ONLY = "vspace_32_download_only"; // 仅下载32位畅玩助手,不跳转安装
|
||||
public static final String GAME_NAME = "game_name";
|
||||
public static final String GAME_CATEGORY = "game_category"; // 游戏类型
|
||||
@ -489,4 +493,8 @@ public class Constants {
|
||||
|
||||
public static final String SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE = "show_community_home_video_guide";
|
||||
public static final String SP_COMMUNITY_HOME_VIDEO_LOTTIE_LAST_PLAY_TIME = "community_home_video_lottie_last_play_time";
|
||||
|
||||
public static final String SP_SERVERS_CALENDAR_BY_APP = "servers_calendar_by_app";
|
||||
|
||||
public static final String SP_SERVERS_CALENDAR_BY_WECHAT = "servers_calendar_by_wechat";
|
||||
}
|
||||
|
||||
@ -228,6 +228,7 @@ public class EntranceConsts {
|
||||
public static final String KEY_ARTICLE_OPEN_IN_NEW_PAGE = "openArticleInNewPage";
|
||||
public static final String KEY_ONLY_CREATE_DRAFT = "onlyCreateDraft";
|
||||
public static final String KEY_KAIFU_SELECT_TIME = "kaifuSelectTime";
|
||||
public static final String KEY_KAIFU_TIME = "kaifuTime";
|
||||
public static final String KEY_POSTER_PATH = "posterPath";
|
||||
public static final String KEY_BLACK_THEME = "blackTheme";
|
||||
public static final String KEY_FROM_LOGIN = "fromLogin";
|
||||
@ -306,4 +307,10 @@ public class EntranceConsts {
|
||||
public static final String KEY_SHOW_DOWNLOAD_MENU = "show_download_menu";
|
||||
public static final String KEY_IS_FROM_MAIN_WRAPPER = "is_from_main_wrapper";
|
||||
public static final String KEY_IS_FROM_HOME_TOOLBAR_WRAPPER = "is_from_home_toolbar_wrapper";
|
||||
public static final String KEY_SHOW_REMIND = "show_remind";
|
||||
public static final String KEY_CALENDAR_YEAR = "calendar_year";
|
||||
public static final String KEY_CALENDAR_MONTH = "calendar_month";
|
||||
public static final String KEY_CALENDAR_DAY = "calendar_day";
|
||||
|
||||
public static final String KEY_SERVER_CALENDAR_ID = "server_calendar_id";
|
||||
}
|
||||
|
||||
@ -90,6 +90,10 @@ class ExposureEntity(
|
||||
var country: String = "",
|
||||
var province: String = "",
|
||||
var city: String = "",
|
||||
@SerializedName("ad_space_id")
|
||||
var adSpaceId: String = "", // 广告位ID
|
||||
@SerializedName("game_ad_source_id")
|
||||
var gameAdSourceId: String = "", // 广告源计划ID
|
||||
) : Parcelable {
|
||||
|
||||
fun setContainerInfo(id: String?, type: String?) {
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
package com.gh.gamecenter.common.livedata
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
|
||||
/**
|
||||
* “非粘性”状态的MutableLiveData,支持用于事件传递,可避免数据倒灌等情况发生
|
||||
* 主要特点是observe方法被调用时,不会回调onChanged事件
|
||||
*/
|
||||
class NonStickyMutableLiveData<T> : MutableLiveData<T> {
|
||||
constructor(): super()
|
||||
|
||||
constructor(value: T): super(value)
|
||||
|
||||
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
|
||||
hook(observer)
|
||||
super.observe(owner, observer)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过反射保持Observer的mLastVersion值与LiveData的值相同, 实现LiveData的“非粘性”状态
|
||||
* @param observer observer实例
|
||||
*/
|
||||
private fun hook(observer: Observer<*>) {
|
||||
val classLiveData = LiveData::class.java
|
||||
val fieldObservers: Field = classLiveData.getDeclaredField("mObservers")
|
||||
fieldObservers.isAccessible = true
|
||||
val objectObservers: Any = fieldObservers.get(this) ?: return
|
||||
val classObservers: Class<*> = objectObservers.javaClass
|
||||
val methodGet: Method = classObservers.getDeclaredMethod("get", Any::class.java)
|
||||
methodGet.isAccessible = true
|
||||
val objectWrapperEntry: Any = methodGet.invoke(objectObservers, observer) ?: return
|
||||
var objectWrapper: Any? = null
|
||||
if (objectWrapperEntry is Map.Entry<*, *>) {
|
||||
objectWrapper = objectWrapperEntry.value
|
||||
}
|
||||
if (objectWrapper == null) {
|
||||
throw NullPointerException("Wrapper can not be bull!")
|
||||
}
|
||||
val classObserverWrapper: Class<*> = objectWrapper.javaClass.superclass ?: return
|
||||
val fieldLastVersion: Field = classObserverWrapper.getDeclaredField("mLastVersion")
|
||||
fieldLastVersion.isAccessible = true
|
||||
//get livedata's version
|
||||
val fieldVersion: Field = classLiveData.getDeclaredField("mVersion")
|
||||
fieldVersion.isAccessible = true
|
||||
val objectVersion: Any = fieldVersion.get(this) ?: return
|
||||
//set wrapper's version
|
||||
fieldLastVersion.set(objectWrapper, objectVersion)
|
||||
}
|
||||
}
|
||||
@ -1061,8 +1061,37 @@ fun DownloadEntity.isSimulatorGame(): Boolean {
|
||||
return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty()
|
||||
}
|
||||
|
||||
fun DownloadEntity.isVGame(): Boolean {
|
||||
return Constants.SMOOTH_GAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
fun DownloadEntity.asVGame(): Boolean {
|
||||
return Constants.VGAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
|| Constants.DUAL_DOWNLOAD_VGAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载时触发的是双下载模式里的畅玩下载
|
||||
*/
|
||||
fun DownloadEntity.isVGameDownloadInDualDownloadMode(): Boolean {
|
||||
return Constants.DUAL_DOWNLOAD_VGAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载时触发的是双下载模式里的普通下载
|
||||
*/
|
||||
fun DownloadEntity.isLocalDownloadInDualDownloadMode(): Boolean {
|
||||
return Constants.DUAL_DOWNLOAD_LOCAL == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置触发时的下载模式为双下载模式里的普通下载
|
||||
*/
|
||||
fun DownloadEntity.setLocalDownloadModeInDualDownloadMode() {
|
||||
addMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE, Constants.DUAL_DOWNLOAD_LOCAL)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置触发时的下载模式为双下载模式里的畅玩下载
|
||||
*/
|
||||
fun DownloadEntity.setVGameDownloadModeInDualDownloadMode() {
|
||||
addMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE, Constants.DUAL_DOWNLOAD_VGAME)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1448,7 +1477,9 @@ fun ImageView.dimOnDarkMode() {
|
||||
* 修复WebView初次加载重置深色模式
|
||||
*/
|
||||
fun WebView.fixUiModeIfNeeded() {
|
||||
val configuration = context.resources.configuration
|
||||
val topContext = if (context is Activity) context else CurrentActivityHolder.getCurrentActivity() ?: return
|
||||
|
||||
val configuration = topContext.resources.configuration
|
||||
val configurationNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
||||
val appCompatNightMode = AppCompatDelegate.getDefaultNightMode()
|
||||
|
||||
@ -1466,9 +1497,9 @@ fun WebView.fixUiModeIfNeeded() {
|
||||
|
||||
if (newUiModeConfiguration != null) {
|
||||
@Suppress("DEPRECATION")
|
||||
context.resources.updateConfiguration(
|
||||
topContext.resources.updateConfiguration(
|
||||
Configuration().apply { uiMode = newUiModeConfiguration },
|
||||
context.resources.displayMetrics
|
||||
topContext.resources.displayMetrics
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +55,9 @@ object SensorsBridge {
|
||||
private const val KEY_SEARCH_TYPE = "search_type"
|
||||
private const val KEY_SEARCH_RESULT = "search_result"
|
||||
private const val KEY_IS_NOT_PROMPT = "is_not_prompt"
|
||||
private const val KEY_SESSION_MESSAGE_TYPE = "session_message_type"
|
||||
private const val KEY_REMINDER_TYPE = "reminder_type"
|
||||
private const val KEY_MESSAGE_TYPE = "message_type"
|
||||
|
||||
private const val EVENT_GAME_DETAIL_PAGE_TAB_SELECT = "GameDetailPageTabSelect"
|
||||
private const val EVENT_GAME_DETAIL_PAGE_TAG_CLICK = "GameDetailPageGameTagClick"
|
||||
@ -117,6 +120,15 @@ object SensorsBridge {
|
||||
private const val EVENT_SEARCH_RESULT_RETURN = "SearchResultReturn"
|
||||
private const val EVENT_SEARCH_RESULT_CLICK = "SearchResultClick"
|
||||
private const val EVENT_ARTICLE_SEARCH_TAB_CLICK = "ArticleSearchTabClick"
|
||||
private const val EVENT_MESSAGE_RECEIVE = "MessageReceive"
|
||||
private const val EVENT_MESSAGE_CENTER_CLICK = "MessageCenterClick"
|
||||
private const val EVENT_MESSAGE_SESSION_CLICK = "MessageSessionClick"
|
||||
private const val EVENT_MESSAGE_ITEM_CLICK = "MessageItemClick"
|
||||
private const val EVENT_MESSAGE_ITEM_LINK_CLICK = "MessageItemLinkClick"
|
||||
private const val EVENT_LAUNCH_SERVER_SUBSCRIBE_CLICK = "LaunchServerSubscribeClick"
|
||||
private const val EVENT_LAUNCH_SERVER_SUBSCRIBE_CANCEL_CLICK = "LaunchServerSubscribeCancelClick"
|
||||
private const val EVENT_LAUNCH_SERVER_REMINDER_CLICK = "LaunchServerReminderClick"
|
||||
private const val EVENT_LAUNCH_SERVER_REMINDER_CANCEL_CLICK ="LaunchServerReminderCancelClick"
|
||||
|
||||
private var mIsSensorsEnabled = false
|
||||
|
||||
@ -1949,4 +1961,202 @@ object SensorsBridge {
|
||||
trackEvent(EVENT_INSTALL_GAME_FINISH, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:MessageReceive
|
||||
* 事件名称:消息接收事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param sessionMessageType 会话类型: 游戏消息、系统消息、客服消息、互动消息、运营消息
|
||||
* @param messageType 消息类型
|
||||
* @see EVENT_MESSAGE_RECEIVE
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackMessageReceive(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sessionMessageType: String,
|
||||
messageType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_SESSION_MESSAGE_TYPE to sessionMessageType
|
||||
KEY_MESSAGE_TYPE to messageType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_MESSAGE_RECEIVE, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:MessageCenterClick
|
||||
* 事件名称:消息中心点击事件
|
||||
* @see EVENT_MESSAGE_CENTER_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackMessageCenterClick() {
|
||||
val json = json {}
|
||||
|
||||
trackEvent(EVENT_MESSAGE_CENTER_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:MessageSessionClick
|
||||
* 事件名称:消息会话点击事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param sessionMessageType 会话类型: 游戏消息、系统消息、客服消息、互动消息、运营消息
|
||||
* @see EVENT_MESSAGE_SESSION_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackMessageSessionClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sessionMessageType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_SESSION_MESSAGE_TYPE to sessionMessageType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_MESSAGE_SESSION_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:MessageItemClick
|
||||
* 事件名称:消息点击事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param sessionMessageType 会话类型: 游戏消息、系统消息、客服消息、互动消息、运营消息
|
||||
* @param messageType 消息类型
|
||||
* @see EVENT_MESSAGE_ITEM_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackMessageItemClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sessionMessageType: String,
|
||||
messageType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_SESSION_MESSAGE_TYPE to sessionMessageType
|
||||
KEY_MESSAGE_TYPE to messageType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_MESSAGE_ITEM_CLICK, json)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 事件ID:MessageItemLinkClick
|
||||
* 事件名称:消息点击事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param sessionMessageType 会话类型: 游戏消息、系统消息、客服消息、互动消息、运营消息
|
||||
* @param messageType 消息类型
|
||||
* @see EVENT_MESSAGE_ITEM_LINK_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackMessageItemLinkClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sessionMessageType: String,
|
||||
messageType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_SESSION_MESSAGE_TYPE to sessionMessageType
|
||||
KEY_MESSAGE_TYPE to messageType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_MESSAGE_ITEM_LINK_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:LaunchServerSubscribeClick
|
||||
* 事件名称:加入开服订阅事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @see EVENT_LAUNCH_SERVER_SUBSCRIBE_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackLaunchServerSubscribeClick(
|
||||
gameId: String,
|
||||
gameName: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
}
|
||||
|
||||
trackEvent(EVENT_LAUNCH_SERVER_SUBSCRIBE_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:LaunchServerSubscribeCancelClick
|
||||
* 事件名称:取消开服订阅事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @see EVENT_LAUNCH_SERVER_SUBSCRIBE_CANCEL_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackLaunchServerSubscribeCancelClick(
|
||||
gameId: String,
|
||||
gameName: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
}
|
||||
|
||||
trackEvent(EVENT_LAUNCH_SERVER_SUBSCRIBE_CANCEL_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:LaunchServerReminderClick
|
||||
* 事件名称:添加开服提醒事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param reminderType 提醒类型: 已知服、未知服
|
||||
* @see EVENT_LAUNCH_SERVER_REMINDER_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackLaunchServerReminderClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
reminderType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_REMINDER_TYPE to reminderType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_LAUNCH_SERVER_REMINDER_CLICK, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:LaunchServerReminderCancelClick
|
||||
* 事件名称:游戏安装完成事件
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @see EVENT_LAUNCH_SERVER_REMINDER_CANCEL_CLICK
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackLaunchServerReminderCancelClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
reminderType: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_REMINDER_TYPE to reminderType
|
||||
}
|
||||
|
||||
trackEvent(EVENT_LAUNCH_SERVER_REMINDER_CANCEL_CLICK, json)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package com.gh.gamecenter.common.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MediatorLiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.tencent.mm.opensdk.modelbase.BaseReq;
|
||||
import com.tencent.mm.opensdk.modelbase.BaseResp;
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI;
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
|
||||
import com.tencent.mm.opensdk.utils.ILog;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用微信SDK代理工厂类
|
||||
* 1. 构造通用微信SDK代理类实例
|
||||
* 2. 处理WXEntryActivity的结果回调
|
||||
*/
|
||||
public final class WXAPIProxyFactory {
|
||||
private WXAPIProxyFactory() {
|
||||
}
|
||||
|
||||
private static final MutableLiveData<BaseResp> mRespLiveData = new MutableLiveData<>();
|
||||
|
||||
public static <T extends BaseReq, R extends BaseResp> WXAPIProxy<T, R> createWXAPI(Context context, String appid) {
|
||||
|
||||
final String transaction = String.valueOf(System.currentTimeMillis());
|
||||
|
||||
return createWXAPI(context, appid, new WXHandler<T, R>() {
|
||||
|
||||
@Override
|
||||
public void handleOnReq(T req) {
|
||||
req.transaction = transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R handleOnResp(BaseResp resp) {
|
||||
if (transaction.equals(resp.transaction)) {
|
||||
return (R) resp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T extends BaseReq, R extends BaseResp> WXAPIProxy<T, R> createWXAPI(Context context, String appid, WXHandler<T, R> handler) {
|
||||
return new WXAPIProxy<>(context, appid, handler);
|
||||
}
|
||||
|
||||
public static MutableLiveData<BaseResp> getLiveData() {
|
||||
return mRespLiveData;
|
||||
}
|
||||
|
||||
public final static class WXAPIProxy<T extends BaseReq, R extends BaseResp> {
|
||||
|
||||
private final IWXAPI mWxAPI;
|
||||
|
||||
private WXHandler<T, R> mHandler;
|
||||
|
||||
private final MediatorLiveData<R> mLiveData = new MediatorLiveData<R>() {{
|
||||
addSource(mRespLiveData, input -> {
|
||||
R resp = mHandler.handleOnResp(input);
|
||||
if (resp != null) {
|
||||
mLiveData.setValue(resp);
|
||||
}
|
||||
});
|
||||
}};
|
||||
|
||||
private WXAPIProxy(Context context, String appid, WXHandler<T, R> handler) {
|
||||
mHandler = handler;
|
||||
mWxAPI = WXAPIFactory.createWXAPI(context, appid);
|
||||
}
|
||||
|
||||
public boolean registerApp(String s) {
|
||||
return mWxAPI.registerApp(s);
|
||||
}
|
||||
|
||||
public boolean registerApp(String s, long l) {
|
||||
return mWxAPI.registerApp(s, l);
|
||||
}
|
||||
|
||||
public void unregisterApp() {
|
||||
mWxAPI.unregisterApp();
|
||||
}
|
||||
|
||||
public boolean handleIntent(Intent var1, IWXAPIEventHandler var2) {
|
||||
return mWxAPI.handleIntent(var1, var2);
|
||||
}
|
||||
|
||||
public boolean isWXAppInstalled() {
|
||||
return mWxAPI.isWXAppInstalled();
|
||||
}
|
||||
|
||||
public int getWXAppSupportAPI() {
|
||||
return mWxAPI.getWXAppSupportAPI();
|
||||
}
|
||||
|
||||
public boolean openWXApp() {
|
||||
return mWxAPI.openWXApp();
|
||||
}
|
||||
|
||||
public boolean sendReq(T req) {
|
||||
mHandler.handleOnReq(req);
|
||||
return mWxAPI.sendReq(req);
|
||||
}
|
||||
|
||||
public boolean sendResp(R resp) {
|
||||
return mWxAPI.sendResp(resp);
|
||||
}
|
||||
|
||||
public void detach() {
|
||||
mWxAPI.detach();
|
||||
}
|
||||
|
||||
public void setLogImpl(ILog var1) {
|
||||
mWxAPI.setLogImpl(var1);
|
||||
}
|
||||
|
||||
public LiveData<R> getLiveData() {
|
||||
return mLiveData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface WXHandler<T extends BaseReq, R extends BaseResp> {
|
||||
void handleOnReq(T req);
|
||||
|
||||
R handleOnResp(BaseResp resp);
|
||||
}
|
||||
}
|
||||
@ -1,82 +0,0 @@
|
||||
package com.gh.gamecenter.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.gamecenter.common.R;
|
||||
|
||||
public class LongPressView extends View {
|
||||
private int mLastMotionX, mLastMotionY;
|
||||
// 是否移动了
|
||||
private boolean isMoved;
|
||||
// 是否释放了
|
||||
private boolean isReleased;
|
||||
// 计数器,防止多次点击导致最后一次形成longpress的时间变短
|
||||
private int mCounter;
|
||||
// 长按的runnable
|
||||
private Runnable mLongPressRunnable;
|
||||
// 移动的阈值
|
||||
private static final int TOUCH_SLOP = 60;
|
||||
private int longPressTimeout = ViewConfiguration.getLongPressTimeout();
|
||||
|
||||
public LongPressView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LongPressView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
public LongPressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
if (attrs != null) {
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LongPressViewStyle);
|
||||
longPressTimeout = ta.getInteger(R.styleable.LongPressViewStyle_timeout, longPressTimeout);
|
||||
ta.recycle();
|
||||
}
|
||||
mLongPressRunnable = () -> {
|
||||
mCounter--;
|
||||
if (mCounter > 0 || isReleased || isMoved)
|
||||
return;
|
||||
performLongClick();// 回调长按事件
|
||||
};
|
||||
}
|
||||
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
mCounter++;
|
||||
isReleased = false;
|
||||
isMoved = false;
|
||||
postDelayed(mLongPressRunnable, longPressTimeout);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (isMoved)
|
||||
break;
|
||||
if (Math.abs(mLastMotionX - x) > TOUCH_SLOP
|
||||
|| Math.abs(mLastMotionY - y) > TOUCH_SLOP) {
|
||||
isMoved = true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
isReleased = true;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user