Merge branch 'dev' of gitlab.ghzs.com:halo/assistant-android into dev

This commit is contained in:
kehaoyuan
2020-04-16 15:45:52 +08:00
31 changed files with 725 additions and 296 deletions

View File

@ -70,6 +70,8 @@ public class Constants {
public static final String SP_FIRST_DEVICE_REMIND = "first_device_remind";
//游戏设备弹窗不再提示
public static final String SP_NO_REMIND_AGAIN = "no_remind_again";
//游戏详情过滤标签数据
public static final String SP_FILTER_TAGS= "filter_tags";
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";

View File

@ -22,6 +22,12 @@ object GsonUtils {
return gson.fromJson(json.toString(), type)
}
@JvmStatic
fun <T> fromJsonList(json: String): List<T> {
val type = object : TypeToken<List<T>>() {}.type
return gson.fromJson(json, type)
}
@JvmStatic
fun toJson(any: Any?): String {
return gson.toJson(any)

View File

@ -24,6 +24,7 @@ public class ExpandTextView extends AppCompatTextView {
private CharSequence mSnapshotText;
private String mExpendText = "...全文";
private int expandTextBackgroundColor = Color.WHITE;
private int mMaxLines = 3; // 由于sdk版本限制(getMaxLines) 这里设置默认值
@ -43,6 +44,7 @@ public class ExpandTextView extends AppCompatTextView {
}
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ExpandTextView);
mExpendText = array.getString(R.styleable.ExpandTextView_expandText) == null ? mExpendText : array.getString(R.styleable.ExpandTextView_expandText);
expandTextBackgroundColor = array.getColor(R.styleable.ExpandTextView_expandTextBackgroundColor, expandTextBackgroundColor);
array.recycle();
}
@ -119,7 +121,7 @@ public class ExpandTextView extends AppCompatTextView {
}
}
}, startPosition + 3, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
msp.setSpan(new BackgroundColorSpan(Color.WHITE), startPosition, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
msp.setSpan(new BackgroundColorSpan(expandTextBackgroundColor), startPosition, msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(msp);
setMovementMethod(CustomLinkMovementMethod.getInstance());

View File

@ -38,6 +38,7 @@ import com.gh.download.DownloadManager;
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.manager.FilterManager;
import com.gh.gamecenter.retrofit.BiResponse;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
@ -48,11 +49,13 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
@ -133,6 +136,7 @@ public class SplashScreenActivity extends BaseActivity {
AppExecutor.getIoExecutor().execute(() -> {
Config.getGhzsSettings();
deviceDialogSetting();
getFilterDetailTags();
UsageStatsHelper.checkAndPostUsageStats();
GameRepositoryHelper.getGameRepository(this);
@ -180,6 +184,18 @@ public class SplashScreenActivity extends BaseActivity {
});
}
private void getFilterDetailTags(){
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
.getApi().getFilterDetailTags()
.subscribe(new Response<ArrayList<String>>(){
@Override
public void onResponse(@Nullable ArrayList<String> response) {
super.onResponse(response);
SPUtils.setString(Constants.SP_FILTER_TAGS, GsonUtils.toJson(response));
}
});
}
@SuppressLint("CheckResult")
private void showPrivacyPolicy(EmptyCallback callback) {
RetrofitManager.getInstance(this).getApi()

View File

@ -136,9 +136,13 @@ class GameDetailEntity(
var first: Boolean = false,
var last: Boolean = false,
@SerializedName("game_id")
var gameId: String,
var gameId: String = "",
@SerializedName("game_name")
var gameName: String,
var gameName: String = "",
@SerializedName("game_icon")
var gameIcon: String = "",
@SerializedName("game_tag")
var gameTags: ArrayList<TagStyleEntity> = ArrayList(),
var index: Int) : Parcelable
@Parcelize

View File

@ -1,9 +1,9 @@
package com.gh.gamecenter.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import java.util.*
@ -25,6 +25,7 @@ class NewsEntity : Parcelable, Cloneable {
var thumbnail: ThumbnailEntity? = null
@SerializedName(value = "intro",alternate = ["content"])
var intro: String? = null
var views: Int = 0

View File

@ -6,7 +6,10 @@ import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.*
import android.widget.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
@ -38,13 +41,14 @@ import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.desc.DescFragment
import com.gh.gamecenter.gamedetail.dialog.GameTagsDialog
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.gamedetail.fuli.FuLiFragment
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.gh.gamecenter.gamedetail.video.TopVideoView
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.mvvm.Status
import com.gh.gamecenter.normal.NormalFragment
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.suggest.SuggestType
import com.gh.gamecenter.tag.TagsActivity
import com.google.android.material.appbar.AppBarLayout
@ -58,7 +62,6 @@ import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import kotlinx.android.synthetic.main.dialog_game_tags.view.*
import kotlinx.android.synthetic.main.piece_game_detail_video.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@ -115,6 +118,10 @@ class GameDetailFragment : NormalFragment() {
lateinit var mTabIndicatorView: TabIndicatorView
@BindView(R.id.gamedetail_gametag)
lateinit var mGameTagView: FlexLinearLayout
@BindView(R.id.gameDetailRankLl)
lateinit var gameDetailRankLl: LinearLayout
@BindView(R.id.gameDetailRankTv)
lateinit var gameDetailRankTv: TextView
private var mDownloadMenuIcon: ImageView? = null
private var mDownloadCountHint: TextView? = null
@ -125,7 +132,8 @@ class GameDetailFragment : NormalFragment() {
private var mGameEntity: GameEntity? = null
private var mDownloadEntity: DownloadEntity? = null
private var mGameDetailEntity: GameDetailEntity? = null
// private var mGameDetailEntity: GameDetailEntity? = null
private var mNewGameDetailEntity: NewGameDetailEntity? = null
private var mTraceEvent: ExposureEvent? = null
private var mOrientationUtils: OrientationUtils? = null
@ -185,7 +193,7 @@ class GameDetailFragment : NormalFragment() {
consume {
when (it.itemId) {
R.id.menu_more -> {
if (mGameEntity != null && mGameDetailEntity != null) {
if (mGameEntity != null && mNewGameDetailEntity != null) {
showMoreMenuDialog()
MtaHelper.onEvent("游戏详情_新", "更多按钮", mViewModel.game?.name ?: "")
}
@ -194,7 +202,7 @@ class GameDetailFragment : NormalFragment() {
R.id.menu_concern -> {
checkReadPhoneStatePermissionBeforeAction {
ifLogin("游戏详情-[关注]") {
if (mGameDetailEntity != null && mGameDetailEntity!!.me.isGameConcerned) {
if (mNewGameDetailEntity != null && mNewGameDetailEntity!!.me.isGameConcerned) {
DialogUtils.showCancelDialog(requireContext(), { mViewModel.concernCommand(false) }, null)
} else {
mViewModel.concernCommand(true)
@ -338,24 +346,6 @@ class GameDetailFragment : NormalFragment() {
mToolbar.setNavigationOnClickListener { requireActivity().finish() }
}
override fun onResume() {
super.onResume()
if (mGameEntity != null && (mGameEntity!!.getApk().size == 1 || mGameEntity!!.isReservable)) {
DetailDownloadUtils.detailInitDownload(detailViewHolder, true)
}
DownloadManager.getInstance(context).addObserver(dataWatcher)
}
override fun onPause() {
super.onPause()
pauseVideo()
DownloadManager.getInstance(context).removeObserver(dataWatcher)
}
override fun onDestroy() {
super.onDestroy()
releaseVideo()
}
private fun observeData() {
mViewModel.gameLiveData.observeNonNull(this) { gameResource ->
@ -367,7 +357,7 @@ class GameDetailFragment : NormalFragment() {
}
}
mViewModel.unifiedGameDetailLiveData.observeNonNull(this) { detailResource ->
mViewModel.gameDetailLiveData.observeNonNull(this) { detailResource ->
if (detailResource.status == Status.SUCCESS) {
val data = detailResource.data ?: return@observeNonNull
@ -377,11 +367,12 @@ class GameDetailFragment : NormalFragment() {
GdtHelper.CONTENT_TYPE, "GAME",
GdtHelper.CONTENT_ID, mGameEntity!!.id)
mGameDetailEntity = data.game
downloadAddWord = data.game.getDownloadAddWord()
downloadOffText = data.game.downloadOffText
// mGameDetailEntity = data.game
mNewGameDetailEntity = data
// downloadAddWord = data.game.getDownloadAddWord()
// downloadOffText = data.game.downloadOffText
showAlertDialogIfNeeded(data.game)
// showAlertDialogIfNeeded(data.game)
initViewPage(data)
initGameDetailTop()
@ -404,7 +395,7 @@ class GameDetailFragment : NormalFragment() {
mTopVideoView.goneIf(!mViewModel.displayTopVideo)
mVideoPlaceholder.goneIf(mViewModel.displayTopVideo)
if (mViewModel.displayTopVideo) {
data.game.topVideo?.let { setUpTopVideo(it) }
data.topVideo?.let { setUpTopVideo(it) }
updateToolbarStyle(isToolbarWhite = false)
} else {
updateToolbarStyle(isToolbarWhite = true)
@ -418,19 +409,19 @@ class GameDetailFragment : NormalFragment() {
}
mViewModel.unifiedGameDetailWithUserRelatedInfoForParentLiveData.observeNonNull(this) {
mGameDetailEntity = it.game
mNewGameDetailEntity = it
initGameDetailTop()
if (mDestinationTab == INDEX_TRENDES || mDestinationTab == INDEX_DESC) {
/* if (mDestinationTab == INDEX_TRENDES || mDestinationTab == INDEX_DESC) {
// do nothing上面的观察已经完成了切换跳转
} else {
// 只要满足"已关注"/"已关联关注"/"已安装"其中一个条件就跳转到动态 tab (aka 福利 tab)
if (mGameDetailEntity!!.me.isGameConcerned
|| mGameDetailEntity!!.me.isGameRelatedConcerned
if (mNewGameDetailEntity!!.me.isGameConcerned
|| mNewGameDetailEntity!!.me.isGameRelatedConcerned
|| PackagesManager.findInstallByIdExcludeBlackPackage(mGameEntity!!.id) != null) {
tabPerformClick(INDEX_TRENDES)
}
}
}*/
}
mViewModel.concernLiveData.observeNonNull(this) { response ->
@ -469,7 +460,7 @@ class GameDetailFragment : NormalFragment() {
})
}
private fun initViewPage(data: UnifiedGameDetailEntity) {
private fun initViewPage(data: NewGameDetailEntity) {
val bundle = Bundle()
bundle.putParcelable(GameEntity.TAG, mGameEntity)
bundle.putString(EntranceUtils.KEY_ENTRANCE, mEntrance)
@ -493,10 +484,10 @@ class GameDetailFragment : NormalFragment() {
if (data.game.showComment) {
if (data.showComment) {
val ratingFragment = RatingFragment()
bundle.putBoolean(EntranceUtils.KEY_SKIP_GAME_COMMENT, mSkipGameComment)
bundle.putBoolean(EntranceUtils.KEY_DIRECT_COMMENT, mGameDetailEntity!!.directComment)
bundle.putBoolean(EntranceUtils.KEY_DIRECT_COMMENT, data.directComment)
ratingFragment.arguments = bundle
fragmentsList.add(ratingFragment)
tabTitleList.add(getString(R.string.game_detail_comment))
@ -615,7 +606,7 @@ class GameDetailFragment : NormalFragment() {
mLoading.visibility = View.GONE
mAppBarLayout.visibility = View.VISIBLE
if (mGameDetailEntity!!.showComment) {
if (mNewGameDetailEntity!!.showComment) {
if (mSkipGameComment) {
tabPerformClick(INDEX_RATING)
mAppBarLayout.setExpanded(false)
@ -623,14 +614,14 @@ class GameDetailFragment : NormalFragment() {
}
}
updateConcernMenuIcon(mGameDetailEntity!!.me.isGameConcerned)
updateConcernMenuIcon(mNewGameDetailEntity!!.me.isGameConcerned)
mBaseHandler.postDelayed({
mGameTagView.setTags(mGameDetailEntity?.tagStyle!!)
mGameTagView.setTags(mGameEntity?.tagStyle!!)
}, 5)
mGameTagView.onClickListener = object : FlexLinearLayout.OnItemClickListener {
override fun onMoreClickListener() {
if (!isVisible) return
GameTagsDialog.showGameTagsDialog(requireActivity(),mGameDetailEntity?.tagStyle!!)
GameTagsDialog.showGameTagsDialog(requireActivity(), mGameEntity?.tagStyle!!)
}
override fun onItemClickListener(tag: TagStyleEntity) {
@ -638,9 +629,19 @@ class GameDetailFragment : NormalFragment() {
tag.name, tag.name, mEntrance, "游戏介绍"))
}
}
ratingScoreContainer.visibleIf(mNewGameDetailEntity!!.showComment)
ratingScoreAverage.text = mNewGameDetailEntity!!.star.toString()
mGameName.text = mGameEntity!!.name
mGameName.isSelected = true
val ranking = mNewGameDetailEntity!!.ranking
if (ranking != null) {
gameDetailRankLl.visibility = View.VISIBLE
gameDetailRankTv.text = "${ranking.columnName}${ranking.no}"
gameDetailRankTv.isSelected=true
gameDetailRankLl.setOnClickListener {
SubjectActivity.startSubjectActivity(requireContext(), ranking.columnId, ranking.columnName, true, mEntrance)
}
}
ImageUtils.display(mGameIcon, mGameEntity!!.icon)
ImageUtils.display(mGameIconSmall, mGameEntity!!.icon)
@ -700,13 +701,13 @@ class GameDetailFragment : NormalFragment() {
mToolbar.setNavigationIcon(if (isToolbarWhite) R.drawable.ic_back_gamedetail else R.drawable.ic_back_gamedetail_white)
mToolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), if (isToolbarWhite) R.color.white else R.color.transparent))
DisplayUtils.setStatusBarColor(requireActivity(), if (isToolbarWhite) R.color.white else R.color.transparent, true)
updateConcernMenuIcon(mGameDetailEntity?.me?.isGameConcerned ?: false)
updateConcernMenuIcon(mNewGameDetailEntity?.me?.isGameConcerned ?: false)
mMoreMenuItem?.setIcon(if (isToolbarWhite) R.drawable.ic_menu_gamedetail_more else R.drawable.ic_menu_gamedetail_more_light)
mDownloadMenuIcon?.setImageResource(if (isToolbarWhite) R.drawable.toolbar_download else R.drawable.toolbar_download_white)
}
private fun share() {
mGameDetailEntity?.let {
mNewGameDetailEntity?.let {
DataCollectionUtils.uploadClick(context, "分享", "游戏详情", mGameEntity!!.name)
GdtHelper.logAction(ActionType.SHARE, GdtHelper.CONTENT_TYPE, "GAME", GdtHelper.CONTENT_ID, mGameEntity!!.id)
@ -730,7 +731,7 @@ class GameDetailFragment : NormalFragment() {
}
}
fun showRatingScore(star: Star) {
/*fun showRatingScore(star: Star) {
ratingScoreContainer.visibility = View.VISIBLE
initGameDetailTop()
if (star.hits > 3) {
@ -744,7 +745,7 @@ class GameDetailFragment : NormalFragment() {
debugOnly {
ratingScoreContainer.setOnClickListener { DirectUtils.directToAmway(requireContext(), "5dc26678ca6372002e0eb1c4", "", "") }
}
}
}*/
override fun onTouchEvent(event: MotionEvent) {
when (event.action) {
@ -804,8 +805,8 @@ class GameDetailFragment : NormalFragment() {
// 关注事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(changed: EBConcernChanged) {
if (mGameDetailEntity != null && mGameEntity != null && changed.isSingle && changed.gameId == mGameEntity!!.id) {
mGameDetailEntity!!.me.isGameConcerned = changed.isConcern
if (mNewGameDetailEntity != null && mGameEntity != null && changed.isSingle && changed.gameId == mGameEntity!!.id) {
mNewGameDetailEntity!!.me.isGameConcerned = changed.isConcern
initGameDetailTop()
}
}
@ -897,6 +898,26 @@ class GameDetailFragment : NormalFragment() {
return super.onBackPressed()
}
override fun onResume() {
super.onResume()
if (mGameEntity != null && (mGameEntity!!.getApk().size == 1 || mGameEntity!!.isReservable)) {
DetailDownloadUtils.detailInitDownload(detailViewHolder, true)
}
DownloadManager.getInstance(context).addObserver(dataWatcher)
}
override fun onPause() {
super.onPause()
pauseVideo()
DownloadManager.getInstance(context).removeObserver(dataWatcher)
}
override fun onDestroy() {
super.onDestroy()
releaseVideo()
}
companion object {
const val INDEX_DESC = 0
const val INDEX_TRENDES = 1

View File

@ -9,9 +9,11 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.constant.Constants
import com.gh.common.history.HistoryHelper
import com.gh.common.util.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.mvvm.Resource
import com.gh.gamecenter.retrofit.BiResponse
@ -36,9 +38,11 @@ class GameDetailViewModel(application: Application,
val unifiedGameDetailLiveData = MutableLiveData<Resource<UnifiedGameDetailEntity>>()
// 供外部 fragment (如 GameDetailFragment) 用的合并用户数据后的游戏数据 liveData
val unifiedGameDetailWithUserRelatedInfoForParentLiveData = MutableLiveData<UnifiedGameDetailEntity>()
val unifiedGameDetailWithUserRelatedInfoForParentLiveData = MutableLiveData<NewGameDetailEntity>()
// 供被包裹 fragment (如 FuliFragment) 用的合并用户数据后的游戏数据 liveData
val unifiedGameDetailWithUserRelatedInfoForChildLiveData = MutableLiveData<UnifiedGameDetailEntity>()
val unifiedGameDetailWithUserRelatedInfoForChildLiveData = MutableLiveData<NewGameDetailEntity>()
val gameDetailLiveData = MutableLiveData<Resource<NewGameDetailEntity>>()
var videoIsMuted = true
var displayTopVideo: Boolean = false
@ -46,8 +50,11 @@ class GameDetailViewModel(application: Application,
fun loadData() {
when {
game != null -> {
filterGameTags()
gameLiveData.value = Resource.success(game)
getUnifiedGameDetail()
// getUnifiedGameDetail()
getGameDetailNew()
}
gameId != null -> getGameDigest()
else -> gameLiveData.postValue(null)
@ -66,8 +73,10 @@ class GameDetailViewModel(application: Application,
DataUtils.onMtaEvent(getApplication(), "详情页面", "游戏详情", name)
game = response
gameLiveData.postValue(Resource.success(response))
getUnifiedGameDetail()
filterGameTags()
gameLiveData.postValue(Resource.success(game))
// getUnifiedGameDetail()
getGameDetailNew()
}
override fun onFailure(e: HttpException?) {
@ -76,8 +85,24 @@ class GameDetailViewModel(application: Application,
})
}
//过滤游戏标签
private fun filterGameTags() {
if (game == null) return
val filterTagString = SPUtils.getString(Constants.SP_FILTER_TAGS)
val filterTags = GsonUtils.fromJsonList<String>(filterTagString)
var i = 0
while (i < game!!.tagStyle.size) {
if (filterTags.contains(game!!.tagStyle[i].name)) {
game!!.tagStyle.removeAt(i)
i--
}
i++
}
}
// 获取游戏详情 (包括了包括 游戏文章,游戏工具箱,游戏礼包 等游戏相关内容但不包含用户([MeEntity])相关内容)
@SuppressLint("CheckResult")
/*@SuppressLint("CheckResult")
private fun getUnifiedGameDetail() {
mApi.getUnifiedGameDetail(game?.id)
.subscribeOn(Schedulers.io())
@ -119,10 +144,42 @@ class GameDetailViewModel(application: Application,
}
}
})
}
}*/
fun getGameDetailNew(){
@SuppressLint("CheckResult")
fun getGameDetailNew() {
mApi.getGameDetailNew(game?.id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<NewGameDetailEntity>() {
override fun onSuccess(data: NewGameDetailEntity) {
// 4.4以下设备不显示顶部视频
displayTopVideo = data.topVideo != null
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
gameDetailLiveData.postValue(Resource.success(data))
if (CheckLoginUtils.isLogin()) {
getUserRelatedInfo(data)
} else {
// 初始化礼包按钮状态
// data.libao?.let { loadLiBaoStatus(data, it) }
for (entity in data.detailEntity) {
if (entity.type == "libao") {
if (entity.libao != null) {
loadLiBaoStatus(data, entity.libao!!)
}
break
}
}
}
}
override fun onFailure(exception: Exception) {
if (exception is HttpException) {
gameDetailLiveData.postValue(Resource.error(exception))
}
}
})
}
@ -130,8 +187,8 @@ class GameDetailViewModel(application: Application,
* 获取游戏详情的内容获取相应内容的用户相关信息
*/
@SuppressLint("CheckResult")
private fun getUserRelatedInfo(unifiedGameDetailEntity: UnifiedGameDetailEntity) {
val toolkitIdList = arrayListOf<String>()
private fun getUserRelatedInfo(newGameDetailEntity: NewGameDetailEntity) {
/*val toolkitIdList = arrayListOf<String>()
unifiedGameDetailEntity.toolkits?.let {
for (toolkit in it) {
toolkitIdList.add(toolkit.id ?: "")
@ -150,7 +207,33 @@ class GameDetailViewModel(application: Application,
for (answer in it) {
answerIdList.add(answer.id ?: "")
}
}*/
val libaoIdList = arrayListOf<String>()
val toolkitIdList = arrayListOf<String>()
val answerIdList = arrayListOf<String>()
newGameDetailEntity.detailEntity.forEach {
if (it.type == "libao") {
for (libao in it.libao!!) {
libaoIdList.add(libao.id ?: "")
}
}
}
if (newGameDetailEntity.zone?.style == "default") {
newGameDetailEntity.zone?.content?.forEach {
if (it.type == "toolkit") {
for (tool in it.toolkit!!) {
toolkitIdList.add(tool.id ?: "")
}
}
if (it.type == "community_column_content") {
for (answer in it.answer!!) {
answerIdList.add(answer.id ?: "")
}
}
}
}
val requestMap = hashMapOf<String, List<String>>()
requestMap["game"] = arrayListOf(game?.id ?: "game id is not supposed to be empty")
@ -161,15 +244,15 @@ class GameDetailViewModel(application: Application,
mApi.getUserRelatedInfoByPost(UserManager.getInstance().userId, requestMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object: BiResponse<UnifiedUserTrendEntity>() {
.subscribe(object : BiResponse<UnifiedUserTrendEntity>() {
override fun onSuccess(data: UnifiedUserTrendEntity) {
mergeUnifiedGameDetailWithUserRelatedInfo(unifiedGameDetailEntity, data)
mergeUnifiedGameDetailWithUserRelatedInfo(newGameDetailEntity, data)
}
})
}
fun mergeUnifiedGameDetailWithUserRelatedInfo(unifiedGameDetailEntity: UnifiedGameDetailEntity, unifiedUserTrendEntity: UnifiedUserTrendEntity) {
unifiedUserTrendEntity.game?.let {
fun mergeUnifiedGameDetailWithUserRelatedInfo(newGameDetailEntity: NewGameDetailEntity, unifiedUserTrendEntity: UnifiedUserTrendEntity) {
/*unifiedUserTrendEntity.game?.let {
if (unifiedUserTrendEntity.game.isNullOrEmpty()) return@let
for (game in it) {
unifiedGameDetailEntity.game.me = game.me
@ -219,11 +302,74 @@ class GameDetailViewModel(application: Application,
unifiedGameDetailEntity.libao?.let {
loadLiBaoStatus(unifiedGameDetailEntity, it)
}
}*/
var libaoList: List<LibaoEntity>? = null
unifiedUserTrendEntity.game?.let {
if (unifiedUserTrendEntity.game.isNullOrEmpty()) return@let
for (game in it) {
newGameDetailEntity.me = game.me
break
}
}
if (newGameDetailEntity.zone?.style == "default") {
newGameDetailEntity.zone?.content?.forEach {
if (it.type == "toolkit") {
if (unifiedUserTrendEntity.toolkit != null) {
for (originalToolkit in it.toolkit!!) {
for (toolkit in unifiedUserTrendEntity.toolkit!!) {
if (originalToolkit.id == toolkit.id) {
originalToolkit.me = toolkit.me
break
}
}
}
}
}
if (it.type == "community_column_content") {
if (unifiedUserTrendEntity.communityColumnContents != null) {
for (originalAnswer in it.answer!!) {
for (answer in unifiedUserTrendEntity.communityColumnContents!!) {
if (originalAnswer.id == answer.id) {
originalAnswer.me = answer.me
originalAnswer.vote = answer.vote
break
}
}
}
}
}
}
}
newGameDetailEntity.detailEntity.forEach {
if (it.type == "libao") {
libaoList = it.libao!!
if (unifiedUserTrendEntity.libao != null) {
for (originalLibao in it.libao!!) {
for (libao in unifiedUserTrendEntity.libao!!) {
if (originalLibao.id == libao.id) {
originalLibao.me = libao.me
break
}
}
}
}
}
}
if (libaoList.isNullOrEmpty()) {
unifiedGameDetailWithUserRelatedInfoForParentLiveData.postValue(newGameDetailEntity)
unifiedGameDetailWithUserRelatedInfoForChildLiveData.postValue(newGameDetailEntity)
} else {
unifiedGameDetailWithUserRelatedInfoForParentLiveData.postValue(newGameDetailEntity)
libaoList?.let {
loadLiBaoStatus(newGameDetailEntity, it)
}
}
}
//获取礼包状态
private fun loadLiBaoStatus(unifiedGameDetailEntity: UnifiedGameDetailEntity, libaoList: List<LibaoEntity>) {
private fun loadLiBaoStatus(newGameDetailEntity: NewGameDetailEntity, libaoList: List<LibaoEntity>) {
val builder = StringBuilder()
var i = 0
val size = libaoList.size
@ -245,13 +391,17 @@ class GameDetailViewModel(application: Application,
override fun onResponse(list: List<LibaoStatusEntity>?) {
LibaoUtils.initLiBaoEntity(list, libaoList)
if (libaoList.isNotEmpty()) {
unifiedGameDetailEntity.libao = libaoList
unifiedGameDetailWithUserRelatedInfoForChildLiveData.postValue(unifiedGameDetailEntity)
newGameDetailEntity.detailEntity.forEach {
if (it.type == "libao") {
it.libao = libaoList as ArrayList<LibaoEntity>
}
}
unifiedGameDetailWithUserRelatedInfoForChildLiveData.postValue(newGameDetailEntity)
}
}
override fun onFailure(e: HttpException?) {
unifiedGameDetailWithUserRelatedInfoForChildLiveData.postValue(unifiedGameDetailEntity)
unifiedGameDetailWithUserRelatedInfoForChildLiveData.postValue(newGameDetailEntity)
}
})
}

View File

@ -28,7 +28,9 @@ import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.game.horizontal.GameHorizontalListViewHolder
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.entity.DetailEntity
import com.gh.gamecenter.gamedetail.entity.GameInfo
import com.gh.gamecenter.gamedetail.entity.UpdateContent
import com.gh.gamecenter.home.amway.LeftPagerSnapHelper
import com.gh.gamecenter.suggest.SuggestType
import com.lightgame.adapter.BaseRecyclerAdapter
@ -43,7 +45,7 @@ class DescAdapter(context: Context,
var gameList = arrayListOf<GameEntity>()
var descItemList = arrayListOf<DescItemData>()
var descItemList = arrayListOf<DetailEntity>()
private var mIsIntroExpanded = false
@ -52,50 +54,59 @@ class DescAdapter(context: Context,
// 是不是第一次 layout ,决定是否显示展开按钮
private var mIsIntroFirstTimeLayout = true
fun updateDescItemList(descItemList: ArrayList<DescItemData>) {
fun updateDescItemList(descItemList: ArrayList<DetailEntity>) {
this.descItemList = descItemList
gameList.clear()
for (descItem in this.descItemList) {
/*for (descItem in this.descItemList) {
if (descItem.recommendedGames != null && descItem.recommendedGames?.data != null) {
for (game in descItem.recommendedGames!!.data!!) {
gameList.add(game)
}
}
}
}*/
notifyDataSetChanged()
}
override fun getItemViewType(position: Int): Int {
// if (position == itemCount - 1) {
// return FOOTER
// } else {
val descItemData = descItemList[position]
return if (descItemData.intro != null) {
INTRO
} else if (descItemData.recommendedGames != null) {
RECOMMENDED_GAMES
} else if (descItemData.relatedVersion != null) {
RELATED_VERSION
} else if (descItemData.customColumn != null) {
CUSTOM_COLUMN
} else if (!TextUtils.isEmpty(descItemData.header)) {
HEADER
} else if (descItemData.recommendedImage != null) {
IMAGE
} else if (descItemData.comments != null) {
COMMENTS
} else if (descItemData.videos != null) {
VIDEOS
} else if (descItemData.gallery != null) {
IMAGE_GALLERY
} else if (descItemData.updateContent != null) {
UPDATE_CONTENT
} else if (descItemData.server != null) {
LATEST_SERVICE
} else {
FOOTER
/* return if (descItemData.intro != null) {
INTRO
} else if (descItemData.recommendedGames != null) {
RECOMMENDED_GAMES
} else if (descItemData.relatedVersion != null) {
RELATED_VERSION
} else if (descItemData.customColumn != null) {
CUSTOM_COLUMN
} else if (!TextUtils.isEmpty(descItemData.header)) {
HEADER
} else if (descItemData.recommendedImage != null) {
IMAGE
} else if (descItemData.comments != null) {
COMMENTS
} else if (descItemData.videos != null) {
VIDEOS
} else if (descItemData.gallery != null) {
IMAGE_GALLERY
} else if (descItemData.updateContent != null) {
UPDATE_CONTENT
} else if (descItemData.server != null) {
LATEST_SERVICE
} else {
FOOTER
}*/
return when (descItemData.type) {
"gallery" -> IMAGE_GALLERY
"video" -> VIDEOS
"comment" -> COMMENTS
"info" -> GAME_DETAIL
"update" -> UPDATE_CONTENT
"server" -> LATEST_SERVICE
"related_version" -> RELATED_VERSION
"image_recommend" -> IMAGE
"libao" -> LIBAO
"article" -> INFO_RAIDERS
else -> FOOTER
}
// }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -145,6 +156,9 @@ class DescAdapter(context: Context,
RELATED_VERSION -> {
GameDetailRelatedVersionViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.game_gallery_list, parent, false))
}
GAME_DETAIL -> {
GameDetailInfoViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.game_detail_info, parent, false))
}
FOOTER -> {
val view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
FooterViewHolder(view)
@ -158,28 +172,34 @@ class DescAdapter(context: Context,
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is GameDetailIntroViewHolder -> initIntroViewHolder(holder, descItemList[position])
is GameHorizontalListViewHolder -> bindGameHorizontalListView(holder, position)
is GameDetailRecommendImageViewHolder -> bindImageViewHolder(holder, descItemList[position].recommendedImage)
is GameDetailCommentsViewHolder -> bindCommentsViewHolder(holder, descItemList[position].comments)
is GameDetailCustomColumnViewHolder -> bindCustomColumnViewHolder(holder, descItemList[position])
is GameDetailHeaderViewHolder -> holder.bindView(descItemList[position].header!!)
is GameDetailRelatedVersionViewHolder -> bindRelatedVersion(holder, descItemList[position])
is GameVideoGalleryViewHolder -> bindVideosViewHolder(holder, descItemList[position].videos)
// is GameDetailIntroViewHolder -> initIntroViewHolder(holder, descItemList[position])
//
// is GameHorizontalListViewHolder -> bindGameHorizontalListView(holder, position)
//
is GameDetailRecommendImageViewHolder -> bindImageViewHolder(holder, descItemList[position].imageRecommend)
//
is GameDetailCommentsViewHolder -> bindCommentsViewHolder(holder, descItemList[position].comment)
//
// is GameDetailCustomColumnViewHolder -> bindCustomColumnViewHolder(holder, descItemList[position])
//
// is GameDetailHeaderViewHolder -> holder.bindView(descItemList[position].header!!)
//
is GameDetailRelatedVersionViewHolder -> bindRelatedVersion(holder, descItemList[position].relatedVersion)
//
is GameVideoGalleryViewHolder -> bindVideosViewHolder(holder, descItemList[position].video)
is GameImageGalleryViewHolder -> bindImageGalleryViewHolder(holder, descItemList[position].gallery)
is GameUpdateContentViewHolder -> bindUpdateContentViewHolder(holder, descItemList[position].updateContent)
is GameUpdateContentViewHolder -> bindUpdateContentViewHolder(holder, descItemList[position].update)
is GameLatestServiceViewHolder -> bindLatestServiceViewHolder(holder, descItemList[position].server)
is GameDetailInfoViewHolder -> bindGameDetailInfoViewHolder(holder, descItemList[position].info)
is GameLibaoGalleryViewHolder -> bindLibaoViewHolder(holder, descItemList[position].libao)
is GameRaidersGalleryViewHolder -> bindRaidersViewHolder(holder, descItemList[position].article)
is FooterViewHolder -> {
holder.loading.visibility = View.GONE
@ -283,10 +303,10 @@ class DescAdapter(context: Context,
private fun bindGameHorizontalListView(holder: GameHorizontalListViewHolder, position: Int) {
val subjectEntity = descItemList[position].recommendedGames
val subjectAdapter = holder.bindHorizontalList(subjectEntity!!)
subjectAdapter.gameName = gameName!!
subjectAdapter.entrance = mEntrance
// val subjectEntity = descItemList[position].recommendedGames
// val subjectAdapter = holder.bindHorizontalList(subjectEntity!!)
// subjectAdapter.gameName = gameName!!
// subjectAdapter.entrance = mEntrance
}
private fun initIntroViewHolder(viewHolder: GameDetailIntroViewHolder, descItemData: DescItemData) {
@ -363,8 +383,14 @@ class DescAdapter(context: Context,
if (viewHolder.binding.recyclerview.adapter == null) {
val commentsAdapter = viewHolder.binding.recyclerview.adapter as DescCommentsAdapter?
?: DescCommentsAdapter(mContext, mViewModel, mEntrance, gameName)
viewHolder.binding.recyclerview.isNestedScrollingEnabled = false
viewHolder.binding.recyclerview.adapter = commentsAdapter
viewHolder.binding.recyclerview.layoutManager = LinearLayoutManager(mContext)
val itemDecoration = HorizontalDividerItemDecoration.Builder(mContext)
.size(DisplayUtils.dip2px(1f))
.margin(DisplayUtils.dip2px(16f))
.color(ContextCompat.getColor(mContext, R.color.text_eeeeee)).build()
viewHolder.binding.recyclerview.addItemDecoration(itemDecoration)
viewHolder.binding.tvAll.setOnClickListener {
EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
MtaHelper.onEvent("游戏详情_新", "玩家评论_点击全部", gameName)
@ -375,7 +401,7 @@ class DescAdapter(context: Context,
}
//绑定其他相关版本
private fun bindRelatedVersion(viewHolder: GameDetailRelatedVersionViewHolder, descItemData: DescItemData) {
private fun bindRelatedVersion(viewHolder: GameDetailRelatedVersionViewHolder, relatedVersion: ArrayList<GameDetailEntity.RelatedVersion>?) {
// holder.binding.relatedVersion = descItemData.relatedVersion
// holder.binding.root.setOnClickListener {
// DirectUtils.directToGameDetail(mContext, descItemData.relatedVersion!!.gameId, mEntrance)
@ -384,7 +410,7 @@ class DescAdapter(context: Context,
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
layoutManager = LinearLayoutManager(mContext)
val relatedVersionAdapter = GameRelatedVersionAdapter(mContext, descItemData.relatedVersion!!)
val relatedVersionAdapter = GameRelatedVersionAdapter(mContext, relatedVersion!!, mEntrance)
adapter = relatedVersionAdapter
addItemDecoration(VerticalItemDecoration(mContext, 16F, false, R.color.white))
}
@ -446,9 +472,9 @@ class DescAdapter(context: Context,
viewHolder.binding.moreTv.visibility = View.GONE
}
//绑定历史版本
private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, updateContent: String?) {
holder.binding.contentTv.text = updateContent ?: ""
//绑定更新内容
private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, updateContent: UpdateContent?) {
holder.binding.contentTv.text = updateContent?.updateDes ?: ""
holder.binding.historyVersionTv.setOnClickListener {
ToastUtils.showToast("历史版本")
}
@ -472,12 +498,12 @@ class DescAdapter(context: Context,
}
//绑定攻略文章
private fun bindRaidersViewHolder(viewHolder: GameLibaoGalleryViewHolder, article: ArrayList<NewsEntity>?) {
private fun bindRaidersViewHolder(viewHolder: GameRaidersGalleryViewHolder, article: ArrayList<NewsEntity>?) {
viewHolder.binding.galleryRv.isNestedScrollingEnabled = false
if (viewHolder.binding.galleryRv.adapter == null) {
viewHolder.binding.galleryRv.apply {
layoutManager = LinearLayoutManager(mContext)
val raidersAdapter = GameRaidersAdapter(mContext, article!!)
layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
val raidersAdapter = GameRaidersAdapter(mContext, article!!, mEntrance, gameName)
adapter = raidersAdapter
addItemDecoration(HorizontalItemDecoration(mContext, 16, article.size))
}
@ -506,8 +532,8 @@ class DescAdapter(context: Context,
}
//绑定游戏信息
private fun bindGameDetailInfoViewHolder(viewHolder: GameDetailInfoViewHolder, info: GameInfo) {
if (!info.topTags.isNullOrEmpty()) {
private fun bindGameDetailInfoViewHolder(viewHolder: GameDetailInfoViewHolder, info: GameInfo?) {
if (!info!!.topTags.isNullOrEmpty()) {
viewHolder.binding.labelsLl.removeAllViews()
info.topTags.forEach {
viewHolder.binding.labelsLl.addView(createGameInfoLabel(it.name))
@ -519,7 +545,7 @@ class DescAdapter(context: Context,
layoutManager = GridLayoutManager(mContext, 2)
val infoAdapter = GameDetailInfoItemAdapter(mContext, info)
adapter = infoAdapter
addItemDecoration(GridSpacingItemColorDecoration(context, 0, 16, R.color.transparent))
addItemDecoration(GridSpacingItemColorDecoration(context, 12, 16, R.color.transparent))
}
}
@ -527,7 +553,7 @@ class DescAdapter(context: Context,
private fun createGameInfoLabel(label: String): TextView {
return TextView(mContext).apply {
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val params = LinearLayout.LayoutParams(DisplayUtils.dip2px(68f), LinearLayout.LayoutParams.WRAP_CONTENT)
params.rightMargin = DisplayUtils.dip2px(12f)
layoutParams = params
textSize = 13F

View File

@ -23,8 +23,10 @@ import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
import com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity
import com.gh.gamecenter.manager.UserManager
import org.greenrobot.eventbus.EventBus
import java.util.regex.Pattern
class DescCommentsAdapter(context: Context,
var mViewModel: DescViewModel,
@ -60,6 +62,59 @@ class DescCommentsAdapter(context: Context,
val commentData = comments[position]
holder.binding.run {
data = commentData
val p = Pattern.compile(RatingEditActivity.LABEL_REGEX)
val m = p.matcher(commentData.content)
if (m.find()) {
val contents = TextHelper.getCommentLabelSpannableStringBuilder(commentData.content)
content.setTextWithHighlightedTextWrappedInsideWrapper(text = contents, copyClickedText = true)
} else {
content.setTextWithHighlightedTextWrappedInsideWrapper(text = commentData.content, copyClickedText = true)
}
if (commentData.user.badge != null) {
sdvUserBadge.visibility = View.VISIBLE
tvBadgeName.visibility = View.VISIBLE
ImageUtils.display(sdvUserBadge, commentData.user.badge.icon)
tvBadgeName.text = commentData.user.badge.name
} else {
sdvUserBadge.visibility = View.GONE
tvBadgeName.visibility = View.GONE
}
when {
commentData.isEditContent == null -> {
time.text = NewsUtils.getFormattedTime(commentData.time)
time.setTextColor(mContext.resources.getColor(R.color.hint))
}
commentData.isEditContent!! -> {
time.text = (NewsUtils.getFormattedTime(commentData.time) + " 已修改 >")
time.setTextColor(mContext.resources.getColor(R.color.tag_orange))
}
else -> {
time.text = (NewsUtils.getFormattedTime(commentData.time) + " 已修改")
time.setTextColor(mContext.resources.getColor(R.color.tag_orange))
}
}
sdvUserBadge.setOnClickListener {
val key = when (path) {
"游戏详情:介绍" -> "游戏详情-玩家评论"
"游戏详情:评分" -> "游戏详情-评论列表"
"评论详情" -> "游戏评论详情"
else -> ""
}
MtaHelper.onEvent("进入徽章墙_用户记录", key, "${commentData.user.name}${commentData.user.id}")
MtaHelper.onEvent("徽章中心", "进入徽章中心", key)
DirectUtils.directToBadgeWall(mContext, commentData.user.id, commentData.user.name, commentData.user.icon)
}
userIcon.setOnClickListener {
DirectUtils.directToHomeActivity(mContext, commentData.user.id, mEntrance, path)
}
userName.setOnClickListener {
userIcon.performClick()
}
tvBadgeName.setOnClickListener { sdvUserBadge.performClick() }
commentItem.setOnClickListener {
val intent = RatingReplyActivity.getIntent(mContext, mViewModel.game!!, commentData, mEntrance, path)
SyncDataBetweenPageHelper.startActivityForResult(mContext, intent, RATING_REPLY_REQUEST, position)
@ -89,6 +144,12 @@ class DescCommentsAdapter(context: Context,
}
}
}
time.setOnClickListener {
if (commentData.isEditContent == true) {
val intent = CommentLogsActivity.getIntent(mContext, mViewModel.game!!.id, commentData.id)
mContext.startActivity(intent)
}
}
}
}

View File

@ -12,13 +12,13 @@ import butterknife.BindView
import com.gh.base.fragment.BaseFragment
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.GameDetailEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.GameDetailFragment.Companion.OPEN_APPBAR
import com.gh.gamecenter.gamedetail.GameDetailFragment.Companion.SKIP_DESC
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.video.detail.VideoDetailActivity
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.EventBus
@ -30,7 +30,8 @@ class DescFragment : BaseFragment<Any>() {
private lateinit var mAdapter: DescAdapter
private var layoutManager: LinearLayoutManager? = null
private var mGameEntity: GameEntity? = null
private var mDetailEntity: GameDetailEntity? = null
// private var mDetailEntity: GameDetailEntity? = null
private var mNewDetailEntity: NewGameDetailEntity? = null
private lateinit var mViewModel: DescViewModel
@ -48,7 +49,7 @@ class DescFragment : BaseFragment<Any>() {
override fun onData(dataPosition: Int): RatingComment? {
val descItemList = mAdapter.descItemList
for (i in 0 until descItemList.size) {
val comments = descItemList[i].comments
val comments = descItemList[i].comment
if (comments != null) {
commentPosition = i
return comments[dataPosition]
@ -71,17 +72,24 @@ class DescFragment : BaseFragment<Any>() {
val gameDetailFactory = GameDetailViewModel.Factory(HaloApp.getInstance().application, mGameEntity?.id, mGameEntity)
val gameDetailViewModel: GameDetailViewModel = viewModelProviderFromParent(gameDetailFactory)
mDetailEntity = gameDetailViewModel.unifiedGameDetailLiveData.value?.data?.game
// mDetailEntity = gameDetailViewModel.unifiedGameDetailLiveData.value?.data?.game
mNewDetailEntity = gameDetailViewModel.gameDetailLiveData.value?.data
val factory = DescViewModel.Factory(HaloApp.getInstance().application, mGameEntity)
mViewModel = viewModelProvider(factory)
gameDetailViewModel.unifiedGameDetailLiveData.observeNonNull(this) {
mViewModel.constructList(it.data!!.game)
// gameDetailViewModel.unifiedGameDetailLiveData.observeNonNull(this) {
// mViewModel.constructList(it.data!!.game)
// }
gameDetailViewModel.gameDetailLiveData.observeNonNull(this) {
mAdapter.updateDescItemList(it.data!!.detailEntity)
}
gameDetailViewModel.unifiedGameDetailWithUserRelatedInfoForChildLiveData.observeNonNull(this) {
mAdapter.updateDescItemList(it.detailEntity)
}
mViewModel.list.observe(this, Observer { descItemDataList ->
descItemDataList?.let {
mAdapter.updateDescItemList(it)
//mAdapter.updateDescItemList(it)
}
descItemDataList.forEach {
if (openVideoStreaming && it.intro?.video != null && !RunningUtils.isEqualsTop(context, VideoDetailActivity::class.java.name)) {

View File

@ -21,7 +21,7 @@ class GameDetailInfoItemAdapter(val context: Context, gameInfo: GameInfo) : Recy
datas.add(GameInfoItemData(title = "当前版本", info = gameInfo.version, actionStr = if (gameInfo.requestUpdateStatus == "on") "我要求更新" else ""))
}
if (gameInfo.updateTime != 0L) {
datas.add(GameInfoItemData(title = "更新时间", info = TimeUtils.getFormatTime(gameInfo.updateTime)))
datas.add(GameInfoItemData(title = "更新时间", info = TimeUtils.getFormatTime(gameInfo.updateTime * 1000)))
}
if (gameInfo.size.isNotEmpty()) {
datas.add(GameInfoItemData(title = "游戏大小", info = gameInfo.size))

View File

@ -37,8 +37,18 @@ class GameLibaoAdapter(val context: Context, val libaos: ArrayList<LibaoEntity>)
override fun getItemCount(): Int = if (libaos.size > 3 && !isExpand) mShowItemCount + 1 else libaos.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val libaoEntity = libaos[position]
when (holder) {
is LibaoViewHolder -> {
holder.binding.libaoNameTv.text = libaoEntity.name
holder.binding.contentTv.text = libaoEntity.content
val total = libaoEntity.total
val repeat = libaoEntity.repeat
holder.binding.libaoSchedulePb.progress = ((total - repeat) / total) * 100
holder.binding.remainingTv.text = "剩余${((repeat) / total) * 100}%"
holder.binding.receiveTv.setOnClickListener {
}
}
is MoreViewHolder -> {
holder.itemView.setOnClickListener {

View File

@ -5,19 +5,44 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.DataUtils
import com.gh.common.util.NewsUtils
import com.gh.common.util.TimeUtils
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameRaidersBinding
import com.gh.gamecenter.entity.NewsEntity
class GameRaidersAdapter(val context: Context, val article: ArrayList<NewsEntity>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class GameRaidersAdapter(val context: Context, val articles: ArrayList<NewsEntity>, val mEntrance: String, val gameName: String?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return RaidersViewHolder(DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_game_raiders, parent, false))
}
override fun getItemCount(): Int = article.size
override fun getItemCount(): Int = articles.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val newsEntity = articles[position]
if (holder is RaidersViewHolder) {
holder.binding.titleTv.text = newsEntity.title ?: ""
holder.binding.contentTv.text = newsEntity.intro ?: ""
holder.binding.timeTv.text = TimeUtils.getFormatTime(newsEntity.publishOn * 1000)
holder.itemView.setOnClickListener {
skipNewsDetail(newsEntity, position)
}
}
}
private fun skipNewsDetail(article: NewsEntity, position: Int) {
DataCollectionUtils.uploadClick(context, "资讯攻略", "游戏详情", article.title)
DataUtils.onMtaEvent(context, "游戏详情_新", "资讯攻略", gameName + "->" + article.title)
// 统计阅读量
NewsUtils.statNewsViews(context, article.id)
NewsDetailActivity.startNewsDetailActivity(context, article,
mEntrance + "+(游戏详情[" + gameName + "]:资讯攻略-列表[" + (position + 1) + "])")
}
class RaidersViewHolder(var binding: ItemGameRaidersBinding) : RecyclerView.ViewHolder(binding.root)

View File

@ -6,11 +6,14 @@ import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.ImageUtils
import com.gh.common.util.StringUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ItemGameDetailRelatedVersionBinding
import com.gh.gamecenter.entity.GameDetailEntity
class GameRelatedVersionAdapter(val context: Context, val datas: ArrayList<GameDetailEntity.RelatedVersion>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class GameRelatedVersionAdapter(val context: Context, val datas: ArrayList<GameDetailEntity.RelatedVersion>, val mEntrance: String) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var isExpand = false
private val mShowItemCount: Int = 3
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -37,9 +40,15 @@ class GameRelatedVersionAdapter(val context: Context, val datas: ArrayList<GameD
override fun getItemCount(): Int = if (datas.size > 3 && !isExpand) mShowItemCount + 1 else datas.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val relatedVersion = datas[position]
when (holder) {
is GameDetailRelatedViewHolder -> {
holder.binding.gameNameTv.text = datas[position].gameName
holder.binding.relatedVersion = relatedVersion
ImageUtils.display(holder.binding.gameIconSdv, relatedVersion.gameIcon)
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(context, relatedVersion.gameId,
StringUtils.buildString(mEntrance, "+(", "游戏详情", "[", relatedVersion.gameName, "]:相关游戏[", (position + 1).toString(), "])"))
}
}
is MoreViewHolder -> {
holder.itemView.setOnClickListener {

View File

@ -0,0 +1,71 @@
package com.gh.gamecenter.gamedetail.entity
import androidx.annotation.Keep
import com.gh.gamecenter.entity.*
import com.google.gson.annotations.SerializedName
@Keep
data class DetailEntity(
var type: String = "",
var notice: NoticeEntity? = null,
var des: String? = null,// 介绍文案
var gallery: ArrayList<String>? = null,
var video: ArrayList<GameDetailEntity.Video>? = null,
var comment: ArrayList<RatingComment>? = null,
var info: GameInfo? = null,
var update: UpdateContent? = null,
var libao: ArrayList<LibaoEntity>? = null,
@SerializedName("related_version")
var relatedVersion: ArrayList<GameDetailEntity.RelatedVersion>? = null,
var server: GameDetailServer? = null,
@SerializedName("image_recommend")
var imageRecommend: LinkEntity? = null,
@SerializedName("related_game")
var relatedGames: ArrayList<GameDetailRelatedGame>? = null,
var article: ArrayList<NewsEntity>? = null
)
//公告文章
@Keep
data class NoticeEntity(
@SerializedName("_id")
var id: String = "",
var title: String = "",
var type: String = "",
var time: String = "",
var overtime: String = ""
)
@Keep
data class GameInfo(
@SerializedName("download_status")
var downloadStatus: String = "",// 下载状态on/off/appointment/link
@SerializedName("top_tag")
var topTags: ArrayList<TagStyleEntity> = ArrayList(),
var version: String = "",
@SerializedName("request_update_status")
var requestUpdateStatus: String = "",// 游戏求更新开关on/off
@SerializedName("update_time")
var updateTime: Long = 0,
var size: String = "",
var contact: Contact? = null,
var manufacturer: String = ""
)
@Keep
data class Contact(
var hint: String = "",// 提示文案
var key: String = "",// QQ群的key类型为qqqun时字段存在
var qq: String = "",// QQ号码 或 QQ群号码
var type: String = ""// qq/qqqun
)
@Keep
data class UpdateContent(
@SerializedName("history_apk_count")
val historyApkCount: Int = 0,
@SerializedName("history_apk_status")
val historyApkStatus: String = "",
@SerializedName("update_des")
val updateDes: String = ""
)

View File

@ -1,7 +1,8 @@
package com.gh.gamecenter.gamedetail.entity
import androidx.annotation.Keep
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.GameDetailEntity
import com.gh.gamecenter.entity.MeEntity
import com.google.gson.annotations.SerializedName
@Keep
@ -14,83 +15,23 @@ data class NewGameDetailEntity(
@SerializedName("share_code")
var shareCode: String = "",// 分享码
var ranking: Ranking? = null,// 游戏榜单排名,无排名时,字段不存在
@SerializedName("top_video")
var topVideo: GameDetailEntity.Video? = null,
@SerializedName("me")
var me: MeEntity = MeEntity(),
@SerializedName("detail_tab")
var detailEntity: ArrayList<DetailEntity> = ArrayList()
var detailEntity: ArrayList<DetailEntity> = ArrayList(),
@SerializedName("zone_tab")
var zone: ZoneEntity? = null
)
@Keep
data class Ranking(
@SerializedName("column_id")
var column_id: String = "",//专题id
var columnId: String = "",//专题id
@SerializedName("column_name")
var columnName: String = "",// 专题标题
var no: String = ""// 排名名次
)
@Keep
data class DetailEntity(
var type: String = "",
var notice: NoticeEntity? = null,
var des: String? = null,// 介绍文案
var gallery: ArrayList<String>? = null,
var video: ArrayList<GameDetailEntity.Video>? = null,
var comment: ArrayList<RatingComment>? = null,
var info: GameInfo? = null,
var update: UpdateContent? = null,
var libao: ArrayList<LibaoEntity>? = null,
@SerializedName("related_version")
var relatedVersion: ArrayList<GameDetailEntity.RelatedVersion>? = null,
var server: GameDetailServer? = null,
@SerializedName("image_recommend")
var imageRecommend: LinkEntity? = null,
@SerializedName("related_game")
var relatedGames: GameDetailRelatedGame? = null,
var article: ArrayList<NewsEntity>? = null
)
//公告文章
@Keep
data class NoticeEntity(
@SerializedName("_id")
var id: String = "",
var title: String = "",
var type: String = "",
var time: String = "",
var overtime: String = ""
)
@Keep
data class GameInfo(
@SerializedName("download_status")
var downloadStatus: String = "",// 下载状态on/off/appointment/link
@SerializedName("top_tag")
var topTags: ArrayList<TagStyleEntity> = ArrayList(),
var version: String = "",
@SerializedName("request_update_status")
var requestUpdateStatus: String = "",// 游戏求更新开关on/off
@SerializedName("update_time")
var updateTime: Long = 0,
var size: String = "",
var contact: Contact? = null,
var manufacturer: String = ""
)
@Keep
data class Contact(
var hint: String = "",// 提示文案
var key: String = "",// QQ群的key类型为qqqun时字段存在
var qq: String = "",// QQ号码 或 QQ群号码
var type: String = ""// qq/qqqun
)
@Keep
data class UpdateContent(
@SerializedName("history_apk_count")
val historyApkCount: Int = 0,
@SerializedName("history_apk_status")
val historyApkStatus: String = "",
@SerializedName("update_des")
val updateDes: String = ""
)

View File

@ -0,0 +1,23 @@
package com.gh.gamecenter.gamedetail.entity
import androidx.annotation.Keep
import com.gh.gamecenter.entity.NewsEntity
import com.gh.gamecenter.entity.ToolBoxEntity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.google.gson.annotations.SerializedName
@Keep
data class ZoneEntity(
var style: String = "",// 游戏专区样式default/link 默认模板/填写链接
var link: String = "",// 样式为link时字段存在
var content: ArrayList<ZoneContentEntity> = ArrayList()// 样式为default时字段存在
)
data class ZoneContentEntity(
var type: String = "",
var notice: NoticeEntity? = null,
var article: ArrayList<NewsEntity>? = null,
var toolkit: List<ToolBoxEntity>? = null,
@SerializedName("community_column_content")
var answer: List<AnswerEntity>? = null
)

View File

@ -125,7 +125,7 @@ class FuLiFragment : BaseFragment<Any>() {
})
mGameDetailViewModel?.unifiedGameDetailWithUserRelatedInfoForChildLiveData?.observeNonNull(this) {
mFuLiViewModel?.updateUnifiedGameDetailEntity(it)
// mFuLiViewModel?.updateUnifiedGameDetailEntity(it)
}
}

View File

@ -17,7 +17,6 @@ import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.entity.Star
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.personal.PersonalFragment.LOGIN_TAG
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.Subscribe
@ -73,10 +72,10 @@ class RatingFragment : ListFragment<RatingComment, RatingViewModel>() {
mAdapter?.ratingData = it
mAdapter?.notifyDataSetChanged()
val parentFragment = parentFragment
if (parentFragment is GameDetailFragment && it != null) {
parentFragment.showRatingScore(it.star)
}
// val parentFragment = parentFragment
// if (parentFragment is GameDetailFragment && it != null) {
// parentFragment.showRatingScore(it.star)
// }
})
}

View File

@ -65,6 +65,7 @@ import com.gh.gamecenter.entity.VideoEntity;
import com.gh.gamecenter.entity.VideoTagEntity;
import com.gh.gamecenter.entity.VoteEntity;
import com.gh.gamecenter.entity.WelcomeDialogEntity;
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity;
import com.gh.gamecenter.personalhome.rating.MyRating;
import com.gh.gamecenter.qa.entity.AnswerDetailEntity;
import com.gh.gamecenter.qa.entity.AnswerDraftEntity;
@ -2307,5 +2308,11 @@ public interface ApiService {
* 获取游戏详情数据(4.0.0)
*/
@GET("games/{gameId}?view=new_detail")
Single<GameDetailEntity> getGameDetailNew(@Path("gameId") String gameId);
Single<NewGameDetailEntity> getGameDetailNew(@Path("gameId") String gameId);
/**
* 获取游戏详情过滤标签数据
*/
@GET("games/filter_detail_tags")
Observable<ArrayList<String>> getFilterDetailTags();
}

View File

@ -6,9 +6,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="18dp"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingRight="18dp"
android:paddingRight="20dp"
android:paddingBottom="16dp">

View File

@ -6,9 +6,9 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="18dp"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingRight="18dp"
android:paddingRight="20dp"
android:paddingBottom="16dp"
android:background="@color/white">

View File

@ -7,9 +7,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="18dp"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingRight="18dp"
android:paddingRight="20dp"
android:paddingBottom="16dp">

View File

@ -6,9 +6,9 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="18dp"
android:paddingLeft="20dp"
android:paddingTop="16dp"
android:paddingRight="18dp"
android:paddingRight="20dp"
android:paddingBottom="16dp"
android:background="@color/white">
@ -37,7 +37,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleTv"
app:expandText="... 全部"
app:expandText="... 全部"
tools:text="每个评论的正文最多显示2行超过则使用省略号…全部点击[全部]即可展开余下全文"/>
<TextView

View File

@ -61,28 +61,49 @@
android:layout_centerHorizontal="true"
fresco:roundedCornerRadius="20dp" />
<RelativeLayout
<LinearLayout
android:id="@+id/gameDetailRankLl"
android:layout_width="match_parent"
android:layout_height="25dp"
android:layout_alignParentBottom="true"
android:background="@drawable/bg_game_detail_rank">
<TextView
android:id="@+id/gameDetailRankTv"
android:background="@drawable/bg_game_detail_rank"
android:orientation="horizontal"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginTop="7dp"
android:src="@drawable/ic_game_detail_rank_trophy" />
<TextView
android:id="@+id/gameDetailRankTv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="2dp"
android:layout_marginTop="8dp"
android:layout_marginRight="2dp"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:layout_weight="1"
android:gravity="center"
android:includeFontPadding="false"
android:textColor="@color/white"
android:textSize="9sp"
android:drawablePadding="2dp"
android:includeFontPadding="false"
android:layout_marginTop="8dp"
android:layout_centerHorizontal="true"
android:drawableLeft="@drawable/ic_game_detail_rank_trophy"
android:drawableRight="@drawable/ic_game_detail_rank_arrow"
android:textStyle="bold"
android:text="预约榜第0名"
tools:text="预约榜第1名"/>
</RelativeLayout>
tools:text="预约榜第1名" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginRight="6dp"
android:src="@drawable/ic_game_detail_rank_arrow" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
@ -96,14 +117,14 @@
android:id="@+id/gamedetail_tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:lineSpacingExtra="4dp"
android:maxLines="3"
android:textColor="@color/text_333333"
android:textSize="16sp"
android:textStyle="bold"
android:lineSpacingExtra="4dp"
android:layout_marginTop="4dp"
tools:text="地海争霸2-最后的火之高兴和霜之哀伤" />
<com.gh.common.view.FlexLinearLayout
@ -111,8 +132,8 @@
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="6dp"
android:orientation="horizontal"
android:clipToPadding="false"/>
android:clipToPadding="false"
android:orientation="horizontal" />
</LinearLayout>
<RelativeLayout
@ -145,29 +166,30 @@
android:id="@+id/gameBigEvent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:includeFontPadding="false"
android:layout_gravity="left"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:textSize="10sp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingRight="8dp"
android:paddingLeft="8dp"
android:layout_marginBottom="16dp"
android:ellipsize="end"
android:textColor="@color/text_999999"
android:drawablePadding="4dp"
android:background="@drawable/bg_game_big_event"
android:drawableLeft="@drawable/ic_game_detail_big_event_gray"
android:drawableRight="@drawable/ic_game_detail_big_event_arrow_gray"
android:background="@drawable/bg_game_big_event"
android:drawablePadding="4dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:paddingLeft="8dp"
android:paddingTop="4dp"
android:paddingRight="8dp"
android:paddingBottom="4dp"
android:text="游戏大事件游戏大事件"
tools:text="游戏大事件游戏大事件"/>
android:textColor="@color/text_999999"
android:textSize="10sp"
tools:text="游戏大事件游戏大事件" />
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@color/background"/>
android:background="@color/background" />
</LinearLayout>
<androidx.appcompat.widget.Toolbar
@ -176,33 +198,35 @@
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@android:color/transparent"
app:layout_collapseMode="pin"
app:contentInsetStartWithNavigation="0dp">
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@color/transparent"
android:gravity="center_vertical">
android:gravity="center_vertical"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/gamedetail_thumb_small"
style="@style/frescoStyle"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_centerHorizontal="true"
fresco:roundedCornerRadius="5dp"
android:visibility="gone"/>
android:visibility="gone"
fresco:roundedCornerRadius="5dp" />
<TextView
android:id="@+id/titleTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginLeft="8dp"
android:textColor="@color/white"/>
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>

View File

@ -52,6 +52,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:layout_marginRight="18dp"
android:layout_marginBottom="16dp"
android:background="@drawable/bg_shape_f8_radius_5"/>
</LinearLayout>

View File

@ -2,12 +2,11 @@
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_marginTop = "8dp"
android:background = "@android:color/white"
android:orientation = "vertical"
android:paddingLeft = "12dp"
android:paddingRight = "12dp"
android:paddingTop = "12dp" >
android:paddingLeft = "14dp"
android:paddingRight = "14dp"
android:paddingTop = "16dp" >
<TextView
android:id = "@+id/title_tv"

View File

@ -26,12 +26,6 @@
android:paddingLeft="20dp"
android:paddingBottom="12dp">
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="@dimen/cutting_line"
android:background="@color/cutting_line"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="@+id/user_icon_container"
@ -39,7 +33,7 @@
android:layout_height="35dp"
android:layout_marginTop="12dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line">
app:layout_constraintTop_toTopOf="parent">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/user_icon"
@ -61,7 +55,7 @@
</RelativeLayout>
<RelativeLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/user_name_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -78,11 +72,19 @@
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:singleLine="true"
android:maxLines="1"
android:maxLength="12"
android:ellipsize="end"
android:text="@{data.user.name}"
android:textColor="@color/text_666666"
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/sdv_user_badge"
tools:text="用户名" />
<com.facebook.drawee.view.SimpleDraweeView
@ -91,9 +93,14 @@
android:layout_height="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="2dp"
android:layout_toRightOf="@id/user_name"
android:visibility="gone"
tools:src="@drawable/logo_black" />
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="@id/user_name"
app:layout_constraintLeft_toRightOf="@id/user_name"
app:layout_constraintTop_toTopOf="@id/user_name"
app:layout_constraintRight_toLeftOf="@+id/tv_badge_name"
tools:src="@drawable/logo_black"
tools:visibility="visible"/>
<TextView
android:id="@+id/tv_badge_name"
@ -102,10 +109,15 @@
android:layout_toRightOf="@id/sdv_user_badge"
android:gravity="center"
android:textColor="@color/text_999999"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="@id/sdv_user_badge"
app:layout_constraintLeft_toRightOf="@id/sdv_user_badge"
app:layout_constraintTop_toTopOf="@id/sdv_user_badge"
app:layout_constraintRight_toRightOf="parent"
android:textSize="10sp"
android:visibility="gone"
tools:text="答题先锋" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.gh.common.view.materialratingbar.MaterialRatingBar
android:id="@+id/rating_start"
@ -134,7 +146,6 @@
android:gravity="center"
android:textColor="@color/hint"
android:textSize="12sp"
android:text="@{NewsUtils.getFormattedTime(data.time)}"
app:layout_constraintBottom_toBottomOf="@+id/rating_start"
app:layout_constraintLeft_toRightOf="@id/rating_start"
app:layout_constraintTop_toTopOf="@+id/rating_start" />
@ -164,7 +175,8 @@
android:maxLines="4"
android:textColor="@color/text_333333"
android:textSize="13sp"
android:text="@{data.content}"
app:expandText="... 全部"
app:expandTextBackgroundColor="@color/f8f8f8"
app:layout_constraintTop_toBottomOf="@+id/user_icon_container"
tools:text="每个评论的正文最多显示4行超过则使用省略号…全部点击[全部]即可展开余下全文" />

View File

@ -2,6 +2,13 @@
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="relatedVersion"
type="com.gh.gamecenter.entity.GameDetailEntity.RelatedVersion" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -21,12 +28,13 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="8dp"
android:textColor="@color/text_333333"
android:textSize="16sp"
android:textStyle="bold"
android:text="@{relatedVersion.gameName}"
app:layout_constraintStart_toEndOf="@+id/gameIconSdv"
app:layout_constraintTop_toTopOf="@+id/gameIconSdv"
android:layout_marginTop="8dp"
android:textStyle="bold"
tools:text="武侠小掌门" />
<TextView
@ -34,11 +42,13 @@
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"
app:layout_constraintStart_toEndOf="@+id/gameIconSdv"
setGameTags="@{relatedVersion.gameTags}"
setMaxGameTags="@{3}"
app:layout_constraintBottom_toBottomOf="@+id/gameIconSdv"
android:layout_marginBottom="8dp"
app:layout_constraintStart_toEndOf="@+id/gameIconSdv"
tools:text="全局加速/无需root" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -104,5 +104,6 @@
<declare-styleable name="ExpandTextView">
<attr name="expandText" format="string"/>
<attr name="expandTextBackgroundColor" format="color"/>
</declare-styleable>
</resources >