Merge branch 'dev' into 'dev_4.0.1'

# Conflicts:
#   app/src/main/java/com/gh/common/util/TimeUtils.kt
#   app/src/main/java/com/gh/download/DownloadManager.java
This commit is contained in:
juntao
2020-05-20 17:50:59 +08:00
70 changed files with 727 additions and 527 deletions

View File

@ -23,7 +23,7 @@ object AppExecutor {
@JvmStatic
val lightWeightIoExecutor by lazy { Executors.newSingleThreadExecutor() }
@JvmStatic
val ioExecutor by lazy { Executors.newCachedThreadPool() }
val ioExecutor = Executors.newCachedThreadPool() // 用 by lazy 可能影响初始化速度
class MainThreadExecutor : Executor {
private val mainThreadHandler = Handler(Looper.getMainLooper())

View File

@ -5,6 +5,8 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.gh.common.util.GsonUtils;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageUtils;
@ -23,8 +25,6 @@ import org.greenrobot.eventbus.EventBus;
import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -237,7 +237,7 @@ public class Config {
}
public static boolean isGameDomeSwitchOpen() {
return getSettings().getGameDomeSwitch().equals("on");
return getSettings() != null && getSettings().getGameDomeSwitch().equals("on");
}
public static void fixHideFunction() {

View File

@ -13,6 +13,12 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.base.OnViewClickListener;
import com.gh.common.constant.Config;
@ -67,12 +73,6 @@ import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.databinding.BindingAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
/**
* Created by khy on 12/02/18.
*/
@ -228,7 +228,7 @@ public class BindingAdapters {
view.setVisibility(View.VISIBLE);
}
}
/**
* lazy 的 paddingTop
*/
@ -647,27 +647,9 @@ public class BindingAdapters {
}
}
@BindingAdapter({"gameLabelList", "subjectTag"})
public static void setGameLabelList(LinearLayout layout, GameEntity gameEntity, String subjectTag) {
if (gameEntity == null) return;
if (gameEntity.getTest() != null) {
layout.removeAllViews();
View testView = LayoutInflater.from(layout.getContext()).inflate(R.layout.game_test_label, null);
TextView testType = testView.findViewById(R.id.test_type);
TextView testTime = testView.findViewById(R.id.test_time);
testType.setText(gameEntity.getTest().getType());
testType.setBackgroundColor(ContextCompat.getColor(layout.getContext(), R.color.tag_yellow));
if (gameEntity.getTest().getStart() == 0) {
testTime.setVisibility(View.GONE);
} else {
testTime.setText(GameViewUtils.getGameTestDate(gameEntity.getTest().getStart()));
}
layout.addView(testView);
} else {
GameViewUtils.setLabelList(layout.getContext(), layout, gameEntity.getTag(), subjectTag, gameEntity.getTagStyle());
}
@BindingAdapter("gameLabelList")
public static void setGameLabelList(LinearLayout layout, List<TagStyleEntity> tagStyle) {
GameViewUtils.setLabelList(layout.getContext(), layout, tagStyle);
}
@BindingAdapter("isRefreshing")

View File

@ -210,7 +210,7 @@ object DirectUtils {
"libao" -> directToGiftDetail(context, linkEntity.link ?: "", entrance)
"feedback" -> directToFeedback(context, "", entrance)
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, entrance)
"qa" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
@ -350,12 +350,21 @@ object DirectUtils {
// 反馈
@JvmStatic
fun directToFeedback(context: Context, content: String? = null, entrance: String? = null) {
directToFeedback(context, content, null, entrance)
}
@JvmStatic
fun directToFeedback(context: Context, content: String? = null, hintType: String? = null, entrance: String? = null) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, SuggestionActivity::class.java.simpleName)
bundle.putString(KEY_CONTENT, content)
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
bundle.putSerializable(EntranceUtils.KEY_SUGGESTTYPE, SuggestType.gameQuestion)
if (TextUtils.isEmpty(hintType)) {
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
} else {
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
}
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
jumpActivity(context, bundle)
}

View File

@ -8,6 +8,12 @@ import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.common.constant.Config;
import com.gh.common.dialog.CertificationDialog;
import com.gh.common.dialog.DeviceRemindDialog;
@ -35,12 +41,6 @@ import com.lightgame.utils.Utils;
import java.util.concurrent.LinkedBlockingQueue;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
/**
* todo 下载判断不能以按钮文案为判断条件,否则按钮文案修改时又要修改判断逻辑
*/
@ -131,11 +131,6 @@ public class DownloadItemUtils {
holder.gameDownloadBtn.setTextColor(Color.WHITE);
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_pause_dn);
}
if (gameEntity.isLibaoExists()) {
holder.gameLibaoIcon.setVisibility(View.VISIBLE);
} else {
holder.gameLibaoIcon.setVisibility(View.GONE);
}
}
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
@ -158,12 +153,6 @@ public class DownloadItemUtils {
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
}
if (gameEntity.isLibaoExists()) {
holder.gameLibaoIcon.setVisibility(View.VISIBLE);
} else {
holder.gameLibaoIcon.setVisibility(View.GONE);
}
// 显示预约
if (gameEntity.isReservable()) {
holder.gameDes.setVisibility(View.VISIBLE);

View File

@ -10,6 +10,9 @@ import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.gh.common.view.DrawableView;
import com.gh.gamecenter.R;
import com.gh.gamecenter.entity.TagStyleEntity;
@ -21,8 +24,6 @@ import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import androidx.core.content.ContextCompat;
/**
* @author 温冠超
* @email 294299195@qq.com
@ -32,21 +33,16 @@ import androidx.core.content.ContextCompat;
*/
public class GameViewUtils {
public static void setLabelList(Context context, LinearLayout labelLayout, List<String> tag, String tagType, List<TagStyleEntity> tagStyle) {
public static void setLabelList(Context context, LinearLayout labelLayout, List<TagStyleEntity> tagStyle) {
labelLayout.removeAllViews();
if (tag == null || tag.isEmpty()) {
labelLayout.addView(getGameTagView(context, "官方版", 0, tagType, null));
if (tagStyle == null || tagStyle.isEmpty()) {
TagStyleEntity tagEntity = new TagStyleEntity();
tagEntity.setName("官方版");
labelLayout.addView(getNewGameTagView(context, tagEntity, 0));
} else {
for (int i = 0, size = tag.size(); i < size; i++) {
View view;
if (i == size - 1) {
view = getGameTagView(context, tag.get(i), 0, tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
} else {
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 8), tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
}
if (view != null) {
labelLayout.addView(view);
}
for (int i = 0, size = tagStyle.size(); i < size; i++) {
View view = getNewGameTagView(context, tagStyle.get(i), i == size - 1 ? 0 : DisplayUtils.dip2px(context, 8));
labelLayout.addView(view);
if (labelLayout.getChildCount() == 3) {
break;
}
@ -76,6 +72,32 @@ public class GameViewUtils {
}
}
// 新的游戏标签样式 version>=4.0.0
private static TextView getNewGameTagView(Context context, TagStyleEntity tagEntity, int rightMargin) {
// 参数不全,用旧样式实现
if (TextUtils.isEmpty(tagEntity.getBackground())) {
return getGameTagView(context, tagEntity.getName(), rightMargin, "type", tagEntity);
}
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lparams.rightMargin = rightMargin;
TextView tag = new TextView(context);
tag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
tag.setSingleLine(true);
tag.setText(tagEntity.getName());
tag.setLayoutParams(lparams);
tag.setPadding(
DisplayUtils.dip2px(context, 4),
0,
DisplayUtils.dip2px(context, 4),
DisplayUtils.dip2px(context, 1));
tag.setTextColor(Color.parseColor("#" + tagEntity.getColor()));
tag.setBackground(DrawableView.getServerDrawable(Color.parseColor("#" + tagEntity.getBackground())));
return tag;
}
private static TextView getGameTagView(Context context, String tagStr, int rightMargin, String tagType, TagStyleEntity tagEntity) {
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

View File

@ -11,8 +11,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
@ -37,6 +35,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import androidx.core.content.ContextCompat;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -151,82 +150,6 @@ public class LibaoUtils {
});
}
public static void setLiBaoBtnStatus(final TextView libaoBtn, String status, Context context) {
libaoBtn.setTextColor(Color.WHITE);
if (TextUtils.isEmpty(status)) return;
switch (status) {
case "ling":
libaoBtn.setText(R.string.libao_ling);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
case "tao":
libaoBtn.setText(R.string.libao_tao);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
case "coming":
libaoBtn.setText(R.string.libao_coming);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "used_up":
libaoBtn.setText(R.string.libao_used_up);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "finish":
libaoBtn.setText(R.string.libao_finish);
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
break;
case "linged":
libaoBtn.setText(R.string.libao_linged);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "taoed":
libaoBtn.setText(R.string.libao_taoed);
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
break;
case "copy":
libaoBtn.setText(R.string.libao_copy);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
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));
break;
case "repeatLinged":
libaoBtn.setText(R.string.libao_repeat_ling);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
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));
break;
case "repeatTaoed":
libaoBtn.setText(R.string.libao_repeat_tao);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
case "unshelve":
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
libaoBtn.setText(R.string.libao_unshelve);
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
break;
case "check":
libaoBtn.setText(R.string.libao_check);
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
break;
default:
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
libaoBtn.setText("异常");
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
break;
}
}
public static void setLiBaoBtnStatusRound(final TextView libaoBtn, String status, Context context) {
libaoBtn.setTextColor(Color.WHITE);
if (TextUtils.isEmpty(status)) return;
@ -306,7 +229,7 @@ public class LibaoUtils {
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
final boolean isInstallRequired, final LibaoDetailAdapter adapter, final String entrance) {
String status = libaoEntity.getStatus();
setLiBaoBtnStatus(libaoBtn, status, context);
setLiBaoBtnStatusRound(libaoBtn, status, context);
libaoBtn.setOnClickListener(v -> {
String btnStatus = libaoBtn.getText().toString();

View File

@ -55,4 +55,21 @@ object TimeUtils {
}
return false
}
/**
* 判断时间戳是多少天前
*/
fun getBeforeDays(timestamp: Long):Int{
var days: Long = 0
val format = SimpleDateFormat("yyyyMMdd HH:mm", Locale.getDefault())
try {
val today = format.parse(format.format(Date())).time
val day = timestamp * 1000
days = (today - day) / 86400000
} catch (e: ParseException) {
e.printStackTrace()
}
return days.toInt()
}
}

View File

@ -131,6 +131,10 @@ public class ExpandTextView extends AppCompatTextView {
int startPosition = 0;
startPosition = content.length() - finalEndText.length() - mExpandText.length();
startPosition = Math.max(startPosition, 0);
// 避免越界
if (startPosition >= length) return;
msp.replace(startPosition, length, finalEndText + mExpandText);
msp.setSpan(new ClickableSpan() {

View File

@ -1,5 +1,4 @@
package com.gh.common.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@ -10,11 +9,8 @@ import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;
import wendu.dsbridge.DWebView;
/**
* 由于WebView没有实现NestedScrollingChild导致与CoordinatorLayout不能实现联动效果
* 所以需要自己实现NestedScrollingChild
*/
public class NestedScrollWebView extends DWebView implements NestedScrollingChild {
public static final String TAG = NestedScrollWebView.class.getSimpleName();
private int mLastMotionY;
@ -23,6 +19,7 @@ public class NestedScrollWebView extends DWebView implements NestedScrollingChil
private final int[] mScrollConsumed = new int[2];
private int mNestedYOffset;
private boolean mChange;
private NestedScrollingChildHelper mChildHelper;
@ -36,6 +33,7 @@ public class NestedScrollWebView extends DWebView implements NestedScrollingChil
init();
}
private void init() {
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
@ -50,25 +48,25 @@ public class NestedScrollWebView extends DWebView implements NestedScrollingChil
@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;
int nestedScrollAxis = ViewCompat.SCROLL_AXIS_VERTICAL;
nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL; //按位或运算
// startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
startNestedScroll(nestedScrollAxis);
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
result = super.onTouchEvent(event);
mChange = false;
break;
case MotionEvent.ACTION_MOVE:
int deltaY = mLastMotionY - y;
@ -88,9 +86,23 @@ public class NestedScrollWebView extends DWebView implements NestedScrollingChil
trackedEvent.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
if (mScrollConsumed[1] == 0 && mScrollOffset[1] == 0) {
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();
result = super.onTouchEvent(trackedEvent);
}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:
@ -104,86 +116,49 @@ public class NestedScrollWebView extends DWebView implements NestedScrollingChil
}
// NestedScrollingChild
@Override
public void setNestedScrollingEnabled(boolean enabled) {//设置嵌套滑动是否可用
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {//嵌套滑动是否可用
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
/**
* 开始嵌套滑动,
*
* @param axes 表示方向 有一下两种值
* ViewCompat.SCROLL_AXIS_HORIZONTAL 横向滑动
* ViewCompat.SCROLL_AXIS_VERTICAL 纵向滑动
*/
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {//停止嵌套滑动
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {//是否有父View 支持 嵌套滑动, 会一层层的网上寻找父View
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
/**
* 在处理滑动之后 调用
*
* @param dxConsumed x轴上 被消费的距离
* @param dyConsumed y轴上 被消费的距离
* @param dxUnconsumed x轴上 未被消费的距离
* @param dyUnconsumed y轴上 未被消费的距离
* @param offsetInWindow view 的移动距离
* @return
*/
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
/**
* 一般在滑动之前调用, 在ontouch 中计算出滑动距离, 然后调用该方法, 就给支持的嵌套的父View 处理滑动事件
*
* @param dx x 轴上滑动的距离, 相对于上一次事件, 不是相对于 down事件的 那个距离
* @param dy y 轴上滑动的距离
* @param consumed 一个数组, 可以传 一个空的 数组, 表示 x 方向 或 y 方向的事件 是否有被消费
* @param offsetInWindow 支持嵌套滑动到额父View 消费 滑动事件后 导致 本 View 的移动距离
* @return 支持的嵌套的父View 是否处理了 滑动事件
*/
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
/**
* @param velocityX x 轴上的滑动速度
* @param velocityY y 轴上的滑动速度
* @param consumed 是否被消费
* @return
*/
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
/**
* @param velocityX x 轴上的滑动速度
* @param velocityY y 轴上的滑动速度
* @return
*/
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}
}

View File

@ -8,6 +8,9 @@ import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
import com.gh.common.AppExecutor;
import com.gh.common.exposure.ExposureEvent;
import com.gh.common.history.HistoryHelper;
@ -279,7 +282,7 @@ public class DownloadManager implements DownloadStatusListener {
} else if (PackageUtils.isCanUpdate(apkEntity, gameEntity.getId())) {
downloadEntity.setUpdate(true);
}
downloadEntity.setPlugin(!TextUtils.isEmpty(apkEntity.getGhVersion()));
if (isSubscribe) {
@ -635,6 +638,7 @@ public class DownloadManager implements DownloadStatusListener {
// 开启下载服务, Fuck me, 即便是在启动页调用的方法,依然有可能触发 `unable is in background`
startDownloadService();
checkRetryDownload();
}
public void addObserver(DataWatcher dataWatcher) {

View File

@ -63,7 +63,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.gameId == mGameEntity.id &&
if (downloadEntity.gameId == mGameEntity?.id &&
DownloadStatus.delete != DownloadManager.getInstance(requireContext()).getStatus(downloadEntity.url)) {
mAdapter?.listData?.forEachIndexed { index, entity ->
if (entity.normal?.packageName == downloadEntity.packageName
@ -95,13 +95,17 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
override fun onCreate(savedInstanceState: Bundle?) {
EventBus.getDefault().register(this)
super.onCreate(savedInstanceState)
mGameEntity = requireArguments().getParcelable(GameEntity::class.java.simpleName)!!
mEntrance = requireArguments().getString(EntranceUtils.KEY_ENTRANCE) ?: ""
mLocation = requireArguments().getString(EntranceUtils.KEY_LOCATION) ?: ""
val factory = DownloadViewModel.Factory(HaloApp.getInstance().application, mGameEntity)
mViewModel = ViewModelProviders.of(this, factory).get(DownloadViewModel::class.java)
mViewModel.listLiveData.observeNonNull(this, callback = { itemList ->
mAdapter = DownloadDialogAdapter(requireContext(), mViewModel, itemList, false, mEntrance, mLocation)
mBinding.contentList.layoutManager = createLayoutManager(itemList)
mBinding.contentList.adapter = mAdapter
})
mViewModel.collectionLiveData.observe(this, Observer { collection ->
@ -126,7 +130,7 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
if (mAdapter != null) collectionEnterAnimation()
} else {
mBinding.title.text = ("选择下载" + mGameEntity.pluginDesc + "版本")
mBinding.title.text = ("选择下载" + mGameEntity?.pluginDesc + "版本")
mCollectionAdapter = null
collectionExitAnimation()
@ -256,7 +260,6 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
return layoutManager
}
override fun onResume() {
mAdapter?.notifyDataSetChanged()
mCollectionAdapter?.notifyDataSetChanged()
@ -266,7 +269,6 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
mElapsedHelper.resumeCounting()
}
override fun onPause() {
super.onPause()
DownloadManager.getInstance(requireContext()).removeObserver(mDataWatcher)
@ -276,10 +278,10 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
private fun postBrowseMta() {
if (mCollectionAdapter == null) {
MtaHelper.onEventWithTime(MTA_KEY, mElapsedHelper.elapsedTime, "浏览", mGameEntity.name)
MtaHelper.onEventWithTime(MTA_KEY, mElapsedHelper.elapsedTime, "浏览", mGameEntity?.name)
} else {
val collectionData = mViewModel.collectionLiveData.value
MtaHelper.onEventWithTime(MTA_KEY, mElapsedHelper.elapsedTime, "浏览", mGameEntity.name + "_" + collectionData?.name)
MtaHelper.onEventWithTime(MTA_KEY, mElapsedHelper.elapsedTime, "浏览", mGameEntity?.name + "_" + collectionData?.name)
throwExceptionInDebug("collectionData must be not null", collectionData == null)
}
}
@ -399,9 +401,11 @@ class DownloadDialog : BaseDialogFragment(), View.OnTouchListener {
if (hasDownloadDialogInCurrentActivity(fragmentActivity)) return
val downloadDialog = DownloadDialog().apply {
mGameEntity = gameEntity
mEntrance = entrance ?: ""
mLocation = location ?: ""
val bundle = Bundle()
bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance)
bundle.putString(EntranceUtils.KEY_LOCATION, location)
bundle.putParcelable(GameEntity::class.java.simpleName, gameEntity)
arguments = bundle
}
downloadDialog.show(fragmentActivity.supportFragmentManager, DownloadDialog::class.java.name)
}

View File

@ -1,9 +1,12 @@
package com.gh.download.dialog
import android.content.Context
import android.view.View
import com.gh.base.BaseActivity
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.constant.Config
import com.gh.common.dialog.CertificationDialog
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.common.util.*
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.download.DownloadManager
@ -12,6 +15,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DownloadDialogItemBinding
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.GameCollectionEntity
import com.gh.gamecenter.entity.GameEntity
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
@ -162,13 +166,12 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
var mtaValue = "未知"
when (itemView.getTag(DownloadDialogAdapter.ITEM_TAG_KEY)) {
DownloadDialogItemStatus.DOWNLOAD -> {
DialogUtils.checkDownload(it.context, apkEntity.size) { isSubscribe ->
DownloadManager.createDownload(it.context, apkEntity, gameEntity, "下载", entrance, location, isSubscribe, null)
}
createDownloadTask(it.context, apkEntity, gameEntity, "下载", entrance, location)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_下载"
}
DownloadDialogItemStatus.LAUNCH -> {
PackageUtils.launchApplicationByPackageName(it.context, apkEntity.packageName)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_启动"
}
DownloadDialogItemStatus.DOWNLOADING -> {
@ -180,6 +183,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
if (AppManager.getInstance().currentActivity() is DownloadManagerActivity) {
viewModel.dismissLiveData.postValue(Any())
}
val downloadEntity = DownloadManager.getInstance(it.context).getDownloadEntityByUrl(apkEntity.url)
if (downloadEntity.status == DownloadStatus.pause) {
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_暂停中"
@ -206,6 +210,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
PackageUtils.launchSetup(it.context, downloadEntity)
}
}
if (downloadEntity.isPluggable) {
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_插件化安装"
} else {
@ -213,21 +218,20 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
}
DownloadDialogItemStatus.PLUGGABLE -> {
DialogUtils.checkDownload(it.context, apkEntity.size) { isSubscribe ->
DownloadManager.createDownload(it.context, apkEntity, gameEntity, "插件化", entrance, location, isSubscribe, null)
}
createDownloadTask(it.context, apkEntity, gameEntity, "插件化", entrance, location)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_插件化"
}
DownloadDialogItemStatus.UPDATE -> {
DialogUtils.checkDownload(it.context, apkEntity.size) { isSubscribe ->
DownloadManager.createDownload(it.context, apkEntity, gameEntity, "更新", entrance, location, isSubscribe, null)
}
createDownloadTask(it.context, apkEntity, gameEntity, "更新", entrance, location)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_更新"
}
DownloadDialogItemStatus.COLLECTION -> {
val apkCollection = apkEntity.apkCollection
if (apkCollection != null) {
viewModel.collectionLiveData.postValue(apkCollection)
mtaValue = gameEntity.name + "_" + apkCollection.name + "_查看合集"
} else if (apkEntity.downloadInstruction.isNotEmpty()) {
val fakeCollection = GameCollectionEntity()
@ -235,6 +239,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
fakeCollection.name = apkEntity.getPlatformName()
fakeCollection.downloadInstruction = apkEntity.downloadInstruction
viewModel.collectionLiveData.postValue(fakeCollection)
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_查看详情"
} else {
throwExceptionInDebug("合集和下载说明至少一个不为空")
@ -242,6 +247,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
DownloadDialogItemStatus.LINK -> {
directToLinkPage(it.context, apkEntity.apkLink?.getLinkEntity()!!, entrance, path)
mtaValue = gameEntity.name + "_" + apkEntity.apkLink?.name
}
DownloadDialogItemStatus.INSTALLED -> {
@ -252,5 +258,31 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
MtaHelper.onEvent(DownloadDialog.MTA_KEY, "点击", mtaValue)
}
}
private fun createDownloadTask(context: Context,
apkEntity: ApkEntity,
gameEntity: GameEntity,
downloadMethod: String,
entrance: String,
location: String) {
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apkEntity, object : EmptyCallback {
override fun onCallback() {
CertificationDialog.showCertificationDialog(context, gameEntity, DialogUtils.ConfirmListener {
DialogUtils.checkDownload(context, apkEntity.size) { isSubscribe ->
DownloadManager.createDownload(
context,
apkEntity,
gameEntity,
downloadMethod,
entrance,
location,
isSubscribe, null)
DeviceRemindDialog.showDeviceRemindDialog(context, gameEntity)
}
})
}
})
}
}
}

View File

@ -23,6 +23,9 @@ import android.view.View;
import android.view.Window;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import com.gh.base.AppUncaughtHandler;
import com.gh.base.BaseActivity;
import com.gh.base.fragment.BaseFragment_ViewPager;
@ -116,8 +119,6 @@ import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProviders;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
@ -212,9 +213,10 @@ public class MainActivity extends BaseActivity {
"玩家操作", "点击关闭"));
}
// checkTinkerPath(); // todo 看情况是否需要显示弹窗
// checkTinkerPath(); // 看情况是否需要显示补丁弹窗
checkRetryDownload();
// 必须放在这里否在会导致获取baseActivity不是本应用包名
DownloadManager.getInstance(this).initDownloadService();
checkNotificationPermission();
@ -244,6 +246,7 @@ public class MainActivity extends BaseActivity {
PushHelper.postPushClickAction(this.getApplicationContext(), null);
}, 2000);
// 耗时操作
AppExecutor.getIoExecutor().execute(() -> {
// 上传数据

View File

@ -163,8 +163,6 @@ public class SplashScreenActivity extends BaseActivity {
// 更新本地时间
DeviceTokenUtils.syncServerTime(this);
DownloadManager.getInstance(this).initDownloadService();
});
}
@ -187,10 +185,10 @@ public class SplashScreenActivity extends BaseActivity {
});
}
private void getFilterDetailTags(){
private void getFilterDetailTags() {
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
.getApi().getFilterDetailTags()
.subscribe(new Response<ArrayList<String>>(){
.subscribe(new Response<ArrayList<String>>() {
@Override
public void onResponse(@Nullable ArrayList<String> response) {
super.onResponse(response);
@ -199,11 +197,11 @@ public class SplashScreenActivity extends BaseActivity {
});
}
private void getAuthDialog(){
private void getAuthDialog() {
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
.getApi()
.authDialog()
.subscribe(new Response<List<AuthDialogEntity>>(){
.subscribe(new Response<List<AuthDialogEntity>>() {
@Override
public void onResponse(@Nullable List<AuthDialogEntity> response) {
super.onResponse(response);

View File

@ -85,6 +85,7 @@ public class WebActivity extends NormalActivity {
bundle.putString(EntranceUtils.KEY_URL, context.getString(R.string.comment_rules_url));
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getCopyrighyRulesIntent(Context context) {
Bundle bundle = new Bundle();
@ -175,6 +176,17 @@ public class WebActivity extends NormalActivity {
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getIntent(Context context, String url, String title, boolean autoCompletionTitle, boolean isOpenNativePage) {
Bundle bundle = new Bundle();
bundle.putString(EntranceUtils.KEY_URL, url);
bundle.putString(EntranceUtils.KEY_GAMENAME, title);
bundle.putBoolean(WebFragment.KEY_COMPLETION_TITLE, autoCompletionTitle);
bundle.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_TITLE, false);
bundle.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, isOpenNativePage);
return getTargetIntent(context, WebActivity.class, WebFragment.class, bundle);
}
@NonNull
public static Intent getIntentByUrl(Context context, String url) {
return getIntentByUrl(context, url, false);
@ -203,8 +215,13 @@ public class WebActivity extends NormalActivity {
@Override
protected View.OnClickListener provideNavigationItemClickListener() {
Bundle bundle = getIntent().getBundleExtra(NORMAL_FRAGMENT_BUNDLE);
if (bundle != null && bundle.getBoolean(WebFragment.KEY_ISTOOLS, false)) {
return view -> finish();
if (bundle != null) {
boolean isTools = bundle.getBoolean(WebFragment.KEY_ISTOOLS, false);
boolean isOpenNativePage = bundle.getBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false);
if (isTools || isOpenNativePage) {
return view -> finish();
}
return super.provideNavigationItemClickListener();
} else {
return super.provideNavigationItemClickListener();
}

View File

@ -2,9 +2,6 @@ package com.gh.gamecenter.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
@ -41,6 +38,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import androidx.recyclerview.widget.LinearLayoutManager;
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;
@ -190,13 +190,21 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
linearLayoutManager.setStackFromEnd(true);
holder.libaoCodeRv.setLayoutManager(linearLayoutManager);
int count = (int) (((float) mLibaoEntity.getAvailable() / (float) mLibaoEntity.getTotal()) * 100);
float availablePercent = ((float) mLibaoEntity.getAvailable() / (float) mLibaoEntity.getTotal()) * 100;
int count;
if (availablePercent >= 1) {
count = (int) availablePercent;
} else if (availablePercent == 0) {
count = 0;
} else {
count = 1;
}
Spanned content = null;
String status = mLibaoEntity.getBeforeStatus();
if ("coming".equals(status) || "finish".equals(status) || TextUtils.isEmpty(status)) {
content = Html.fromHtml("剩余:--");
} else if ("ling".equals(status) || "linged".equals(status)) {
content = Html.fromHtml(StringUtils.buildString("剩余:", "<font color=\"#06D0A8\">", count + "%", "</font>"));
content = Html.fromHtml(StringUtils.buildString("剩余:", "<font color=\"#1383EB\">", count + "%", "</font>"));
} else if ("tao".equals(status) || "taoed".equals(status)) {
content = Html.fromHtml(StringUtils.buildString("剩余:", String.valueOf(count), "%"));
} else if ("used_up".equals(status)) {

View File

@ -91,6 +91,7 @@ data class ApkEntity(@SerializedName("package")
class ApkLink(@SerializedName("_id")
val id: String = "",
val name: String = "",
@SerializedName("new_icon")
val icon: String = "",
val type: String = "",
val link: String = "",

View File

@ -132,7 +132,7 @@ class GameDetailEntity(
var gameName: String = "",
@SerializedName("game_icon")
var gameIcon: String = "",
@SerializedName("game_tag")
@SerializedName(value = "game_tag", alternate = arrayOf("new_game_tag"))
var gameTags: ArrayList<TagStyleEntity> = ArrayList(),
var index: Int) : Parcelable

View File

@ -92,7 +92,7 @@ data class GameEntity(
var subjectData: GameSubjectData? = null,
// 所有标签(插件标签和游戏标签)
@SerializedName("tag_style")
@SerializedName(value = "tag_style", alternate = arrayOf("new_tag_style"))
var tagStyle: ArrayList<TagStyleEntity> = ArrayList(),
var des: String? = null,
// 用来标记在专题中的序号,仅用于曝光记录

View File

@ -9,7 +9,9 @@ class Rating(val star: Star = Star(),
@SerializedName("service_comment")
var serviceComment: RatingComment? = null,
@SerializedName("comment")
var myComment: RatingComment? = null)
var myComment: RatingComment? = null,
@SerializedName("comment_count")
var commentCount: Int = 0)
class Star(var average: Float = 0F,
val hits: Int = 0,

View File

@ -10,4 +10,7 @@ class TagStyleEntity(
var id: String = "",
var name: String = "",
var style: String = "",
var color: String = "") : Parcelable
var color: String = "",
// 新样式
var background: String? = "") : Parcelable

View File

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

View File

@ -367,7 +367,7 @@ class GameDetailFragment : NormalFragment() {
mNewGameDetailEntity = data
// showAlertDialogIfNeeded(data.game)
showAlertDialogIfNeeded(data)
initViewPage(data)
initGameDetailTop()
@ -479,6 +479,7 @@ class GameDetailFragment : NormalFragment() {
val webFragment = WebFragment()
val webBundle = Bundle()
webBundle.putString(EntranceUtils.KEY_URL, "${it.link}?timestamp=${System.currentTimeMillis()}")
webBundle.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, true)
webFragment.arguments = webBundle
fragmentsList.add(webFragment)
} else {
@ -515,14 +516,14 @@ class GameDetailFragment : NormalFragment() {
BaseFragment_TabLayout.initTabStyle(mTabLayout, mViewPager.currentItem)
}
private fun showAlertDialogIfNeeded(detailEntity: GameDetailEntity) {
private fun showAlertDialogIfNeeded(detailEntity: NewGameDetailEntity) {
if (detailEntity.detailDialog != null) {
val dialog = detailEntity.detailDialog
// 机型匹配或规则为空都弹
if (dialog!!.rule.models.isEmpty() || dialog.rule.models.contains(Build.MODEL)) {
val dayOfMonth = Calendar.getInstance().get(Calendar.DAY_OF_MONTH)
if ("EVERY_TIME_OPEN" == dialog.alert || SPUtils.getLong(SP_OPENED_DIALOG_TIME_PREFIX + detailEntity.id!!, 0) != dayOfMonth.toLong()) {
SPUtils.setLong(SP_OPENED_DIALOG_TIME_PREFIX + detailEntity.id!!, 0)
if ("EVERY_TIME_OPEN" == dialog.alert || SPUtils.getLong(SP_OPENED_DIALOG_TIME_PREFIX + mGameEntity?.id, 0) != dayOfMonth.toLong()) {
SPUtils.setLong(SP_OPENED_DIALOG_TIME_PREFIX + mGameEntity?.id, 0)
doShowAlertDialog(dialog)
}
}
@ -643,7 +644,7 @@ class GameDetailFragment : NormalFragment() {
ratingScoreAverage.textSize = 18f
ratingScoreAverage.text = if (mNewGameDetailEntity!!.newStar == 10F) "10" else mNewGameDetailEntity!!.newStar.toString()
} else {
ratingScoreAverage.textSize = 9f
ratingScoreAverage.textSize = 8f
ratingScoreAverage.text = "评分过少"
}
@ -677,7 +678,7 @@ class GameDetailFragment : NormalFragment() {
gameBigEvent.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_game_big_event)
gameBigEvent.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(requireContext(), R.drawable.ic_game_detail_big_event_gray), null,
ContextCompat.getDrawable(requireContext(), R.drawable.ic_game_detail_big_event_arrow_gray), null)
var eventStr = "${TimeUtils.getFormatTime(it.time, "MM-dd")}${it.content}"
var eventStr = if (TimeUtils.getBeforeDays(it.time) <= 15) "${TimeUtils.getFormatTime(it.time, "MM-dd")}${it.content}" else it.content
if (eventStr.contains("\n")) eventStr = eventStr.substring(0, eventStr.indexOf("\n"))
gameBigEvent.text = eventStr
}

View File

@ -331,6 +331,12 @@ class GameDetailViewModel(application: Application,
override fun onResponse(response: List<BigEvent>?) {
super.onResponse(response)
response?.let {
for (event in it) {
if (event.link?.type == "feedback") {
event.link?.name = game?.name
event.link?.text = game?.getGameCategory().toString()
}
}
bigEventLiveData.postValue(it)
}
}

View File

@ -5,7 +5,6 @@ import android.text.TextUtils
import android.util.SparseBooleanArray
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
@ -25,11 +24,15 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.SuggestionActivity
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.LinkEntity
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.game.horizontal.GameHorizontalAdapter
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.entity.*
import com.gh.gamecenter.gamedetail.entity.CustomColumn
import com.gh.gamecenter.gamedetail.entity.DetailEntity
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.home.amway.LeftPagerSnapHelper
@ -143,25 +146,25 @@ class DescAdapter(context: Context,
is GamesRecommendedGalleryViewHolder -> bindGamesRecommendedGalleryViewHolder(holder, position)
is GameDetailRecommendImageViewHolder -> bindImageViewHolder(holder, descItemList[position].imageRecommend)
is GameDetailRecommendImageViewHolder -> bindImageViewHolder(holder, descItemList[position])
is GameDetailCommentsViewHolder -> bindCommentsViewHolder(holder, descItemList[position].comment)
is GameDetailCommentsViewHolder -> bindCommentsViewHolder(holder, descItemList[position])
is GameDetailRelatedVersionViewHolder -> bindRelatedVersion(holder, descItemList[position].relatedVersion)
is GameDetailRelatedVersionViewHolder -> bindRelatedVersion(holder, descItemList[position])
is GameVideoGalleryViewHolder -> bindVideosViewHolder(holder, descItemList[position].video, descItemList[position].videoCount)
is GameVideoGalleryViewHolder -> bindVideosViewHolder(holder, descItemList[position], descItemList[position].videoCount)
is GameImageGalleryViewHolder -> bindImageGalleryViewHolder(holder, descItemList[position].gallery)
is GameImageGalleryViewHolder -> bindImageGalleryViewHolder(holder, descItemList[position])
is GameUpdateContentViewHolder -> bindUpdateContentViewHolder(holder, descItemList[position].update)
is GameUpdateContentViewHolder -> bindUpdateContentViewHolder(holder, descItemList[position])
is GameLatestServiceViewHolder -> bindLatestServiceViewHolder(holder, descItemList[position].server)
is GameLatestServiceViewHolder -> bindLatestServiceViewHolder(holder, descItemList[position])
is GameDetailInfoViewHolder -> bindGameDetailInfoViewHolder(holder, descItemList[position].info)
is GameDetailInfoViewHolder -> bindGameDetailInfoViewHolder(holder, descItemList[position])
is GameLibaoGalleryViewHolder -> bindLibaoViewHolder(holder, descItemList[position].libao)
is GameLibaoGalleryViewHolder -> bindLibaoViewHolder(holder, descItemList[position])
is GameRaidersGalleryViewHolder -> bindRaidersViewHolder(holder, descItemList[position].article)
is GameRaidersGalleryViewHolder -> bindRaidersViewHolder(holder, descItemList[position])
is FooterViewHolder -> {
holder.loading.visibility = View.GONE
@ -190,6 +193,9 @@ class DescAdapter(context: Context,
viewHolder.binding.gamedetailItemNotice.startWithList(list)
viewHolder.binding.shouldBoundToNextItem = detailEntity.shouldBoundTogetherWithNextItem
viewHolder.binding.shouldBoundToPreviousItem = detailEntity.shouldBoundTogetherWithPreviousItem
viewHolder.binding.containerPaddingTop = detailEntity.paddingTop
viewHolder.binding.containerPaddingBottom = detailEntity.paddingBottom
viewHolder.binding.executePendingBindings()
updateBoundableContainerBackground(
viewHolder.binding.container,
detailEntity.shouldBoundTogetherWithPreviousItem,
@ -221,10 +227,9 @@ class DescAdapter(context: Context,
viewHolder.binding.customColumn = customColumn
viewHolder.binding.shouldBoundToNextItem = detailEntity.shouldBoundTogetherWithNextItem
viewHolder.binding.shouldBoundToPreviousItem = detailEntity.shouldBoundTogetherWithPreviousItem
val params = viewHolder.binding.container.layoutParams as FrameLayout.LayoutParams
params.bottomMargin = DisplayUtils.dip2px(if (!detailEntity.shouldBoundTogetherWithNextItem) 12f else 0f)
viewHolder.binding.container.layoutParams = params
viewHolder.binding.containerPaddingTop = detailEntity.paddingTop
viewHolder.binding.containerPaddingBottom = detailEntity.paddingBottom
viewHolder.binding.executePendingBindings()
updateBoundableContainerBackground(
viewHolder.binding.container,
@ -246,15 +251,23 @@ class DescAdapter(context: Context,
linkHintTv = viewHolder.binding.linkHintTv,
linkHintArrowIv = viewHolder.binding.linkHintArrowIv)
viewHolder.binding.customColumn = customColumn
viewHolder.binding.executePendingBindings()
}
//绑定大家都在玩
private fun bindGamesRecommendedGalleryViewHolder(viewHolder: GamesRecommendedGalleryViewHolder, position: Int) {
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
viewHolder.binding.executePendingBindings()
//分割线
val params = viewHolder.itemView.layoutParams as RecyclerView.LayoutParams
params.topMargin = DisplayUtils.dip2px(8f)
viewHolder.itemView.layoutParams = params
//重新调整间距
// viewHolder.itemView.setPadding(viewHolder.itemView.paddingLeft, viewHolder.itemView.paddingTop - DisplayUtils.dip2px(4f), viewHolder.itemView.paddingRight, viewHolder.itemView.paddingBottom)
val galleryParams = viewHolder.binding.galleryRv.layoutParams as ConstraintLayout.LayoutParams
galleryParams.topMargin = DisplayUtils.dip2px(8f)
viewHolder.binding.galleryRv.layoutParams = galleryParams
val subjectEntity = descItemList[position].recommendedGames
if (subjectEntity != null) {
@ -275,7 +288,13 @@ class DescAdapter(context: Context,
}
//绑定评论
private fun bindCommentsViewHolder(viewHolder: GameDetailCommentsViewHolder, comments: ArrayList<RatingComment>?) {
private fun bindCommentsViewHolder(viewHolder: GameDetailCommentsViewHolder, itemData: DetailEntity) {
val comments = itemData.comment
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
if (viewHolder.binding.recyclerview.adapter == null) {
val commentsAdapter = viewHolder.binding.recyclerview.adapter as DescCommentsAdapter?
?: DescCommentsAdapter(mContext, mViewModel, mEntrance, gameName)
@ -298,7 +317,13 @@ class DescAdapter(context: Context,
}
//绑定其他相关版本
private fun bindRelatedVersion(viewHolder: GameDetailRelatedVersionViewHolder, relatedVersion: ArrayList<GameDetailEntity.RelatedVersion>?) {
private fun bindRelatedVersion(viewHolder: GameDetailRelatedVersionViewHolder, itemData: DetailEntity) {
val relatedVersion = itemData.relatedVersion
itemData.paddingBottom = DisplayUtils.dip2px(16F)
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
@ -317,8 +342,13 @@ class DescAdapter(context: Context,
}
//绑定图片推荐
private fun bindImageViewHolder(viewHolder: GameDetailRecommendImageViewHolder, recommendedImage: LinkEntity?) {
private fun bindImageViewHolder(viewHolder: GameDetailRecommendImageViewHolder, itemData: DetailEntity) {
val recommendedImage = itemData.imageRecommend
viewHolder.binding.link = recommendedImage
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
viewHolder.binding.root.setOnClickListener {
MtaHelper.onEvent("游戏详情_新", "图片推荐", gameName + "+${recommendedImage?.title}")
if (!TextUtils.isEmpty(recommendedImage?.communityId)) {
@ -333,7 +363,12 @@ class DescAdapter(context: Context,
}
//绑定视频
private fun bindVideosViewHolder(viewHolder: GameVideoGalleryViewHolder, videos: ArrayList<GameDetailEntity.Video>?, videoCount: Int) {
private fun bindVideosViewHolder(viewHolder: GameVideoGalleryViewHolder, itemData: DetailEntity, videoCount: Int) {
val videos = itemData.video
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
@ -366,8 +401,13 @@ class DescAdapter(context: Context,
}
//绑定图片
private fun bindImageGalleryViewHolder(viewHolder: GameImageGalleryViewHolder, gallery: ArrayList<String>?) {
private fun bindImageGalleryViewHolder(viewHolder: GameImageGalleryViewHolder, itemData: DetailEntity) {
val gallery = itemData.gallery
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
val params = layoutParams as ConstraintLayout.LayoutParams
@ -385,11 +425,16 @@ class DescAdapter(context: Context,
}
//绑定更新内容
private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, updateContent: UpdateContent?) {
private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, itemData: DetailEntity) {
val updateContent = itemData.update
holder.binding.containerPaddingTop = itemData.paddingTop
holder.binding.containerPaddingBottom = itemData.paddingBottom
holder.binding.contentTv.text = updateContent?.updateDes ?: ""
val maxDesLines = if (mExpandSparseBooleanArray.get(holder.adapterPosition)) Int.MAX_VALUE else 4
holder.binding.contentTv.setExpandMaxLines(maxDesLines)
holder.binding.contentTv.setIsExpanded(Int.MAX_VALUE == maxDesLines)
holder.binding.executePendingBindings()
holder.binding.contentTv.setExpandCallback {
mExpandSparseBooleanArray.put(holder.adapterPosition, true)
MtaHelper.onEvent("游戏详情_新", "展开更新内容", gameName)
@ -408,8 +453,13 @@ class DescAdapter(context: Context,
}
//绑定最近开服
private fun bindLatestServiceViewHolder(viewHolder: GameLatestServiceViewHolder, server: GameDetailServer?) {
private fun bindLatestServiceViewHolder(viewHolder: GameLatestServiceViewHolder, itemData: DetailEntity) {
val server = itemData.server
viewHolder.binding.serviceRv.isNestedScrollingEnabled = false
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
if (!server!!.calendar.isNullOrEmpty()) {
viewHolder.binding.serviceRv.visibility = View.VISIBLE
@ -444,12 +494,17 @@ class DescAdapter(context: Context,
DialogUtils.showKaifuRemindDialog(mContext, server.des, gameName)
}
}
}
//绑定攻略文章
private fun bindRaidersViewHolder(viewHolder: GameRaidersGalleryViewHolder, article: ArrayList<NewsEntity>?) {
private fun bindRaidersViewHolder(viewHolder: GameRaidersGalleryViewHolder, itemData: DetailEntity) {
val article = itemData.article
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
val params = layoutParams as ConstraintLayout.LayoutParams
@ -472,7 +527,11 @@ class DescAdapter(context: Context,
}
//绑定礼包
private fun bindLibaoViewHolder(viewHolder: GameLibaoGalleryViewHolder, libao: ArrayList<LibaoEntity>?) {
private fun bindLibaoViewHolder(viewHolder: GameLibaoGalleryViewHolder, itemData: DetailEntity) {
val libao = itemData.libao
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
viewHolder.binding.galleryRv.apply {
background = ContextCompat.getDrawable(mContext, R.drawable.bg_shape_f8_radius_5)
@ -492,16 +551,24 @@ class DescAdapter(context: Context,
}
//绑定游戏信息
private fun bindGameDetailInfoViewHolder(viewHolder: GameDetailInfoViewHolder, info: GameInfo?) {
private fun bindGameDetailInfoViewHolder(viewHolder: GameDetailInfoViewHolder, itemData: DetailEntity) {
val info = itemData.info
viewHolder.binding.containerPaddingTop = itemData.paddingTop
viewHolder.binding.containerPaddingBottom = itemData.paddingBottom
viewHolder.binding.executePendingBindings()
if (!info!!.topTags.isNullOrEmpty()) {
viewHolder.binding.labelsLl.visibility = View.VISIBLE
viewHolder.binding.labelsLl.removeAllViews()
val tags = info.topTags.take(4)
tags.forEach {
viewHolder.binding.labelsLl.addView(createGameInfoLabel(it.name))
tags.forEachIndexed { index, tag ->
viewHolder.binding.labelsLl.addView(createGameInfoLabel(tag.name, index != 0))
}
}
viewHolder.binding.gameInfoRv.isNestedScrollingEnabled = false
viewHolder.binding.shouldBoundToNextItem = itemData.shouldBoundTogetherWithNextItem
updateBoundableContainerBackground(viewHolder.binding.container, false, itemData.shouldBoundTogetherWithNextItem)
if (viewHolder.binding.gameInfoRv.adapter == null) {
viewHolder.binding.gameInfoRv.apply {
val infoAdapter = GameDetailInfoItemAdapter(mContext, info, mViewModel, gameName
@ -523,7 +590,7 @@ class DescAdapter(context: Context,
}
}
layoutManager = gridLayoutManager
addItemDecoration(GridSpacingItemColorDecoration(context, 0, 10, R.color.transparent))
addItemDecoration(GridSpacingItemColorDecoration(context, 24, 10, R.color.transparent))
viewHolder.binding.dividerView.goneIf(info.topTags.isEmpty() || infoAdapter.datas.size == 0)
}
}
@ -591,27 +658,34 @@ class DescAdapter(context: Context,
MtaHelper.onEvent("游戏详情_新", "自定义栏目正文_图片", "${gameName}-${customColumn.name}")
titleHintTv.performClick()
}
val linkClosure: (LinkEntity) -> Unit = {
// 当配置的是不需要 id 也能跳转的时候直接跳转,否则都得根据是否有 ID 判断跳不跳
if (it.type == "top_game_comment"
|| it.type == "server"
|| it.type == "feedback") {
it.name = gameName
it.text = mViewModel.game?.getGameCategory().toString()
DirectUtils.directToLinkPage(mContext, it, StringUtils.buildString(mEntrance, "游戏详情[", gameName, "]:自定义栏目"), "")
} else if (!it.link.isNullOrEmpty()) {
DirectUtils.directToLinkPage(mContext, it, StringUtils.buildString(mEntrance, "游戏详情[", gameName, "]:自定义栏目"), "")
}
}
titleHintTv.setOnClickListener {
MtaHelper.onEvent("游戏详情_新", "自定义栏目标题后跳转", "${gameName}-${customColumn.name}-${customColumn.nameLink?.value}")
// 当配置的是不需要 id 也能跳转的时候直接跳转,否则都得根据是否有 ID 判断跳不跳
if (customColumn.nameLink?.type == "top_game_comment"
|| customColumn.nameLink?.type == "server"
|| customColumn.nameLink?.type == "feedback") {
DirectUtils.directToLinkPage(mContext, customColumn.nameLink!!, StringUtils.buildString(mEntrance, "游戏详情[", gameName, "]:自定义栏目"), "")
} else if (!customColumn.nameLink?.link.isNullOrEmpty()) {
DirectUtils.directToLinkPage(mContext, customColumn.nameLink!!, StringUtils.buildString(mEntrance, "游戏详情[", gameName, "]:自定义栏目"), "")
}
linkClosure(customColumn.nameLink ?: LinkEntity())
}
linkHintIv.setOnClickListener { linkHintTv.performClick() }
linkHintArrowIv.setOnClickListener { linkHintTv.performClick() }
linkHintTv.setOnClickListener {
MtaHelper.onEvent("游戏详情_新", "自定义栏目右上角跳转", "${gameName}-${customColumn.name}-${customColumn.link?.value}")
DirectUtils.directToLinkPage(mContext, customColumn.link!!, StringUtils.buildString(mEntrance, "游戏详情[", gameName, "]:自定义栏目"), "")
linkClosure(customColumn.link ?: LinkEntity())
}
}
private fun createGameInfoLabel(label: String): TextView {
private fun createGameInfoLabel(label: String, hasDividingLine: Boolean = false): TextView {
return TextView(mContext).apply {
val params = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT)
params.weight = 1f
@ -619,6 +693,10 @@ class DescAdapter(context: Context,
textSize = 13F
setTextColor(ContextCompat.getColor(mContext, R.color.text_666666))
text = label
if (hasDividingLine) {
compoundDrawablePadding = DisplayUtils.dip2px(12f)
setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(context, R.drawable.game_detail_info_dividing_line), null, null, null)
}
}
}

View File

@ -23,7 +23,6 @@ import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.halo.assistant.HaloApp
import kotlinx.android.synthetic.main.layout_video_detail_surface.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

View File

@ -2,8 +2,6 @@ package com.gh.gamecenter.gamedetail.desc
import android.annotation.SuppressLint
import android.app.Application
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Build
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
@ -23,7 +21,6 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Util_System_Phone_State
import com.squareup.picasso.Picasso
import com.squareup.picasso.Target
import com.walkud.rom.checker.RomIdentifier
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -199,12 +196,25 @@ class DescViewModel(application: Application,
// 装饰列表数据
fun decorateList(detailEntityList: ArrayList<DetailEntity>): ArrayList<DetailEntity> {
// A 把低权重的自定义栏目转化为新的低权重自定义栏目 item
for (rawItem in detailEntityList) {
if (rawItem.type == DetailEntity.Type.CUSTOM_COLUMN.value) {
if (rawItem.customColumn?.order ?: -1 <= 0) {
rawItem.type = DetailEntity.Type.INFERIOR_CUSTOM_COLUMN.value
}
// // A 把低权重的自定义栏目转化为新的低权重自定义栏目 item // DEPRECATED
// for (rawItem in detailEntityList) {
// if (rawItem.type == DetailEntity.Type.CUSTOM_COLUMN.value) {
// if (rawItem.customColumn?.order ?: -1 <= 0) {
// rawItem.type = DetailEntity.Type.INFERIOR_CUSTOM_COLUMN.value
// }
// }
// }
val specialPadding = DisplayUtils.dip2px(12F)
val defaultPadding = DisplayUtils.dip2px(15F)
// A 确定每个 item 的上下内边距
for ((index, rawItem) in detailEntityList.withIndex()) {
rawItem.paddingTop = defaultPadding
rawItem.paddingBottom = defaultPadding
if (index == 0) {
rawItem.paddingTop = specialPadding
}
}
@ -222,11 +232,15 @@ class DescViewModel(application: Application,
}
}
// C 标记"公告"、"自定义栏目"的UI样式是否合并在一起
// C 标记"公告"、"自定义栏目"、"详细信息" 的UI样式是否合并在一起
for ((index, rawItem) in detailEntityList.withIndex()) {
if (rawItem.type == DetailEntity.Type.NOTICE.value || rawItem.type == DetailEntity.Type.CUSTOM_COLUMN.value) {
if (rawItem.type == DetailEntity.Type.NOTICE.value
|| rawItem.type == DetailEntity.Type.CUSTOM_COLUMN.value
|| rawItem.type == DetailEntity.Type.GAME_INFO.value) {
if (index + 1 != detailEntityList.size
&& (detailEntityList[index + 1].type == DetailEntity.Type.CUSTOM_COLUMN.value || detailEntityList[index + 1].type == DetailEntity.Type.NOTICE.value)) {
&& (detailEntityList[index + 1].type == DetailEntity.Type.CUSTOM_COLUMN.value
|| detailEntityList[index + 1].type == DetailEntity.Type.NOTICE.value
|| detailEntityList[index + 1].type == DetailEntity.Type.GAME_INFO.value)) {
rawItem.shouldBoundTogetherWithNextItem = true
detailEntityList[index + 1].shouldBoundTogetherWithPreviousItem = true
}
@ -246,11 +260,9 @@ class DescViewModel(application: Application,
if (item.type == DetailEntity.Type.CUSTOM_COLUMN.value) {
item.customColumn?.infoTag?.let {
for (tag in it) {
Picasso.with(getApplication()).load(tag.icon).into(object : Target {
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
override fun onBitmapFailed(errorDrawable: Drawable?) {}
override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {}
})
tryWithDefaultCatch {
Picasso.with(getApplication()).load(tag.icon).fetch()
}
}
}
}

View File

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.SpanBuilder
import com.gh.common.util.tryWithDefaultCatch
import com.gh.common.view.CenterImageSpan
import com.gh.common.view.CustomLinkMovementMethod
import com.gh.gamecenter.R
@ -51,22 +52,24 @@ class GameDetailCustomColumnAdapter(context: Context)
color ?: "#000000")
.build()
Picasso.with(mContext).load(icon)
.priority(Picasso.Priority.HIGH)
.into(object : Target {
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
viewHolder.contentTv.movementMethod = CustomLinkMovementMethod.getInstance()
viewHolder.contentTv.text = spannable
}
override fun onBitmapFailed(errorDrawable: Drawable?) {}
override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
val bitmapDrawable = BitmapDrawable(mContext.resources, bitmap)
bitmapDrawable.setBounds(0, 0, DensityUtil.dip2px(12F), DensityUtil.dip2px(12F))
spannable.setSpan(CenterImageSpan(bitmapDrawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
viewHolder.contentTv.movementMethod = CustomLinkMovementMethod.getInstance()
viewHolder.contentTv.text = spannable
}
})
tryWithDefaultCatch {
Picasso.with(mContext).load(icon)
.priority(Picasso.Priority.HIGH)
.into(object : Target {
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
viewHolder.contentTv.movementMethod = CustomLinkMovementMethod.getInstance()
viewHolder.contentTv.text = spannable
}
override fun onBitmapFailed(errorDrawable: Drawable?) {}
override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
val bitmapDrawable = BitmapDrawable(mContext.resources, bitmap)
bitmapDrawable.setBounds(0, 0, DensityUtil.dip2px(12F), DensityUtil.dip2px(12F))
spannable.setSpan(CenterImageSpan(bitmapDrawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
viewHolder.contentTv.movementMethod = CustomLinkMovementMethod.getInstance()
viewHolder.contentTv.text = spannable
}
})
}
}
}

View File

@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.base.OnListClickListener
import com.gh.common.util.LibaoUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.RandomUtils
import com.gh.common.util.fromHtml
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameLibaoBinding
import com.gh.gamecenter.entity.LibaoEntity
@ -46,12 +46,24 @@ class GameLibaoAdapter(val context: Context, val libaos: ArrayList<LibaoEntity>,
when (holder) {
is LibaoViewHolder -> {
holder.binding.libaoNameTv.text = libaoEntity.name
holder.binding.contentTv.text = libaoEntity.content
holder.binding.contentTv.text = libaoEntity.content?.fromHtml()
val total = libaoEntity.total
val available = libaoEntity.available
if (total != 0) {
holder.binding.libaoSchedulePb.progress = ((available / total.toFloat()) * 100).toInt()
holder.binding.remainingTv.text = "剩余${RandomUtils.getInt((available) / total.toDouble() * 100)}%"
val availablePercent = (available) / total.toFloat() * 100
val count = when {
availablePercent >= 1F -> {
availablePercent.toInt()
}
availablePercent == 0F -> {
0
}
else -> {
1
}
}
holder.binding.remainingTv.text = "剩余${count}%"
holder.binding.libaoSchedulePb.progress = count
}
LibaoUtils.setLiBaoBtnStatusRound(holder.binding.receiveTv, libaoEntity.status, context)
holder.itemView.setOnClickListener {

View File

@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.GameViewUtils
import com.gh.common.util.ImageUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.StringUtils
@ -45,6 +46,7 @@ class GameRelatedVersionAdapter(val context: Context, val gameName: String, val
when (holder) {
is GameDetailRelatedViewHolder -> {
holder.binding.relatedVersion = relatedVersion
GameViewUtils.setLabelList(context, holder.binding.gameLabelLl, "type", relatedVersion.gameTags)
ImageUtils.display(holder.binding.gameIconSdv, relatedVersion.gameIcon)
holder.itemView.setOnClickListener {
MtaHelper.onEvent("游戏详情_新", "相关游戏版本", "${gameName}+${relatedVersion.gameName}")

View File

@ -12,7 +12,9 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.*
import com.gh.common.util.DirectUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.TimeUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameDetailBigEventBinding
import com.gh.gamecenter.gamedetail.entity.BigEvent

View File

@ -1,13 +1,15 @@
package com.gh.gamecenter.gamedetail.dialog
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.*
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.base.fragment.BaseDialogFragment
import com.gh.common.dialog.BaseTrackableDialogFragment
import com.gh.common.util.DisplayUtils
import com.gh.common.util.MtaHelper
@ -18,7 +20,6 @@ import com.gh.gamecenter.entity.TagStyleEntity
import com.gh.gamecenter.tag.TagsActivity
import com.halo.assistant.HaloApp
import kotlinx.android.synthetic.main.dialog_game_tags.view.*
import java.util.concurrent.atomic.AtomicBoolean
class GameTagsDialog : BaseTrackableDialogFragment() {
@ -26,6 +27,12 @@ class GameTagsDialog : BaseTrackableDialogFragment() {
lateinit var mTagStyles: ArrayList<TagStyleEntity>
lateinit var mGameName: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mGameName = requireArguments().getString("gameName") ?: ""
mTagStyles = requireArguments().getParcelableArrayList("tagStyles") ?: ArrayList()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val createDialog = super.onCreateDialog(savedInstanceState)
createDialog.setCanceledOnTouchOutside(true)
@ -76,8 +83,7 @@ class GameTagsDialog : BaseTrackableDialogFragment() {
companion object {
fun showGameTagsDialog(context: FragmentActivity, tagStyles: ArrayList<TagStyleEntity>, gameName: String) {
val dialog = GameTagsDialog().apply {
mTagStyles = tagStyles
mGameName = gameName
arguments = bundleOf("gameName" to gameName, "tagStyles" to tagStyles)
}
dialog.show(context.supportFragmentManager, DownloadDialog::class.java.name)
}

View File

@ -33,7 +33,11 @@ data class DetailEntity(
// 是否与前一个 item 连成整体
var shouldBoundTogetherWithPreviousItem: Boolean = false,
// 是否与后一个 item 连成整体
var shouldBoundTogetherWithNextItem: Boolean = false) {
var shouldBoundTogetherWithNextItem: Boolean = false,
// 上 padding
var paddingTop: Int = 0,
// 下 padding
var paddingBottom: Int = 0) {
enum class Type(val value: String) {
IMAGE_GALLERY("gallery"),

View File

@ -1,10 +1,7 @@
package com.gh.gamecenter.gamedetail.entity
import androidx.annotation.Keep
import com.gh.gamecenter.entity.GameDetailEntity
import com.gh.gamecenter.entity.LinkEntity
import com.gh.gamecenter.entity.MeEntity
import com.gh.gamecenter.entity.TagStyleEntity
import com.gh.gamecenter.entity.*
import com.google.gson.annotations.SerializedName
@Keep
@ -26,6 +23,8 @@ data class NewGameDetailEntity(
@SerializedName("me")
var me: MeEntity = MeEntity(),
var event: BigEvent? = null,//游戏大事件
@SerializedName("detail_dialog")
var detailDialog: GameEntity.Dialog? = null,
@SerializedName("tag_style")
var tagStyle: ArrayList<TagStyleEntity> = ArrayList(),
@SerializedName("detail_tab")

View File

@ -52,7 +52,7 @@ public class GameLibaoGalleryAdapter extends BaseRecyclerAdapter<GameLibaoGaller
}
holder.libaoDes.setText(content);
if (libaoEntity.getStatus() == null) return;
LibaoUtils.setLiBaoBtnStatus(holder.libaoBtn, libaoEntity.getStatus(), mContext);
LibaoUtils.setLiBaoBtnStatusRound(holder.libaoBtn, libaoEntity.getStatus(), mContext);
holder.libaoBtn.setOnTouchListener((v, event) -> {
DataUtils.onMtaEvent(mContext, "游戏详情_新", "游戏礼包_领取", mGameName + "->" + libaoEntity.getName());

View File

@ -28,8 +28,8 @@ import com.lightgame.utils.Utils
class HistoryApkListAdapter(context: Context, private var mViewModel: HistoryApkListViewModel) : ListAdapter<GameEntity>(context) {
private var mExpandSparseBooleanArray = SparseBooleanArray()
private var mDescExpandedMarginRight = 0
private var mDescShrankMarginRight = 0
private var mDescExpandedMarginRight = -1
private var mDescShrankMarginRight = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
@ -137,8 +137,8 @@ class HistoryApkListAdapter(context: Context, private var mViewModel: HistoryApk
// damn, 设计师说要存在下载按钮和不存在下载按钮时有不一样的收起/展开效果
private fun updateDescMarginRight(descTv: TextView, isExpanded: Boolean, isDownloadBtnVisible: Boolean) {
if (mDescExpandedMarginRight == 0) {
mDescExpandedMarginRight = mContext.resources.getDimension(R.dimen.history_apk_desc_expanded_margin_right).toInt()
if (mDescExpandedMarginRight == -1) {
mDescExpandedMarginRight = 0
mDescShrankMarginRight = mContext.resources.getDimension(R.dimen.history_apk_desc_shrank_margin_right).toInt()
}

View File

@ -123,8 +123,8 @@ class RatingViewModel(application: Application, val game: GameEntity) : ListView
})
}
fun unVoteComment(commentId: String, callback: () -> Unit){
mApi.unvoteGameComment(game.id,commentId)
fun unVoteComment(commentId: String, callback: () -> Unit) {
mApi.unvoteGameComment(game.id, commentId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {

View File

@ -52,7 +52,6 @@ class HistoryGameListAdapter(context: Context, private val mViewModel: HistoryGa
holder.initServerType(gameEntity)
holder.binding.subjectTag = "type"
holder.binding.executePendingBindings()
holder.binding.gameLibaoIcon.visibleIf(gameEntity.isLibaoExists)
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(mContext, gameEntity.id, "(浏览记录:游戏)")

View File

@ -1,7 +1,6 @@
package com.gh.gamecenter.libao;
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
@ -30,6 +29,7 @@ import com.lightgame.utils.Utils;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@ -287,7 +287,7 @@ class Libao3FragmentAdapter extends BaseRecyclerAdapter<RecyclerView.ViewHolder>
});
holder.libaoBtnStatus.setText("复制");
holder.libaoBtnStatus.setBackgroundResource(R.drawable.textview_blue_style);
holder.libaoBtnStatus.setBackgroundResource(R.drawable.button_normal_round_style);
} else if (viewHolder instanceof FooterViewHolder) {
initFooterViewHolder((FooterViewHolder) viewHolder);
}

View File

@ -1,9 +1,6 @@
package com.gh.gamecenter.libao;
import android.content.Context;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
@ -28,6 +25,9 @@ import com.lightgame.adapter.BaseRecyclerAdapter;
import java.util.ArrayList;
import java.util.List;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
@ -160,7 +160,7 @@ public class LibaoHistoryAdapter extends BaseRecyclerAdapter<ViewHolder> {
ImageUtils.display(viewHolder.libaoGameIcon, libaoEntity.getIcon());
//领取状态
LibaoUtils.setLiBaoBtnStatus(viewHolder.libaoBtnStatus
LibaoUtils.setLiBaoBtnStatusRound(viewHolder.libaoBtnStatus
, !TextUtils.isEmpty(libaoEntity.getStatus()) ? libaoEntity.getStatus() : "unshelve", mContext);
} else {

View File

@ -41,6 +41,7 @@ import com.gh.gamecenter.qa.select.CommunitiesSelectActivity
import com.gh.gamecenter.qa.select.CommunitiesSelectWrapperFragment
import com.google.android.material.tabs.TabLayout
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import kotterknife.bindView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -151,16 +152,12 @@ class CommunityFragment : BaseLazyTabFragment() {
mColumnViewModel.tagGroupsObservable.observe(this, Observer {
// 如果专栏数据为空,则隐藏专栏模块
// todo 无法动态删除 ViewPage item
if (it.isNullOrEmpty() && mTabLayout.tabCount == 4) {
if (it.isNullOrEmpty()) {
// remove
mTabLayout.removeTabAt(INDEX_COLUMN)
mTabTitleList.removeAt(INDEX_COLUMN)
} else if ((!it.isNullOrEmpty()) && mTabLayout.tabCount == 3) {
mTabLayout.getTabAt(INDEX_COLUMN)?.view?.visibility = View.GONE
} else if (!it.isNullOrEmpty()) {
// add
val columnTab = mTabLayout.newTab().setText(TAB_TITLE_COLUMN)
columnTab.customView = createDefaultTabCustomView(TAB_TITLE_COLUMN)
mTabLayout.addTab(columnTab, INDEX_COLUMN)
mTabTitleList.add(INDEX_COLUMN, TAB_TITLE_COLUMN)
mTabLayout.getTabAt(INDEX_COLUMN)?.view?.visibility = View.VISIBLE
}
mBaseHandler.postDelayed({

View File

@ -35,7 +35,6 @@ import com.lightgame.listeners.OnBackPressedListener
import com.lightgame.utils.AppManager
import com.scwang.smartrefresh.layout.footer.ClassicsFooter
import com.squareup.picasso.Picasso
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.fragment_video_detail_container.*
import kotlinx.android.synthetic.main.reuse_no_connection.*
import kotlinx.android.synthetic.main.reuse_none_data.*
@ -57,7 +56,6 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
private var mIsHomeVideo = false//是否是视频总入口
private var mExposureListener: ExposureListener? = null
private var mScheduledPlayDisposable: Disposable? = null
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
@ -104,7 +102,6 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
toolbar.setNavigationIcon(R.drawable.ic_toolbar_back_white)
toolbar.setNavigationOnClickListener { requireActivity().finish() }
}
smartRefreshLayout.setNoMoreData(true)
mViewModel.videoList.observeNonNull(this) {
@ -220,10 +217,6 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
override fun onPageSelected(position: Int, isBottom: Boolean) {
smartRefreshLayout.isEnableLoadMore = isBottom
smartRefreshLayout.setNoMoreData(isBottom)
if (mScheduledPlayDisposable != null && !mScheduledPlayDisposable!!.isDisposed) {
mScheduledPlayDisposable!!.dispose()
mScheduledPlayDisposable = null
}
val isShowClick = SPUtils.getBoolean(Constants.SP_SHOW_CLICK_GUIDE)
if (!isShowClick) {
showClickGuide()
@ -254,33 +247,26 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
if (pos == -1) return
val videoView = findVisibleVideoViewByPosition()
videoView?.observeVolume(requireActivity() as AppCompatActivity)
if (userVisibleHint) {
//延时处理,快速滑动不播放视频
mScheduledPlayDisposable = rxTimer(1) {
if (it >= 100) {
mScheduledPlayDisposable?.dispose()
mScheduledPlayDisposable = null
if (pos + 2 <= mAdapter.videoList.size - 1) {//预加载视频
ExoCacheManager.preload(mAdapter.videoList[pos + 1].url)
ExoCacheManager.preload(mAdapter.videoList[pos + 2].url)
Picasso.with(context).load(mAdapter.videoList[pos + 1].getThumb()).fetch()
Picasso.with(context).load(mAdapter.videoList[pos + 2].getThumb()).fetch()
} else if (pos + 1 <= mAdapter.videoList.size - 1) {
ExoCacheManager.preload(mAdapter.videoList[pos + 1].url)
Picasso.with(context).load(mAdapter.videoList[pos + 1].getThumb()).fetch()
}
if (mLastPosition != pos /*&& videoView?.isInPlayingState != true*/) {
ExoCacheManager.cancel(mAdapter.videoList[pos].url)
CustomManager.releaseAllVideos("detail_${mViewModel.uuid}")
videoView?.startButton?.performClick()
mBaseHandler.postDelayed({
videoView?.updateMuteStatus()
}, 500)
}
mLastPosition = pos
mViewModel.addHistoryRecord(mAdapter.videoList[pos])
}
if (isSupportVisible) {
if (pos + 2 <= mAdapter.videoList.size - 1) {//预加载视频
ExoCacheManager.preload(mAdapter.videoList[pos + 1].url)
ExoCacheManager.preload(mAdapter.videoList[pos + 2].url)
Picasso.with(context).load(mAdapter.videoList[pos + 1].getThumb()).fetch()
Picasso.with(context).load(mAdapter.videoList[pos + 2].getThumb()).fetch()
} else if (pos + 1 <= mAdapter.videoList.size - 1) {
ExoCacheManager.preload(mAdapter.videoList[pos + 1].url)
Picasso.with(context).load(mAdapter.videoList[pos + 1].getThumb()).fetch()
}
if (mLastPosition != pos /*&& videoView?.isInPlayingState != true*/) {
ExoCacheManager.cancel(mAdapter.videoList[pos].url)
CustomManager.releaseAllVideos("detail_${mViewModel.uuid}")
videoView?.startButton?.performClick()
mBaseHandler.postDelayed({
videoView?.updateMuteStatus()
}, 500)
}
mLastPosition = pos
mViewModel.addHistoryRecord(mAdapter.videoList[pos])
}
mViewModel.videoList.value?.apply {
@ -434,10 +420,6 @@ class VideoDetailContainerFragment : BaseLazyFragment(), OnBackPressedListener {
}
override fun onFragmentPause() {
if (mScheduledPlayDisposable != null && !mScheduledPlayDisposable!!.isDisposed) {
mScheduledPlayDisposable!!.dispose()
mScheduledPlayDisposable = null
}
DownloadManager.getInstance(requireContext()).removeObserver(dataWatcher)
val videoView = findVisibleVideoViewByPosition()
videoView?.run {

View File

@ -33,6 +33,7 @@ import com.gh.common.util.ShareUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.MessageDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.entity.CommentnumEntity;
import com.gh.gamecenter.entity.MeEntity;
import com.gh.gamecenter.entity.ToolBoxEntity;
@ -75,6 +76,7 @@ public class WebFragment extends NormalFragment {
public static final String KEY_LEAVE_WEB_PAGE_TO_HANDLE_TITLE = "leave_web_page_to_handle_title";
public static final String KEY_REQUIRE_BACK_CONFIRMATION = "require_back_confirmation";
public static final String KEY_BACK_CONFIRMATION_CONTENT = "back_confirmation_content";
public static final String KEY_OPEN_NATIVE_PAGE = "open_native_page";
public static final String KEY_GAME_NAME = "game_name";
@BindView(R.id.news_webview)
@ -102,6 +104,7 @@ public class WebFragment extends NormalFragment {
private boolean mIsTools;
private boolean mIsBindWechat;
private boolean mIsBackpressRequireConfirmation;
private boolean mIsOpenNativePage;//网页打开新页面是否重新打开一个原生页面
private String mBackConfirmationContent;
private String mGameName;
@ -175,7 +178,7 @@ public class WebFragment extends NormalFragment {
mToolBoxEntity.getDes(),
ShareUtils.ShareType.tools);
} else {
curActivity.showShare(getArguments().getString(EntranceUtils.KEY_URL),
curActivity.showShare(TextUtils.isEmpty(mShareEntity.getUrl()) ? getArguments().getString(EntranceUtils.KEY_URL) : mShareEntity.getUrl(),
mShareEntity.getIcon(),
mShareEntity.getTitle(),
mShareEntity.getDescription(),
@ -249,6 +252,7 @@ public class WebFragment extends NormalFragment {
newsId = args.getString(EntranceUtils.KEY_NEWSID);
mIsBackpressRequireConfirmation = args.getBoolean(KEY_REQUIRE_BACK_CONFIRMATION);
mBackConfirmationContent = args.getString(KEY_BACK_CONFIRMATION_CONTENT);
mIsOpenNativePage = args.getBoolean(KEY_OPEN_NATIVE_PAGE, false);
mGameName = args.getString(KEY_GAME_NAME);
boolean leaveWebpageToHandleTitle = args.getBoolean(KEY_LEAVE_WEB_PAGE_TO_HANDLE_TITLE, false);
@ -273,7 +277,13 @@ public class WebFragment extends NormalFragment {
// 自适应屏幕
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
try {
// 部分设备不支持 TEXT_AUTOSIZING
// 报 java.lang.IllegalArgumentException: WebViewClassic does not support TEXT_AUTOSIZING layout mode
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
} catch (Throwable throwable) {
// do nothing
}
}
// 用webview打开url
@ -281,7 +291,13 @@ public class WebFragment extends NormalFragment {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isAdded()) {
return DefaultWebViewUrlHandler.interceptUrl(requireContext(), url, mEntrance + "+(光环浏览器)");
// return DefaultWebViewUrlHandler.interceptUrl(requireContext(), url, mEntrance + "+(光环浏览器)");
boolean b = DefaultWebViewUrlHandler.interceptUrl(requireContext(), url, mEntrance + "+(光环浏览器)");
if (mIsOpenNativePage && !b) {
startActivity(WebActivity.getIntent(requireContext(), url, mNavigationTitle, true, true));
return true;
}
return b;
} else {
return false;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 KiB

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/text_eeeeee" />
<size
android:width="1dp"
android:height="14dp" />
</shape>

View File

@ -27,9 +27,8 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="35dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:layout_height="wrap_content"
android:padding="12dp"
android:gravity="center_vertical"
android:background="@drawable/game_detail_video_bottom_bg"
android:layout_alignParentBottom="true">
@ -38,7 +37,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="11sp"
android:textSize="12sp"
android:includeFontPadding="false"
tools:text="光环老司机" />
<TextView
@ -49,8 +49,9 @@
android:drawableLeft="@drawable/ic_game_detail_video_vote"
android:drawablePadding="4dp"
android:text="0"
android:includeFontPadding="false"
android:textColor="@color/white"
android:textSize="11sp"
android:textSize="12sp"
tools:text="0" />
</RelativeLayout>
</RelativeLayout>

View File

@ -34,18 +34,6 @@
app:layout_constraintTop_toTopOf="parent"
app:roundedCornerRadius="5dp" />
<ImageView
android:id="@+id/libao_icon"
visibleGone="@{game.isLibaoExists}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="@drawable/game_libao_icon"
android:visibility="visible"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView

View File

@ -2,15 +2,32 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="shouldBoundToNextItem"
type="Boolean" />
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
<import type="com.gh.common.util.DisplayUtils" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingTop="@{containerPaddingTop}"
android:paddingRight="20dp"
android:paddingBottom="11dp">
android:paddingBottom="@{shouldBoundToNextItem ? 0 : containerPaddingBottom}">
<TextView
android:id="@+id/titleTv"
@ -20,10 +37,12 @@
android:textColor="@color/text_333333"
android:textSize="18sp"
android:textStyle="bold"
android:includeFontPadding="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
@ -41,20 +60,20 @@
android:id="@+id/labelsLl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
android:weightSum="4"
android:orientation="horizontal"/>
android:weightSum="4" />
<View
android:id="@+id/dividerView"
android:layout_width="match_parent"
android:layout_height="12dp"
android:visibility="gone"/>
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gameInfoRv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -3,14 +3,25 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
<import type="com.gh.common.util.DisplayUtils"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="11dp"
android:paddingTop="@{containerPaddingTop == 0 ? DisplayUtils.dip2px(16) : containerPaddingTop}"
android:paddingBottom="@{containerPaddingBottom == 0 ? DisplayUtils.dip2px(11) : containerPaddingBottom }"
android:background="@color/white">
<TextView
android:id="@+id/titleTv"
android:layout_width="wrap_content"
@ -20,6 +31,7 @@
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginLeft="20dp"
android:includeFontPadding="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -39,16 +39,6 @@
android:layout_centerInParent="true"
fresco:roundedCornerRadius="10dp" />
<ImageView
android:id="@+id/game_libao_icon"
visibleGone="@{game.libaoExists}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="@drawable/game_libao_icon"
android:visibility="visible" />
</RelativeLayout>
<TextView

View File

@ -113,26 +113,26 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="22dp">
android:layout_height="28dp">
<TextView
android:id="@+id/game_des"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="6dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="11dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:singleLine="true"
android:text="@{(game.apk.size > 0 &amp;&amp; !hideSize) ? game.getApk().get(0).getSize() + ` ` + game.brief : game.brief }"
android:textColor="@color/text_999999"
android:textSize="11sp" />
android:textSize="10sp" />
<LinearLayout
android:id="@+id/game_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2.5dp"
android:layout_marginTop="2dp"
android:orientation="horizontal"
android:visibility="gone">
@ -178,12 +178,12 @@
<LinearLayout
android:id="@+id/label_list"
gameLabelList="@{game}"
subjectTag="@{subjectTag}"
gameLabelList="@{game.tagStyle}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
android:orientation="horizontal" />
android:orientation="horizontal"
android:visibility="visible" />
</LinearLayout>

View File

@ -3,15 +3,24 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingTop="@{containerPaddingTop}"
android:paddingRight="20dp"
android:paddingBottom="11dp">
android:paddingBottom="@{containerPaddingBottom}">
<TextView
android:id="@+id/titleTv"
@ -20,6 +29,7 @@
android:text="最新开服"
android:textColor="@color/text_333333"
android:textSize="18sp"
android:includeFontPadding="false"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -3,13 +3,23 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="12dp"
android:paddingTop="@{containerPaddingTop}"
android:paddingRight="20dp"
android:paddingBottom="11dp"
android:paddingBottom="@{containerPaddingBottom}"
android:background="@color/white">
<TextView
@ -19,6 +29,7 @@
android:text="更新内容"
android:textColor="@color/text_333333"
android:textSize="18sp"
android:includeFontPadding="false"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -44,6 +55,7 @@
android:id="@+id/historyVersionTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
app:layout_constraintTop_toBottomOf="@+id/contentTv"
app:layout_constraintStart_toStartOf="parent"
android:textColor="@color/theme_font"

View File

@ -1,11 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical">
android:orientation="vertical"
android:paddingTop="@{containerPaddingTop}"
android:paddingBottom="@{containerPaddingBottom}">
<RelativeLayout
android:layout_width="match_parent"
@ -20,8 +32,8 @@
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:text="玩家评论"
android:includeFontPadding="false"
android:textColor="@color/text_333333"
android:paddingTop="16dp"
android:paddingBottom="13dp"
android:textSize="18sp"
android:textStyle="bold" />
@ -52,7 +64,6 @@
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="16dp"
android:background="@drawable/bg_shape_f8_radius_5"/>
</LinearLayout>

View File

@ -17,20 +17,28 @@
name="customColumn"
type="com.gh.gamecenter.gamedetail.entity.CustomColumn" />
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
<import type="android.text.TextUtils" />
<import type="com.gh.common.util.DisplayUtils" />
</data>
<FrameLayout
lazyPaddingTop="@{shouldBoundToPreviousItem ? 0 : 12}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingTop="12dp"
android:paddingRight="20dp">
android:paddingTop="@{shouldBoundToPreviousItem ? 0 : containerPaddingTop}"
android:paddingRight="20dp"
android:paddingBottom="@{shouldBoundToNextItem ? 0 : containerPaddingBottom}">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
@ -40,7 +48,7 @@
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingBottom="14dp">
android:paddingBottom="11dp">
<View
goneIf="@{!shouldBoundToPreviousItem}"
@ -62,7 +70,9 @@
app:layout_constraintTop_toTopOf="parent"
app:roundedCornerRadius="5dp"
app:viewAspectRatio="2"
tools:background="@color/placeholder_bg"
app:fadeDuration="500"
app:placeholderImage="@drawable/occupy"
app:placeholderImageScaleType="fitXY"
tools:layout_width="match_parent"
tools:visibility="visible" />
@ -223,6 +233,7 @@
goneIf="@{customColumn.infoTag == null || customColumn.infoTag.size() == 0}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="3dp"
app:layout_constraintTop_toBottomOf="@id/contentTv" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -12,6 +12,14 @@
name="shouldBoundToNextItem"
type="Boolean" />
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
<import type="com.gh.common.util.DisplayUtils" />
</data>
@ -20,7 +28,8 @@
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:paddingTop="@{shouldBoundToPreviousItem ? 0 : DisplayUtils.dip2px(12)}">
android:paddingTop="@{shouldBoundToPreviousItem ? 0 : containerPaddingTop}"
android:paddingBottom="@{shouldBoundToNextItem ? 0 : containerPaddingBottom}">
<View
goneIf="@{!shouldBoundToPreviousItem}"
@ -28,7 +37,8 @@
android:layout_height="1dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@color/EDEDED" />
android:background="@color/EDEDED"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/container"
@ -68,8 +78,8 @@
android:layout_toLeftOf="@id/arrowIv"
android:layout_toRightOf="@id/iconIv"
app:mvAnimDuration="1000"
app:mvSingleLine="true"
app:mvInterval="3000"
app:mvSingleLine="true"
app:mvTextColor="@color/fuli_detail"
app:mvTextSize="12sp" />
</RelativeLayout>

View File

@ -8,6 +8,14 @@
<variable
name="link"
type="com.gh.gamecenter.entity.LinkEntity" />
<variable
name="containerPaddingTop"
type="Integer" />
<variable
name="containerPaddingBottom"
type="Integer" />
</data>
<LinearLayout
@ -16,7 +24,8 @@
android:background="@android:color/white"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp">
android:paddingRight="20dp"
android:paddingBottom="@{containerPaddingBottom}">
<TextView
android:layout_width="wrap_content"
@ -27,7 +36,8 @@
android:textColor="@color/text_333333"
android:textSize="18sp"
android:textStyle="bold"
android:paddingTop="16dp"
android:includeFontPadding="false"
android:paddingTop="@{containerPaddingTop}"
android:paddingBottom="11dp"
tools:text="大图" />
@ -35,7 +45,6 @@
imageUrl="@{link.image}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="11dp"
app:placeholderImage="@drawable/occupy" />
</LinearLayout>

View File

@ -45,18 +45,6 @@
app:layout_constraintTop_toTopOf="parent"
app:roundedCornerRadius="5dp" />
<ImageView
android:id="@+id/libao_icon"
visibleGone="@{data.isLibaoExists}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="@drawable/game_libao_icon"
android:visibility="visible"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView

View File

@ -29,26 +29,24 @@
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="8dp"
android:text="@{relatedVersion.gameName}"
android:textColor="@color/text_333333"
android:textSize="14sp"
android:textStyle="bold"
android:text="@{relatedVersion.gameName}"
app:layout_constraintStart_toEndOf="@+id/gameIconSdv"
app:layout_constraintTop_toTopOf="@+id/gameIconSdv"
tools:text="武侠小掌门" />
<TextView
android:id="@+id/gameLabelTv"
<LinearLayout
android:id="@+id/gameLabelLl"
gameLabelList="@{relatedVersion.gameTags}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginBottom="8dp"
android:textColor="@color/text_333333"
android:textSize="11sp"
setGameTags="@{relatedVersion.gameTags}"
setMaxGameTags="@{3}"
android:layout_marginBottom="12dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@+id/gameIconSdv"
app:layout_constraintStart_toEndOf="@+id/gameIconSdv"
tools:text="全局加速/无需root" />
app:layout_constraintStart_toEndOf="@+id/gameIconSdv" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -8,9 +8,8 @@
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="18dp"
android:paddingRight="18dp">
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/libaoNameTv"
@ -28,35 +27,39 @@
<ProgressBar
android:id="@+id/libaoSchedulePb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="148dp"
android:layout_height="6dp"
android:layout_width="0dp"
android:layout_height="4dp"
android:layout_marginTop="12dp"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/progressbar_rating_style"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/remainingTv"
app:layout_constraintTop_toBottomOf="@+id/libaoNameTv" />
<TextView
android:id="@+id/remainingTv"
android:layout_width="wrap_content"
android:layout_width="52dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:textColor="@color/theme_font"
android:textSize="11sp"
android:gravity="start"
android:layout_marginRight="20dp"
app:layout_constraintBottom_toBottomOf="@+id/libaoSchedulePb"
app:layout_constraintStart_toEndOf="@+id/libaoSchedulePb"
app:layout_constraintTop_toTopOf="@+id/libaoSchedulePb"
app:layout_constraintEnd_toStartOf="@+id/receiveTv"
android:text="剩余0%"/>
<TextView
android:id="@+id/contentTv"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxWidth="212dp"
android:textColor="@color/text_999999"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="@+id/remainingTv"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/libaoSchedulePb" />

View File

@ -60,7 +60,7 @@
android:id="@+id/updateDescTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:layout_marginTop="11dp"
android:includeFontPadding="false"
android:lineSpacingExtra="4dp"
android:maxLines="3"

View File

@ -97,7 +97,7 @@
android:src="@drawable/bg_game_detail_rating_score" />
<TextView
setTextSize="@{rating.game.star>0?18:9}"
setTextSize="@{rating.game.star>0?18:8}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"

View File

@ -56,6 +56,7 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="bottom"
android:background="@drawable/bg_video_detail_bottom"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout

View File

@ -14,12 +14,13 @@
<TextView
android:id = "@+id/libao_copy_btn"
android:layout_width = "45dp"
android:layout_height = "25dp"
android:layout_width = "44dp"
android:layout_height = "24dp"
android:layout_alignParentRight = "true"
android:layout_centerVertical = "true"
android:background = "@drawable/textview_blue_style"
android:background = "@drawable/button_normal_round_style"
android:gravity = "center"
android:textSize="12sp"
android:text = "@string/libao_copy"
android:textColor = "@android:color/white" />

View File

@ -65,12 +65,13 @@
<TextView
android:id = "@+id/libaodetail_copy_btn"
android:layout_width = "60dp"
android:layout_height = "30dp"
android:layout_width = "56dp"
android:layout_height = "28dp"
android:layout_alignParentRight = "true"
android:layout_centerVertical = "true"
android:layout_marginLeft = "10dp"
android:gravity = "center"
android:textSize="12sp"
android:textColor = "@android:color/white" />
</LinearLayout >

View File

@ -16,12 +16,28 @@
android:gravity = "center_horizontal"
android:orientation = "vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:layout_marginBottom="22dp"
android:text="还没有收集到足够的评论,无法给出公正的评分"
android:gravity="center"
android:textSize="14sp"
android:visibility="gone"
android:includeFontPadding="false"
android:drawablePadding="4dp"
android:drawableLeft="@drawable/ic_game_detail_no_rating_tips"
android:textColor="@color/text_999999"
visibleGone="@{data.commentCount &lt;= 3}"/>
<LinearLayout
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:orientation = "horizontal"
android:layout_marginTop="32dp"
android:layout_marginBottom="16dp">
android:layout_marginTop="28dp"
android:layout_marginBottom="22dp"
visibleGone="@{data.commentCount > 3}">
<LinearLayout
android:layout_width = "wrap_content"
@ -39,11 +55,11 @@
android:src = "@drawable/bg_game_detail_rating_score" />
<TextView
setTextSize = "@{data.star.hits > 3? 18: 9}"
setTextSize = "@{data.commentCount > 3? 18: 8}"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_centerInParent = "true"
android:text = "@{data.star.hits > 3?(data.star.average == 10.0? `10`: data.star.average + ``): `评分过少`}"
android:text = "@{data.commentCount > 3?(data.star.average == 10.0? `10`: data.star.average + ``): `评分过少`}"
android:textColor = "@android:color/white"
tools:text = "8.5" />
</RelativeLayout >
@ -66,10 +82,10 @@
<com.gh.common.view.materialratingbar.MaterialRatingBar
style = "@style/Widget.MaterialRatingBar.RatingBar"
android:layout_width = "60dp"
android:layout_height = "10dp"
android:layout_height = "8dp"
android:isIndicator = "true"
android:minWidth = "12dp"
android:minHeight = "12dp"
android:minWidth = "8dp"
android:minHeight = "8dp"
android:rating = "5"
app:mrb_progressTint = "@color/theme" />
@ -95,10 +111,10 @@
<com.gh.common.view.materialratingbar.MaterialRatingBar
style = "@style/Widget.MaterialRatingBar.RatingBar"
android:layout_width = "60dp"
android:layout_height = "10dp"
android:layout_height = "8dp"
android:isIndicator = "true"
android:minWidth = "12dp"
android:minHeight = "12dp"
android:minWidth = "8dp"
android:minHeight = "8dp"
android:rating = "4"
app:mrb_progressTint = "@color/theme" />
@ -125,10 +141,10 @@
<com.gh.common.view.materialratingbar.MaterialRatingBar
style = "@style/Widget.MaterialRatingBar.RatingBar"
android:layout_width = "60dp"
android:layout_height = "10dp"
android:layout_height = "8dp"
android:isIndicator = "true"
android:minWidth = "12dp"
android:minHeight = "12dp"
android:minWidth = "8dp"
android:minHeight = "8dp"
android:rating = "3"
app:mrb_progressTint = "@color/theme" />
@ -155,10 +171,10 @@
<com.gh.common.view.materialratingbar.MaterialRatingBar
style = "@style/Widget.MaterialRatingBar.RatingBar"
android:layout_width = "60dp"
android:layout_height = "10dp"
android:layout_height = "8dp"
android:isIndicator = "true"
android:minWidth = "12dp"
android:minHeight = "12dp"
android:minWidth = "8dp"
android:minHeight = "8dp"
android:rating = "2"
app:mrb_progressTint = "@color/theme" />
@ -185,10 +201,10 @@
<com.gh.common.view.materialratingbar.MaterialRatingBar
style = "@style/Widget.MaterialRatingBar.RatingBar"
android:layout_width = "60dp"
android:layout_height = "10dp"
android:layout_height = "8dp"
android:isIndicator = "true"
android:minWidth = "12dp"
android:minHeight = "12dp"
android:minWidth = "8dp"
android:minHeight = "8dp"
android:rating = "1"
app:mrb_progressTint = "@color/theme" />
@ -240,8 +256,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop = "16dp">
android:orientation="horizontal">
<LinearLayout
android:id = "@+id/rating_amway_btn"
android:layout_width="0dp"

View File

@ -170,4 +170,5 @@
<color name="text_2A85FB">#2A85FB</color>
<color name="text_F3F3F3">#F3F3F3</color>
<color name="text_3CB9FF">#3CB9FF</color>
<color name="text_E8F3FF">#E8F3FF</color>
</resources>

View File

@ -54,8 +54,8 @@ COMMENT_HOST=https\://api.ghzs.com/v4d0d0/
# 请不要手动改动下面的值除非你明确需要以某个apk作为基准包需要打包请以scripts/tinker*.sh为准
TINKER_ENABLE=
TINKER_ID=d0c9bd803
TINKER_BASE_APK_DIR=app-0410-14-04-05_d0c9bd803
TINKER_ID=961d4eb
TINKER_BASE_APK_DIR=app-0520-11-32-50_961d4eb
android.useAndroidX=true
android.enableJetifier=true