diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74faeb16ad..9d85ffe3cc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -732,6 +732,9 @@ android:name="com.gh.gamecenter.toolbox.ToolBoxBlockActivity" android:screenOrientation="portrait" /> + + diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 2904df851c..5e451a812e 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -427,7 +427,7 @@ public class BindingAdapters { return; } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { VHelper.launch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 319dc5600b..a497ff04f1 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -102,7 +102,7 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.pluggable).equals(status)) { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { - if (VHelper.isSGame(viewHolder.gameEntity)) { + if (VHelper.isVGame(viewHolder.gameEntity)) { downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); @@ -186,7 +186,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } - } else if (VHelper.isSGame(viewHolder.gameEntity)) { + } else if (VHelper.isVGame(viewHolder.gameEntity)) { viewHolder.mDownloadPb.setText(R.string.smooth_launch); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); } else { diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index a64044aa6b..0e260b928c 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -71,6 +71,7 @@ import com.gh.gamecenter.video.detail.VideoDetailActivity import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel import com.gh.gamecenter.video.game.GameVideoActivity import com.gh.gamecenter.video.videomanager.VideoManagerActivity +import com.gh.vspace.VDownloadManagerActivity import com.halo.assistant.HaloApp import com.halo.assistant.fragment.WebFragment import com.lightgame.utils.Utils @@ -1761,6 +1762,11 @@ object DirectUtils { } } + @JvmStatic + fun directToVGameDownload(context: Context) { + context.startActivity(Intent(context, VDownloadManagerActivity::class.java)) + } + @JvmStatic fun directToSuggestion(context: Context, type: SuggestType) { directToSuggestion(context = context, type = type, requestCode = null) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index b5bf14e78b..5eac0c5f2b 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -141,8 +141,11 @@ object DownloadItemUtils { @JvmStatic @JvmOverloads fun updateItem( - context: Context, gameEntity: GameEntity, holder: GameViewHolder, - isShowPlatform: Boolean, pluginLocation: PluginLocation? = PluginLocation.only_game, + context: Context, + gameEntity: GameEntity, + holder: GameViewHolder, + isShowPlatform: Boolean, + pluginLocation: PluginLocation? = PluginLocation.only_game, hideDownloadBtnIfNoAvailableContent: Boolean = false, briefStyle: String? = null, isShowRecommendStar: Boolean = false @@ -272,7 +275,7 @@ object DownloadItemUtils { } // 更新正常的条目,只有一个apk包 - private fun updateNormalItem( + fun updateNormalItem( context: Context, holder: GameViewHolder, gameEntity: GameEntity, isShowPlatform: Boolean, briefStyle: String?, isShowRecommendStar: Boolean = false @@ -753,7 +756,7 @@ object DownloadItemUtils { return } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { VHelper.launch((context as AppCompatActivity), gameEntity.getApk()[0].packageName) return } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index b0234a3124..8ee62f9746 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -320,7 +320,7 @@ public class DownloadManager implements DownloadStatusListener { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator())); } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME); } @@ -636,6 +636,23 @@ public class DownloadManager implements DownloadStatusListener { return filterSilentDownloadTask(all); } + /** + * 获取下载列表中的畅玩下载任务 + */ + public List getAllSmoothDownloadTask() { + List downloadList = getAllDownloadEntity(); + + ArrayList filteredDownloadEntityList = new ArrayList<>(); + + for (DownloadEntity downloadEntity : downloadList) { + if (Constants.SMOOTH_GAME.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE))) { + filteredDownloadEntityList.add(downloadEntity); + } + } + + return filteredDownloadEntityList; + } + private ArrayList filterSilentDownloadTask(List downloadEntityList) { ArrayList filteredDownloadEntityList = new ArrayList<>(); diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 4b03c64e78..460320c555 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -61,7 +61,8 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override public boolean onMenuItemClick(MenuItem item) { - return super.onMenuItemClick(item); + DirectUtils.directToVGameDownload(this); + return true; } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index facb87f3a1..4442384116 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -237,7 +237,7 @@ public class DetailViewHolder { return; } - if (VHelper.isSGame(mGameEntity)) { + if (VHelper.isVGame(mGameEntity)) { VHelper.launch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt index b7ba454688..571baf54d8 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.entity import com.gh.common.util.PackageUtils +import com.gh.vspace.VHelper import com.google.gson.annotations.SerializedName import com.halo.assistant.HaloApp @@ -14,6 +15,7 @@ data class GameInstall( var isSignByGh: Boolean = false, var installTime: Long = 0, var version: String = "", + var isSmoothGame: Boolean = false, // 是否是畅玩游戏 var tag: Any? = null) { companion object { @@ -28,6 +30,7 @@ data class GameInstall( gameInstall.iconSubScript = game.iconSubscript gameInstall.version = PackageUtils.getVersionNameByPackageName(installedPkgName) ?: "unknown" gameInstall.packageName = installedPkgName + gameInstall.isSmoothGame = VHelper.isVGame(game) return gameInstall } } diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 8fd07c9c0b..3de5380269 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -21,6 +21,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.ObservableUtil import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers @@ -28,7 +29,6 @@ import io.reactivex.schedulers.Schedulers import org.json.JSONException import org.json.JSONObject import java.util.* -import kotlin.collections.ArrayList /** * 该类存储的是已安装的所有游戏(助手后台已收录的)和所有更新(包括插件化)数据 @@ -54,6 +54,9 @@ object PackageRepository { val gameUpdateLiveData = MutableLiveData>() val gameInstalledLiveData = MutableLiveData>() + val installedGameListLiveData = MutableLiveData>() // 已安装的游戏列表 (信息比 GameInstall 更全) + + private val mInstalledGameList = Collections.synchronizedList(ArrayList()) val gameInstalled = Collections.synchronizedList(ArrayList()) val gameUpdate = ArrayList() @@ -66,6 +69,7 @@ object PackageRepository { fun initData() { runOnIoThread { if (gameInstalled.isNotEmpty()) gameInstalled.clear() + if (mInstalledGameList.isNotEmpty()) mInstalledGameList.clear() if (gameUpdate.isNotEmpty()) gameUpdate.clear() if (mInstalledPkgList.isNotEmpty()) mInstalledPkgList.clear() @@ -169,11 +173,14 @@ object PackageRepository { * 如果有数据变动会调用[gameUpdateLiveData] [gameInstalledLiveData]实现相关页面刷新 * * @param filteredList 已安装的游戏包名集合 (仅已收录部分) + * @param onWorkerThreadOnly 是否在工作线程执行 + * @param matchSmoothGameOnly 是否仅匹配畅玩游戏 */ @SuppressLint("CheckResult") private fun loadInstalledGameDigestAndNotifyData( filteredList: ArrayList, - onWorkerThreadOnly: Boolean = false + onWorkerThreadOnly: Boolean = false, + matchSmoothGameOnly: Boolean = false, ) { var isNotifyUpdate = false val maxPageCount = (filteredList.size / PAGE_SIZE) + 1 @@ -207,13 +214,16 @@ object PackageRepository { } for (game in validGames) { + // 仅匹配畅玩游戏时,非畅玩游戏直接跳过 + if (matchSmoothGameOnly && !VHelper.isVGame(game)) { + continue + } + if (gh_id == null || gh_id == game.id) { gameInstalled.add( - GameInstall.transformGameInstall( - game, - pkgName - ) + GameInstall.transformGameInstall(game, pkgName) ) + mInstalledGameList.add(game) val isCanPluggable = checkGamePlugin(game, pkgName) val isCanUpdate = checkGameUpdate(game) addCurrentlyInstalledVersionIfValid(game) @@ -402,8 +412,10 @@ object PackageRepository { var i = 0 while (i < gameInstalled.size) { val game = gameInstalled[i] + val gameEntity = mInstalledGameList[i] if (game.packageName == pkgName) { gameInstalled.remove(game) + mInstalledGameList.remove(gameEntity) } else { i++ } @@ -414,6 +426,7 @@ object PackageRepository { private fun notifyGameInstallData() { PackagesManager.initGameInstall(ArrayList(gameInstalled)) gameInstalledLiveData.postValue(ArrayList(gameInstalled)) + installedGameListLiveData.postValue(ArrayList(mInstalledGameList)) } private fun notifyGameUpdateData() { diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt index a69555868c..b27f514bda 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt @@ -222,7 +222,7 @@ class PersonalFragment : BaseLazyFragment() { .decorView .findViewById(android.R.id.content) .findViewById(BaseActivity.ID_ROOT_INDICATOR) - indicator.setOnClickListener { + indicator?.setOnClickListener { requireContext().startActivity( getIntent(requireContext()) ) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index 603f350732..4db3f9d99d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -1,10 +1,10 @@ package com.gh.vspace import android.os.Bundle -import com.gh.base.BaseActivity +import com.gh.base.ToolBarActivity import com.gh.gamecenter.R -class VDownloadManagerActivity: BaseActivity() { +class VDownloadManagerActivity: ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -14,6 +14,6 @@ class VDownloadManagerActivity: BaseActivity() { } } - override fun getLayoutId() = R.layout.activity_shell + override fun getLayoutId() = R.layout.activity_vdownload_manager } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 73e5353a0c..16dd35b2ab 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -1,23 +1,273 @@ package com.gh.vspace import android.content.Context +import android.view.Gravity +import android.view.LayoutInflater import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.PopupWindow +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView +import com.gh.base.CurrentActivityHolder +import com.gh.common.constant.Constants +import com.gh.common.constant.ItemViewType +import com.gh.common.util.* +import com.gh.download.DownloadManager +import com.gh.gamecenter.GameDetailActivity +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder +import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.PopupHistoryOptionBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.PluginLocation +import com.gh.gamecenter.game.GameItemViewHolder +import com.gh.gamecenter.history.ManageOption +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus +import com.lightgame.utils.Utils -class VDownloadManagerAdapter(context: Context) : ListAdapter(context) { +class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloadManagerViewModel) : + ListAdapter(context) { + + private var mPopWindow: PopupWindow? = null + private var mCurrentOption = ManageOption.OPTION_MANAGER + private var mPopupBinding: PopupHistoryOptionBinding? = null + + var selectItems = arrayListOf() + + private val mPositionAndPackageMap = HashMap() + + override fun setListData(updateData: MutableList?) { + mPositionAndPackageMap.clear() + // 记录游戏位置 + if (updateData != null) { + for (i in 0 until updateData.size) { + val gameEntity = updateData[i] + var packages = gameEntity.id + for (apkEntity in gameEntity.getApk()) { + packages += apkEntity.packageName + } + mPositionAndPackageMap[packages + i] = i + } + } + super.setListData(updateData) + } + + override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem?.id == newItem?.id + } + + override fun getItemViewType(position: Int) = ItemViewType.GAME_NORMAL override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - TODO("Not yet implemented") + return GameItemViewHolder(parent.toBinding()) } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - TODO("Not yet implemented") + override fun getItemCount(): Int = if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + + fun changeOption(option: ManageOption) { + mCurrentOption = option + when (mCurrentOption) { + ManageOption.OPTION_MANAGER -> { + selectItems.clear() + mPopWindow?.dismiss() + mPopWindow = null + } + else -> { + if (mPopWindow == null || mPopWindow?.isShowing == false) { + showOptionWindow() + } + } + } + notifyItemRangeChanged(0, mEntityList.size) } - override fun getItemCount(): Int { - TODO("Not yet implemented") + override fun onBindViewHolder( + holder: RecyclerView.ViewHolder, + position: Int + ) { + when (holder) { + is GameItemViewHolder -> { + val gameEntity = mEntityList[position] + + holder.bindGameItem(gameEntity) + holder.initServerType(gameEntity) + + (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { + width = 20F.dip2px() + height = 20F.dip2px() + holder.binding.selectIv.layoutParams = this + } + holder.binding.selectIv.setImageDrawable(R.drawable.selector_ic_history.toDrawable()) + holder.binding.selectIv.goneIf(mCurrentOption == ManageOption.OPTION_MANAGER) + holder.binding.selectIv.isChecked = selectItems.contains(gameEntity.id) + + holder.itemView.setOnClickListener { + if (mCurrentOption == ManageOption.OPTION_MANAGER) { + GameDetailActivity.startGameDetailActivity( + mContext, + gameEntity.id, + "(畅玩游戏管理)" + ) + } else { + if (selectItems.contains(gameEntity.id)) { + selectItems.remove(gameEntity.id) + } else { + selectItems.add(gameEntity.id) + } + checkSelectItems() + notifyItemChanged(position) + } + } + + DownloadItemUtils.updateNormalItem(mContext, GameViewHolder(holder.binding), gameEntity, true, null) + updateDownloadBtn(mContext, holder.binding.downloadBtn, gameEntity) + + holder.itemView.setOnLongClickListener { + consume { + DialogHelper.showDialog(holder.binding.root.context, + "删除记录", + "删除浏览记录将不可恢复,确定删除吗?", + "确定", + "取消", { + mViewModel.removeItem() + }) + } + } + } + is FooterViewHolder -> { + holder.initItemPadding() + holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver) + } + } + } + + private fun showOptionWindow() { + mPopupBinding = PopupHistoryOptionBinding.inflate(LayoutInflater.from(mContext)) + mPopupBinding?.root?.isFocusable = true + mPopupBinding?.root?.isFocusableInTouchMode = true + + mPopWindow = + PopupWindow(mPopupBinding?.root, LinearLayout.LayoutParams.MATCH_PARENT, 56F.dip2px()) + mPopWindow?.showAtLocation( + (mContext as AppCompatActivity).window.decorView, + Gravity.BOTTOM, + 0, + 0 + ) + + mPopupBinding?.itemDelete?.setOnClickListener { + DialogHelper.showDialog( + mContext, + "是否删除${selectItems.size}条记录?", + "提示:删除记录将不可恢复", + "删除", + "取消", + { + mViewModel.removeItems() + selectItems.clear() + checkSelectItems() + }, + extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) + ) + } + mPopupBinding?.checkAllCb?.setOnClickListener { + if (mPopupBinding?.checkAllCb?.isChecked == true) { + selectItems.clear() + selectItems.addAll(mEntityList.map { it.id }.toList()) + } else { + selectItems.clear() + } + checkSelectItems() + notifyItemRangeChanged(0, mEntityList.size) + } + checkSelectItems() + } + + private fun checkSelectItems() { + mPopupBinding?.run { + selectNumTv.text = if (selectItems.isEmpty()) "" else "(${selectItems.size})" + itemDelete.background = + if (selectItems.isEmpty()) R.drawable.bg_shape_f5_radius_999.toDrawable() else R.drawable.download_button_normal_style.toDrawable() + itemDelete.setTextColor(if (selectItems.isEmpty()) R.color.text_body.toColor() else R.color.white.toColor()) + itemDelete.isEnabled = selectItems.isNotEmpty() + checkAllCb.isChecked = selectItems.size == mEntityList.size + } + } + + fun notifyItemByDownload(download: DownloadEntity) { + for (key in mPositionAndPackageMap.keys) { + if (key.contains(download.packageName) && key.contains(download.gameId)) { + val position = mPositionAndPackageMap[key] + if (position != null && mEntityList != null && position < mEntityList.size) { + mEntityList[position].getEntryMap()[download.platform] = download + notifyItemChanged(position) + } + } + } + } + + private fun updateDownloadBtn(context: Context, + downloadBtn: TextView, + gameEntity: GameEntity) { + // 青少年模式显示查看 + if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) { + downloadBtn.text = "查看" + return + } + + if (gameEntity.getApk().size == 1) { + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) + if (downloadEntity != null) { + val status = downloadEntity.status + var btnText = R.string.downloading + var btnColor = R.color.white + var btnBackground = R.drawable.download_button_normal_style + + downloadBtn.apply { + if (status == DownloadStatus.downloading) { + btnText = R.string.pause + btnBackground = R.drawable.button_normal_round_border + btnColor = R.color.theme_font + setOnClickListener { DownloadManager.getInstance().pause(downloadEntity.url) } + } else if (status == DownloadStatus.waiting) { + btnText = R.string.waiting + setOnClickListener { Utils.toast(mContext, "最多只能同时启动3个下载任务"); } + } else if (status == DownloadStatus.pause + || status == DownloadStatus.timeout + || status == DownloadStatus.neterror + || status == DownloadStatus.subscribe + || status == DownloadStatus.overflow + ) { + btnText = R.string.resume + setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, true) + } + } else if (status == DownloadStatus.done) { + if (downloadEntity.isSmoothGame()) { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } + + setOnClickListener { + CurrentActivityHolder.getCurrentActivity()?.let { + VHelper.launch(it, downloadEntity.packageName) + } + } + } + + setText(btnText) + setTextColor(btnColor.toColor()) + setBackgroundResource(btnBackground) + } + } else { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } + } else { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 9769590ae4..4b838f58ca 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -1,13 +1,114 @@ package com.gh.vspace +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.ethanhua.skeleton.Skeleton +import com.gh.common.util.toColor +import com.gh.common.util.toDrawable +import com.gh.common.util.viewModelProvider +import com.gh.common.view.CustomDividerItemDecoration +import com.gh.download.DownloadManager +import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.history.IBatchDelete +import com.gh.gamecenter.history.ManageOption +import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadEntity -class VDownloadManagerFragment: ListFragment() { +class VDownloadManagerFragment : + ListFragment(), IBatchDelete { - private val mAdapter by lazy { VDownloadManagerAdapter(requireContext()) } + private var mManageMenu: MenuItem? = null + + private val mAdapter by lazy { VDownloadManagerAdapter(requireContext(), provideListViewModel()) } + private val mViewModel: VDownloadManagerViewModel by lazy { viewModelProvider() } + private val mBinding by lazy { FragmentListBaseSkeletonBinding.inflate(layoutInflater) } + + private val dataWatcher: DataWatcher = object : DataWatcher() { + override fun onDataChanged(downloadEntity: DownloadEntity) { + mAdapter.notifyItemByDownload(downloadEntity) + } + } override fun provideListAdapter(): ListAdapter<*> = mAdapter + override fun provideListViewModel(): VDownloadManagerViewModel = mViewModel + + override fun getLayoutId() = R.layout.fragment_list_base_skeleton + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + initMenu(R.menu.menu_manage) + mManageMenu = getItemMenu(R.id.layout_menu_manage) + mManageMenu?.actionView?.setOnClickListener { + when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_CANCEL_SELECT + } + ManageOption.OPTION_CANCEL_SELECT -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER + } + } + changeOption(mViewModel.currentOptionLiveData.value ?: ManageOption.OPTION_MANAGER) + } + changeMenuTextByOption() + + mViewModel.currentOptionLiveData.observe(this) { + changeMenuTextByOption() + } + } + + override fun onResume() { + super.onResume() + setNavigationTitle("畅玩游戏管理") + DownloadManager.getInstance().addObserver(dataWatcher) + } + + override fun onPause() { + super.onPause() + DownloadManager.getInstance().removeObserver(dataWatcher) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mCachedView.setBackgroundColor(R.color.white.toColor()) + mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) + .load(R.layout.fragment_subject_skeleton).show() + } + + override fun changeOption(option: ManageOption) { + mAdapter.changeOption(option) + changeMenuTextByOption() + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration { + val itemDecoration = CustomDividerItemDecoration( + requireContext(), + onlyDecorateTheFirstItem = false, + notDecorateTheFirstItem = false, + notDecorateTheLastItem = true, + notDecorateTheFirstTwoItems = false + ) + itemDecoration.setDrawable(R.drawable.divider_item_line_space_16.toDrawable()!!) + return itemDecoration + } + + override fun shouldLoadMore() = false + + private fun changeMenuTextByOption() { + (mManageMenu?.actionView as? TextView)?.apply { + text = when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> "编辑" + ManageOption.OPTION_CANCEL_SELECT -> "取消" + else -> "" + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 75ae89f950..d6bce66586 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -1,19 +1,77 @@ package com.gh.vspace import android.app.Application +import androidx.lifecycle.MutableLiveData +import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.history.ManageOption +import com.gh.gamecenter.packagehelper.PackageRepository +import com.lightgame.download.DownloadEntity import io.reactivex.Observable +import io.reactivex.Single -class VDownloadManagerViewModel(application: Application) - : ListViewModel(application) { +class VDownloadManagerViewModel(application: Application) : + ListViewModel(application) { + + var currentOptionLiveData = MutableLiveData(ManageOption.OPTION_MANAGER) override fun mergeResultLiveData() { - TODO("Not yet implemented") + mResultLiveData.addSource(mListLiveData) { + mResultLiveData.postValue(it) + } } - override fun provideDataObservable(page: Int): Observable> { - TODO("Not yet implemented") + override fun provideDataObservable(page: Int): Observable>? = null + + override fun provideDataSingle(page: Int): Single> { + return Single.create { emitter -> + val installedGameList = + PackageRepository.installedGameListLiveData.value ?: arrayListOf() + val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + + val vGameList = arrayListOf() + + for (downloadEntity in vDownloadList) { + gameIdSet.add(downloadEntity.gameId) + vGameList.add(toGameEntity(downloadEntity)) + } + + for (game in installedGameList) { + if (VHelper.isVGame(game) && !gameIdSet.contains(game.id)) { + vGameList.add(game) + } + } + + emitter.onSuccess(vGameList) + } + } + + private fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { + return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { + setApk( + arrayListOf( + ApkEntity( + packageName = downloadEntity.packageName, + url = downloadEntity.url, + platform = downloadEntity.platform + ) + ) + ) + icon = downloadEntity.icon + downloadStatus = "smooth" + setEntryMap(DownloadManager.getInstance().getEntryMap(name)) + } + } + + fun removeItem() { + // TODO 移除下载任务 and 卸载 VA 安装 + } + + fun removeItems() { + // TODO 移除下载任务 and 卸载 VA 安装 } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 833bf0ae61..6645e5c0fb 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -21,7 +21,6 @@ object VHelper { private const val LOG_TAG = "VSPACE" private const val VSPACE_PACKAGE_NAME = "com.lg.vspace" - private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -61,7 +60,7 @@ object VHelper { * 是否是使用畅玩启动类型的游戏 */ @JvmStatic - fun isSGame(gameEntity: GameEntity?): Boolean { + fun isVGame(gameEntity: GameEntity?): Boolean { return gameEntity?.downloadStatus != "smooth" } diff --git a/app/src/main/res/layout/activity_vdownload_manager.xml b/app/src/main/res/layout/activity_vdownload_manager.xml new file mode 100644 index 0000000000..1b659a5a1e --- /dev/null +++ b/app/src/main/res/layout/activity_vdownload_manager.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7672fd2079..972723e9bf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -372,6 +372,8 @@ 下载中 插件化 安装 + 继续 + 暂停 启动 更新 更新中