From 001cbfcdb68b1df7df4986d692d89bf5391df4b4 Mon Sep 17 00:00:00 2001 From: jack <1484288157@qq.com> Date: Sat, 6 Nov 2021 15:55:06 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9=E6=89=8BV5?= =?UTF-8?q?.5.0=E3=80=91=E5=88=9B=E5=BB=BA/=E7=BC=96=E8=BE=91=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=8D=95(=E9=80=89=E6=8B=A9=E6=B8=B8=E6=88=8F/?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B8=B8=E6=88=8FUI)=20https://git.ghzs.com/?= =?UTF-8?q?pm/halo-app-issues/-/issues/1604?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 10 +- .../com/gh/common/util/SingletonHolder.kt | 26 +++ .../gamecollection/choose/AddGamesActivity.kt | 19 ++ .../gamecollection/choose/AddGamesFragment.kt | 19 ++ .../choose/AddSearchAndPlayedGameAdapter.kt | 44 ++++ .../choose/AddSearchGameFragment.kt | 59 ++++++ .../choose/AddUserPlayedGameFragment.kt | 51 +++++ .../choose/ChooseGamesActivity.kt | 23 ++ .../choose/ChooseGamesAdapter.kt | 69 ++++++ .../choose/ChooseGamesFragment.kt | 108 ++++++++++ .../choose/ChooseGamesRepository.kt | 12 ++ .../choose/ChooseGamesViewModel.kt | 21 ++ .../publish/GameCollectionEditActivity.kt | 39 +++- ...odel.kt => GameCollectionEditViewModel.kt} | 2 +- .../gamecenter/mygame/PlayedGameViewModel.kt | 50 ++--- .../home/game/UserPlayedGameFragment.kt | 2 +- .../gh/gamecenter/qa/editor/GameActivity.kt | 197 +----------------- .../gh/gamecenter/qa/editor/GameAdapter.kt | 2 +- .../gh/gamecenter/qa/editor/GameFragment.kt | 190 +++++++++++++++++ .../drawable-xxxhdpi/ic_choose_games_drag.png | Bin 0 -> 473 bytes .../drawable-xxxhdpi/ic_choose_games_top.png | Bin 0 -> 1491 bytes .../res/drawable-xxxhdpi/icon_add_games.webp | Bin 0 -> 3594 bytes .../res/drawable/bg_shape_f5_radius_6.xml | 6 + .../layout/activity_editor_insert_game.xml | 3 - .../layout/activity_game_collection_edit.xml | 10 +- .../layout/fragment_add_user_played_game.xml | 57 +++++ .../main/res/layout/fragment_choose_games.xml | 56 +++++ .../main/res/layout/fragment_search_game.xml | 162 ++++++++++++++ app/src/main/res/layout/item_choose_games.xml | 116 +++++++++++ app/src/main/res/layout/layout_menu_save.xml | 18 ++ app/src/main/res/menu/menu_save.xml | 11 + 31 files changed, 1146 insertions(+), 236 deletions(-) create mode 100644 app/src/main/java/com/gh/common/util/SingletonHolder.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt rename app/src/main/java/com/gh/gamecenter/gamecollection/publish/{GameCollectionViewModel.kt => GameCollectionEditViewModel.kt} (61%) create mode 100644 app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png create mode 100644 app/src/main/res/drawable-xxxhdpi/icon_add_games.webp create mode 100644 app/src/main/res/drawable/bg_shape_f5_radius_6.xml create mode 100644 app/src/main/res/layout/fragment_add_user_played_game.xml create mode 100644 app/src/main/res/layout/fragment_choose_games.xml create mode 100644 app/src/main/res/layout/fragment_search_game.xml create mode 100644 app/src/main/res/layout/item_choose_games.xml create mode 100644 app/src/main/res/layout/layout_menu_save.xml create mode 100644 app/src/main/res/menu/menu_save.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index df0dbb1963..74fc368709 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -727,7 +727,15 @@ android:screenOrientation="portrait" /> + + + + (creator: () -> T) { + private var creator: (() -> T)? = creator + + @Volatile + private var instance: T? = null + + fun getInstance(): T { + val obj = instance + if (obj != null) { + return obj + } + return synchronized(this) { + val obj1 = instance + if (obj1 != null) { + obj1 + } else { + val created = creator!!() + instance = created + creator = null + created + } + } + } +} diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt new file mode 100644 index 0000000000..09a979b0d0 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt @@ -0,0 +1,19 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.gh.gamecenter.NormalActivity + +class AddGamesActivity : NormalActivity() { + + override fun provideNormalIntent(): Intent { + return getTargetIntent(this, AddGamesActivity::class.java, AddGamesFragment::class.java) + } + + companion object { + fun getIntent(context: Context): Intent { + return getTargetIntent(context, AddGamesActivity::class.java, AddGamesFragment::class.java) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt new file mode 100644 index 0000000000..b994ba2dfa --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt @@ -0,0 +1,19 @@ +package com.gh.gamecenter.gamecollection.choose + +import androidx.core.os.bundleOf +import androidx.fragment.app.Fragment +import com.gh.base.fragment.BaseLazyTabFragment +import com.gh.common.util.EntranceUtils + +class AddGamesFragment : BaseLazyTabFragment() { + + override fun initFragmentList(fragments: MutableList) { + fragments.add(AddSearchGameFragment().apply { bundleOf(EntranceUtils.KEY_NAVIGATION_TITLE to "添加游戏") }) + fragments.add(AddUserPlayedGameFragment()) + } + + override fun initTabTitleList(tabTitleList: MutableList) { + tabTitleList.add("搜索游戏") + tabTitleList.add("玩过游戏") + } +} diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt new file mode 100644 index 0000000000..3864f12d74 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt @@ -0,0 +1,44 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.content.Context +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.ToastUtils +import com.gh.common.util.toColor +import com.gh.common.util.toDrawable +import com.gh.gamecenter.R +import com.gh.gamecenter.game.GameItemViewHolder +import com.gh.gamecenter.qa.editor.GameAdapter + +class AddSearchAndPlayedGameAdapter(context: Context, val mChooseGamesViewModel: ChooseGamesViewModel) : GameAdapter(context) { + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is GameItemViewHolder) { + val entity = mEntityList[position] + val isSelected = mChooseGamesViewModel.chooseGamesLiveData.value?.find { it.id == entity.id } != null + holder.binding.game = entity + holder.binding.downloadBtn.text = if (isSelected) "删除" else "添加" + holder.binding.downloadBtn.background = + if (isSelected) R.drawable.bg_shape_f5_radius_999.toDrawable() else R.drawable.download_button_normal_style.toDrawable() + holder.binding.downloadBtn.setTextColor(if (isSelected) R.color.text_999999.toColor() else R.color.white.toColor()) + + holder.binding.downloadBtn.setOnClickListener { + val chooseGameList = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf() + if (isSelected) { + chooseGameList.remove(chooseGameList.find { it.id == entity.id }) + ToastUtils.showToast("游戏已移除") + } else { + if (chooseGameList.size >= 100) { + ToastUtils.showToast("已添加游戏到达上限") + return@setOnClickListener + } + chooseGameList.add(entity) + ToastUtils.showToast("游戏已添加") + } + notifyItemChanged(position) + mChooseGamesViewModel.chooseGamesLiveData.postValue(chooseGameList) + } + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt new file mode 100644 index 0000000000..ab0a01cb9c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt @@ -0,0 +1,59 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.os.Bundle +import android.view.View +import androidx.core.widget.doOnTextChanged +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.goneIf +import com.gh.common.util.viewModelProvider +import com.gh.gamecenter.R +import com.gh.gamecenter.SuggestionActivity +import com.gh.gamecenter.databinding.FragmentSearchGameBinding +import com.gh.gamecenter.qa.editor.GameAdapter +import com.gh.gamecenter.qa.editor.GameFragment +import com.gh.gamecenter.suggest.SuggestType + +class AddSearchGameFragment : GameFragment() { + + private lateinit var mBinding: FragmentSearchGameBinding + private lateinit var mChooseGamesViewModel: ChooseGamesViewModel + + override fun getLayoutId(): Int = 0 + + override fun getInflatedLayout(): View { + return FragmentSearchGameBinding.bind(layoutInflater.inflate(R.layout.fragment_search_game, null, false)).apply { + mBinding = this + }.root + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory()) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setNavigationTitle("添加游戏") + noneText.text = "没有找到相关游戏,换个搜索词试试?" + searchEt.doOnTextChanged { text, _, _, _ -> + mBinding.promptTv.goneIf(!text.isNullOrEmpty()) + } + + mBinding.applyGameTv.setOnClickListener { + SuggestionActivity.startSuggestionActivity(requireContext(), SuggestType.gameCollect, "求游戏:") + } + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration? { + return null + } + + override fun provideListAdapter(): GameAdapter? { + if (mAdapter == null) { + mAdapter = AddSearchAndPlayedGameAdapter(requireContext(), mChooseGamesViewModel) + } + return mAdapter + } + + override fun isAutoShowKeyboard(): Boolean = false +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt new file mode 100644 index 0000000000..c2801c2e23 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt @@ -0,0 +1,51 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.EntranceUtils +import com.gh.common.util.toColor +import com.gh.common.util.viewModelProvider +import com.gh.gamecenter.R +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.manager.UserManager +import com.gh.gamecenter.mygame.PlayedGameViewModel +import com.gh.gamecenter.qa.editor.GameAdapter + +class AddUserPlayedGameFragment : ListFragment() { + + private var mAdapter: GameAdapter? = null + private lateinit var mViewModel: PlayedGameViewModel + private lateinit var mChooseGamesViewModel: ChooseGamesViewModel + + override fun getLayoutId(): Int = R.layout.fragment_add_user_played_game + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory()) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mCachedView.setBackgroundColor(R.color.white.toColor()) + } + + override fun provideListAdapter(): ListAdapter { + return mAdapter ?: AddSearchAndPlayedGameAdapter(requireContext(), mChooseGamesViewModel).apply { + mAdapter = this + } + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration? { + return null + } + + override fun provideListViewModel(): PlayedGameViewModel { + val userId = arguments?.getString(EntranceUtils.KEY_USER_ID) + ?: UserManager.getInstance().userId + mViewModel = viewModelProvider(PlayedGameViewModel.Factory(userId, true)) + return mViewModel + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt new file mode 100644 index 0000000000..0769fa62a5 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt @@ -0,0 +1,23 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.gh.gamecenter.NormalActivity + +class ChooseGamesActivity : NormalActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setNavigationTitle("选择游戏") + } + + override fun provideNormalIntent(): Intent { + return getTargetIntent(this, ChooseGamesActivity::class.java, ChooseGamesFragment::class.java) + } + + companion object { + fun getIntent(context: Context): Intent { + return getTargetIntent(context, ChooseGamesActivity::class.java, ChooseGamesFragment::class.java) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt new file mode 100644 index 0000000000..3fcf57c08e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt @@ -0,0 +1,69 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.annotation.SuppressLint +import android.content.Context +import android.view.MotionEvent +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.base.BaseRecyclerViewHolder +import com.gh.common.util.TextHelper +import com.gh.common.util.consume +import com.gh.common.util.toBinding +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.ItemChooseGamesBinding +import com.gh.gamecenter.entity.GameEntity +import com.lightgame.adapter.BaseRecyclerAdapter + +class ChooseGamesAdapter(context: Context, val dragListener: ItemDragListener) : + ListAdapter(context) { + + + public override fun setListData(updateData: MutableList?) { + super.setListData(updateData) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return ChooseGamesViewHolder(parent.toBinding()) + } + + override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem?.id == newItem?.id + } + + @SuppressLint("ClickableViewAccessibility") + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is ChooseGamesViewHolder) { + val gameEntity = mEntityList[position] + holder.binding.gameNameTv.text = gameEntity.name + holder.binding.gameIcon.displayGameIcon(gameEntity) + holder.binding.recommendReasonEt.filters = arrayOf(TextHelper.getFilter(45, "最多输入45个字")) + holder.binding.deleteIv.setOnClickListener { + dragListener.deleteItem(gameEntity) + } + holder.binding.dragView.setOnTouchListener { _, event -> + consume { + if (event.action == MotionEvent.ACTION_DOWN) { + dragListener.startDragItem(holder) + } + } + } + holder.binding.topView.setOnClickListener { + dragListener.setToTop(holder) + } + } + } + + override fun getItemCount(): Int = mEntityList.size + + class ChooseGamesViewHolder(val binding: ItemChooseGamesBinding) : BaseRecyclerViewHolder(binding.root) + + interface ItemDragListener { + fun startDragItem(holder: RecyclerView.ViewHolder) + fun setToTop(holder: RecyclerView.ViewHolder) + fun deleteItem(entity: GameEntity) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt new file mode 100644 index 0000000000..9aed0f7833 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt @@ -0,0 +1,108 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.goneIf +import com.gh.common.util.viewModelProvider +import com.gh.gamecenter.R +import com.gh.gamecenter.databinding.FragmentChooseGamesBinding +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.normal.NormalFragment +import java.util.* + +class ChooseGamesFragment : NormalFragment(), ChooseGamesAdapter.ItemDragListener { + + private lateinit var mBinding: FragmentChooseGamesBinding + private lateinit var mViewModel: ChooseGamesViewModel + private lateinit var mAdapter: ChooseGamesAdapter + + private val mItemTouchCallback = object : ItemTouchHelper.Callback() { + override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { + return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) + } + + override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + mAdapter.notifyItemMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition) + Collections.swap(mAdapter.entityList, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition) + val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf() + Collections.swap(games, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition) + return true + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + + } + + override fun canDropOver(recyclerView: RecyclerView, current: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + return true + } + + override fun isLongPressDragEnabled(): Boolean { + return false + } + + } + private val mItemTouchHelper = ItemTouchHelper(mItemTouchCallback) + + override fun getLayoutId(): Int = 0 + + override fun getInflatedLayout(): View { + return FragmentChooseGamesBinding.inflate(layoutInflater, null, false).apply { + mBinding = this + }.root + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + initMenu(R.menu.menu_save) + mViewModel = viewModelProvider(ChooseGamesViewModel.Factory()) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mViewModel.chooseGamesLiveData.observe(viewLifecycleOwner) { + mBinding.addGamesTv.goneIf(it.isNotEmpty()) + mBinding.gamesRv.goneIf(it.isEmpty()) + mAdapter.setListData(it) + mBinding.gameCountTv.text = "已收录${it.size}款游戏" + } + mBinding.gamesRv.apply { + layoutManager = LinearLayoutManager(requireContext()) + adapter = ChooseGamesAdapter(requireContext(), this@ChooseGamesFragment).apply { + mAdapter = this + } + mItemTouchHelper.attachToRecyclerView(this) + } + + mBinding.addGamesButton.setOnClickListener { + requireContext().startActivity(AddGamesActivity.getIntent(requireContext())) + } + + mBinding.addGamesTv.setOnClickListener { mBinding.addGamesButton.performClick() } + + } + + override fun startDragItem(holder: RecyclerView.ViewHolder) { + mItemTouchHelper.startDrag(holder) + } + + override fun setToTop(holder: RecyclerView.ViewHolder) { + val holderPosition = holder.bindingAdapterPosition + for (i in holderPosition downTo 1) { + mAdapter.notifyItemMoved(i, i - 1) + Collections.swap(mAdapter.entityList, i, i - 1) + val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf() + Collections.swap(games, i, i - 1) + } + } + + override fun deleteItem(entity: GameEntity) { + val chooseGames = mViewModel.chooseGamesLiveData.value + chooseGames?.remove(entity) + mViewModel.chooseGamesLiveData.postValue(chooseGames) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt new file mode 100644 index 0000000000..4ccdd3d248 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt @@ -0,0 +1,12 @@ +package com.gh.gamecenter.gamecollection.choose + +import androidx.lifecycle.MutableLiveData +import com.gh.common.util.SingletonHolder +import com.gh.gamecenter.entity.GameEntity + +class ChooseGamesRepository private constructor() { + + val chooseGamesLiveData: MutableLiveData> = MutableLiveData() + + companion object : SingletonHolder(::ChooseGamesRepository) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt new file mode 100644 index 0000000000..3822a7e5d1 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt @@ -0,0 +1,21 @@ +package com.gh.gamecenter.gamecollection.choose + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.halo.assistant.HaloApp + +class ChooseGamesViewModel(application: Application, repository: ChooseGamesRepository) : AndroidViewModel(application) { + + val chooseGamesLiveData = repository.chooseGamesLiveData + + class Factory : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return ChooseGamesViewModel( + HaloApp.getInstance().application, + ChooseGamesRepository.getInstance() + ) as T + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt index f80adc305c..c85d47a426 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt @@ -11,6 +11,8 @@ import com.gh.common.util.* import com.gh.gamecenter.CropImageActivity import com.gh.gamecenter.R import com.gh.gamecenter.databinding.ActivityGameCollectionEditBinding +import com.gh.gamecenter.gamecollection.choose.ChooseGamesActivity +import com.gh.gamecenter.gamecollection.choose.ChooseGamesViewModel import com.gh.gamecenter.qa.editor.LocalMediaActivity import com.zhihu.matisse.Matisse import com.zhihu.matisse.internal.utils.PathUtils @@ -19,7 +21,8 @@ class GameCollectionEditActivity : ToolBarActivity() { private lateinit var mMenuPost: MenuItem private lateinit var mBinding: ActivityGameCollectionEditBinding - private lateinit var mViewModel: GameCollectionViewModel + private lateinit var mViewModel: GameCollectionEditViewModel + private lateinit var mChooseGamesViewModel: ChooseGamesViewModel override fun getLayoutId(): Int = R.layout.activity_game_collection_edit @@ -27,6 +30,7 @@ class GameCollectionEditActivity : ToolBarActivity() { super.onCreate(savedInstanceState) mBinding = ActivityGameCollectionEditBinding.bind(mContentView) mViewModel = viewModelProvider() + mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory()) setToolbarMenu(R.menu.menu_game_collection_edit) mMenuPost = getMenuItem(R.id.menu_game_collection_post) setNavigationTitle("创建游戏单") @@ -63,6 +67,10 @@ class GameCollectionEditActivity : ToolBarActivity() { mBinding.gameCollectionIntroduceEt.doOnTextChanged { text, start, before, count -> mBinding.introduceSizeTv.text = "${text?.length ?: 0}/200" } + + mBinding.chooseGameContainer.setOnClickListener { + startActivityForResult(ChooseGamesActivity.getIntent(this), REQUEST_CHOOSE_GAMES) + } } private fun initData() { @@ -70,7 +78,10 @@ class GameCollectionEditActivity : ToolBarActivity() { } private fun observeData() { - + mChooseGamesViewModel.chooseGamesLiveData.observe(this) { + mBinding.gamesTv.text = if (it.isEmpty()) "选择游戏" else "已选 ${it.size} 款游戏" + mBinding.gamesTipTv.goneIf(it.isNotEmpty()) + } } override fun onMenuItemClick(item: MenuItem?): Boolean { @@ -80,16 +91,21 @@ class GameCollectionEditActivity : ToolBarActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (data == null || resultCode != Activity.RESULT_OK) return - if (requestCode == REQUEST_CODE_IMAGE) { - val selectedPaths = Matisse.obtainResult(data) - if (!selectedPaths.isNullOrEmpty()) { - val path = PathUtils.getPath(this, selectedPaths[0]) - val intent = CropImageActivity.getIntent(this, path, 142 / 328F, false, mEntrance) - startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP) + when (requestCode) { + REQUEST_CODE_IMAGE -> { + val selectedPaths = Matisse.obtainResult(data) + if (!selectedPaths.isNullOrEmpty()) { + val path = PathUtils.getPath(this, selectedPaths[0]) + val intent = CropImageActivity.getIntent(this, path, 142 / 328F, false, mEntrance) + startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP) + } + } + REQUEST_CODE_IMAGE_CROP -> { + val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: "" + initPosterUI(imagePath) + } + REQUEST_CHOOSE_GAMES -> { } - } else if (requestCode == REQUEST_CODE_IMAGE_CROP) { - val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: "" - initPosterUI(imagePath) } } @@ -109,6 +125,7 @@ class GameCollectionEditActivity : ToolBarActivity() { const val REQUEST_CODE_IMAGE = 100 const val REQUEST_CODE_IMAGE_CROP = 101 + const val REQUEST_CHOOSE_GAMES = 102 @JvmStatic fun getIntent(context: Context): Intent { diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt similarity index 61% rename from app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt rename to app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt index 251c02bcf6..173e63e661 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt @@ -3,6 +3,6 @@ package com.gh.gamecenter.gamecollection.publish import android.app.Application import androidx.lifecycle.AndroidViewModel -class GameCollectionViewModel(application: Application) : AndroidViewModel(application) { +class GameCollectionEditViewModel(application: Application) : AndroidViewModel(application) { var imagePath = "" } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt index 203f6982f9..17bb6bd809 100644 --- a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt @@ -16,8 +16,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody -class PlayedGameViewModel(application: Application, var userId: String) - : ListViewModel(application) { +class PlayedGameViewModel(application: Application, var userId: String, val isKeepTagStyle: Boolean = false) : + ListViewModel(application) { override fun provideDataObservable(page: Int): Observable>? { return null @@ -29,9 +29,11 @@ class PlayedGameViewModel(application: Application, var userId: String) override fun mergeResultLiveData() { mResultLiveData.addSource(mListLiveData) { - it.forEach { game -> - game.hideSizeInsideDes = true - game.tagStyle.clear() + if (!isKeepTagStyle) { + it.forEach { game -> + game.hideSizeInsideDes = true + game.tagStyle.clear() + } } mResultLiveData.postValue(it) } @@ -40,32 +42,32 @@ class PlayedGameViewModel(application: Application, var userId: String) @SuppressLint("CheckResult") fun deletePlayedGame(gameEntity: GameEntity) { RetrofitManager.getInstance(getApplication()).api - .deletePlayedGame(userId, gameEntity.playedGameId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: ResponseBody) { - mListLiveData.value?.let { - for (game in it) { - if (gameEntity.id == game.id) { - it.remove(game) - mListLiveData.postValue(it) - break - } + .deletePlayedGame(userId, gameEntity.playedGameId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + mListLiveData.value?.let { + for (game in it) { + if (gameEntity.id == game.id) { + it.remove(game) + mListLiveData.postValue(it) + break } } } + } - override fun onFailure(exception: Exception) { - super.onFailure(exception) - Utils.toast(getApplication(), exception.localizedMessage) - } - }) + override fun onFailure(exception: Exception) { + super.onFailure(exception) + Utils.toast(getApplication(), exception.localizedMessage) + } + }) } - class Factory(private val mUserId: String) : ViewModelProvider.NewInstanceFactory() { + class Factory(private val mUserId: String, val isKeepTagStyle: Boolean = false) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return PlayedGameViewModel(HaloApp.getInstance().application, mUserId) as T + return PlayedGameViewModel(HaloApp.getInstance().application, mUserId, isKeepTagStyle) as T } } diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt index 5eab999e09..e810967e03 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt @@ -26,7 +26,7 @@ import com.lightgame.download.DownloadEntity import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode -class UserPlayedGameFragment: ListFragment() { +open class UserPlayedGameFragment: ListFragment() { private var mUserId = "" private var mAdapter: UserPlayedGameAdapter? = null diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt index 0028f12c36..bddaa7d784 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt @@ -2,201 +2,22 @@ package com.gh.gamecenter.qa.editor import android.content.Context import android.content.Intent -import android.os.Bundle -import android.os.Message -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import android.view.inputmethod.EditorInfo -import android.widget.EditText -import android.widget.TextView -import androidx.lifecycle.ViewModelProviders -import androidx.recyclerview.widget.RecyclerView -import com.gh.common.constant.Config +import androidx.core.os.bundleOf import com.gh.common.util.EntranceUtils -import com.gh.common.view.FixLinearLayoutManager -import com.gh.common.view.VerticalItemDecoration -import com.gh.gamecenter.BuildConfig -import com.gh.gamecenter.R -import com.gh.gamecenter.baselist.ListActivity -import com.gh.gamecenter.baselist.NormalListViewModel -import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.manager.UserManager -import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity -import com.gh.gamecenter.retrofit.Response -import com.gh.gamecenter.retrofit.RetrofitManager -import com.google.android.material.appbar.AppBarLayout -import com.halo.assistant.HaloApp -import com.lightgame.utils.Util_System_Keyboard -import io.reactivex.Observable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers -import kotterknife.bindView +import com.gh.gamecenter.NormalActivity -class GameActivity : ListActivity>() { +class GameActivity : NormalActivity() { - val searchEt by bindView(R.id.search_input) - val searchTv by bindView(R.id.search_button) - val searchBack by bindView(R.id.search_back) - val appBar by bindView(R.id.list_appbar) - val noneText by bindView(R.id.reuse_tv_none_data) - val defaultList by bindView(R.id.default_list) - val defaultListContainer by bindView(R.id.default_list_container) - - private var mAdapter: GameAdapter? = null - - private var mSearchKey: String = "" - - override fun handleMessage(msg: Message) { - if (msg.what == 1) { - if (mSearchKey.isEmpty()) { - clearPage() - } else { - search() - } - } - } - - override fun getLayoutId(): Int { - return R.layout.activity_editor_insert_game - } - - override fun isAutomaticLoad(): Boolean { - return false - } - - override fun getItemDecoration(): RecyclerView.ItemDecoration { - return VerticalItemDecoration(this, 8f, false) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val title = intent?.getStringExtra(EntranceUtils.KEY_NAVIGATION_TITLE) ?: INSERT_GAME_TITLE - setNavigationTitle(title) - noneText.text = "搜索结果为空" - mListLoading.visibility = View.GONE - mListRefresh.isEnabled = false -// appBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> -// val totalScrollRange = appBarLayout.totalScrollRange -// if (totalScrollRange == -verticalOffset) { -// Util_System_Keyboard.hideSoftKeyboard(this) -// } -// }) - - searchEt.setOnEditorActionListener { _, actionId, _ -> - if (actionId == EditorInfo.IME_ACTION_SEARCH) { - search() - } - false - } - - searchTv.setOnClickListener { - search() - Util_System_Keyboard.hideSoftKeyboard(this) - } - searchBack.setOnClickListener { - searchEt.setText("") - } - - searchEt.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { - } - - override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - } - - override fun afterTextChanged(s: Editable) { - val newSearchKey = s.toString().trim() - if (newSearchKey != mSearchKey) { - mBaseHandler.removeMessages(1) - mSearchKey = newSearchKey - mBaseHandler.sendEmptyMessageDelayed(1, 500) - } - searchBack.visibility = if (newSearchKey.isNotEmpty()) View.VISIBLE - else View.GONE - } - }) - - mListRv.clearOnScrollListeners() - - // default open soft keyboard - searchEt.requestFocus() - Util_System_Keyboard.showSoftKeyboard(this, searchEt) - - if (title == SELECT_GAME_TITLE) initDefaultData() - } - - private fun clearPage() { - mAdapter?.setListData(ArrayList()) - mListLoading.visibility = View.GONE - mReuseNoData.visibility = View.GONE - mReuseNoConn.visibility = View.GONE - mListRv.visibility = View.GONE - } - - fun search() { - if (mSearchKey.isEmpty()) { - toast("请输入搜索关键字") - } else { - clearPage() - onLoadRefresh() - } - } - - override fun provideListAdapter(): GameAdapter? { - if (mAdapter == null) { - mAdapter = GameAdapter(this) - } - return mAdapter - } - - override fun provideDataObservable(page: Int): Observable>? { - return RetrofitManager - .getInstance(this).api - .getSearchGame(Config.SENSITIVE_API_HOST + "games:search?keyword=" + searchEt.text + "&view=digest" + "&channel=" + HaloApp.getInstance().channel + "&version" + BuildConfig.VERSION_NAME) - } - - override fun provideListViewModel(): NormalListViewModel { - val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this) - return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel - } - - private fun initDefaultData() { - RetrofitManager.getInstance(this).api - .getEditorInsertDefaultData(UserManager.getInstance().userId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response>() { - override fun onResponse(response: List?) { - if (response == null || response.isEmpty()) return - // init default page - defaultList.layoutManager = FixLinearLayoutManager(baseContext) - defaultList.adapter = GameDefaultAdapter(this@GameActivity, response) - defaultListContainer.visibility = View.VISIBLE - } - }) - } - - override fun onLoadRefresh() { - super.onLoadRefresh() - mListRv.visibility = View.VISIBLE - } - - override fun onLoadEmpty() { - super.onLoadEmpty() - mListRv.visibility = View.VISIBLE - } - - override fun onLoadDone() { - super.onLoadDone() - mListRv.visibility = View.VISIBLE + override fun provideNormalIntent(): Intent { + return getTargetIntent(this, GameActivity::class.java, GameFragment::class.java) } companion object { fun getIntent(context: Context, title: String): Intent { - val intent = Intent(context, GameActivity::class.java) - intent.putExtra(EntranceUtils.KEY_NAVIGATION_TITLE, title) - return intent + val bundle = bundleOf( + EntranceUtils.KEY_NAVIGATION_TITLE to title + ) + return getTargetIntent(context, GameActivity::class.java, GameFragment::class.java, bundle) } const val INSERT_GAME_TITLE = "插入游戏" diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt index 332bd4e242..735ed0b950 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt @@ -11,7 +11,7 @@ import com.gh.gamecenter.databinding.GameItemBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.game.GameItemViewHolder -class GameAdapter(context: Context) : ListAdapter(context) { +open class GameAdapter(context: Context) : ListAdapter(context) { public override fun setListData(updateData: MutableList?) { super.setListData(updateData) diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt new file mode 100644 index 0000000000..8fa0824cef --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt @@ -0,0 +1,190 @@ +package com.gh.gamecenter.qa.editor + +import android.os.Bundle +import android.os.Message +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import android.view.inputmethod.EditorInfo +import android.widget.EditText +import android.widget.TextView +import androidx.lifecycle.ViewModelProviders +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.constant.Config +import com.gh.common.util.EntranceUtils +import com.gh.common.view.FixLinearLayoutManager +import com.gh.common.view.VerticalItemDecoration +import com.gh.gamecenter.BuildConfig +import com.gh.gamecenter.R +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.baselist.NormalListViewModel +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.manager.UserManager +import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity +import com.gh.gamecenter.retrofit.Response +import com.gh.gamecenter.retrofit.RetrofitManager +import com.google.android.material.appbar.AppBarLayout +import com.halo.assistant.HaloApp +import com.lightgame.utils.Util_System_Keyboard +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import kotterknife.bindView + +open class GameFragment : ListFragment>() { + val searchEt by bindView(R.id.search_input) + val searchTv by bindView(R.id.search_button) + val searchBack by bindView(R.id.search_back) + val appBar by bindView(R.id.list_appbar) + val noneText by bindView(R.id.reuse_tv_none_data) + val defaultList by bindView(R.id.default_list) + val defaultListContainer by bindView(R.id.default_list_container) + + protected var mAdapter: GameAdapter? = null + + private var mSearchKey: String = "" + + override fun handleMessage(msg: Message) { + if (msg.what == 1) { + if (mSearchKey.isEmpty()) { + clearPage() + } else { + search() + } + } + } + + override fun getLayoutId(): Int { + return R.layout.activity_editor_insert_game + } + + override fun isAutomaticLoad(): Boolean { + return false + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration? { + return VerticalItemDecoration(requireContext(), 8f, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val title = arguments?.getString(EntranceUtils.KEY_NAVIGATION_TITLE) ?: "" + if (title.isNotEmpty()) { + setNavigationTitle(title) + } + noneText.text = "搜索结果为空" + mListLoading?.visibility = View.GONE + mListRefresh?.isEnabled = false + + searchEt.setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + search() + } + false + } + + searchTv.setOnClickListener { + search() + Util_System_Keyboard.hideSoftKeyboard(requireActivity()) + } + searchBack.setOnClickListener { + searchEt.setText("") + } + + searchEt.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + } + + override fun afterTextChanged(s: Editable) { + val newSearchKey = s.toString().trim() + if (newSearchKey != mSearchKey) { + mBaseHandler.removeMessages(1) + mSearchKey = newSearchKey + mBaseHandler.sendEmptyMessageDelayed(1, 500) + } + searchBack.visibility = if (newSearchKey.isNotEmpty()) View.VISIBLE else View.GONE + } + }) + + mListRv.clearOnScrollListeners() + + // default open soft keyboard + if (isAutoShowKeyboard()) { + searchEt.requestFocus() + } + Util_System_Keyboard.showSoftKeyboard(requireActivity(), searchEt) + + if (title == GameActivity.SELECT_GAME_TITLE) initDefaultData() + } + + private fun clearPage() { + mAdapter?.setListData(ArrayList()) + mListLoading?.visibility = View.GONE + mReuseNoData?.visibility = View.GONE + mReuseNoConn?.visibility = View.GONE + mListRv.visibility = View.GONE + } + + fun search() { + if (mSearchKey.isEmpty()) { + toast("请输入搜索关键字") + } else { + clearPage() + onLoadRefresh() + } + } + + override fun provideListAdapter(): GameAdapter? { + if (mAdapter == null) { + mAdapter = GameAdapter(requireContext()) + } + return mAdapter + } + + override fun provideDataObservable(page: Int): Observable>? { + return RetrofitManager + .getInstance(requireContext()).api + .getSearchGame(Config.SENSITIVE_API_HOST + "games:search?keyword=" + searchEt.text + "&view=digest" + "&channel=" + HaloApp.getInstance().channel + "&version" + BuildConfig.VERSION_NAME) + } + + override fun provideListViewModel(): NormalListViewModel { + val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this) + return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel + } + + private fun initDefaultData() { + RetrofitManager.getInstance(requireContext()).api + .getEditorInsertDefaultData(UserManager.getInstance().userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response>() { + override fun onResponse(response: List?) { + if (response == null || response.isEmpty()) return + // init default page + defaultList.layoutManager = FixLinearLayoutManager(requireContext()) + defaultList.adapter = GameDefaultAdapter(requireContext(), response) + defaultListContainer.visibility = View.VISIBLE + } + }) + } + + override fun onLoadRefresh() { + super.onLoadRefresh() + mListRv.visibility = View.VISIBLE + } + + override fun onLoadEmpty() { + super.onLoadEmpty() + mListRv.visibility = View.VISIBLE + } + + override fun onLoadDone() { + super.onLoadDone() + mListRv.visibility = View.VISIBLE + } + + open fun isAutoShowKeyboard(): Boolean = true +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png b/app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png new file mode 100644 index 0000000000000000000000000000000000000000..c0caeb6fb2c1748dc54b618f2a2f233c5f852e12 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdl8)jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-euz(rC1}QXr;NuTe=IrU>7*fIb z_KqQ6lY;le3Gj9A78m@mhaR zu*&YHGl>-ee$MAtPAy(JKUZ_YwRrzHm0h!ZwmcVjkQE}9p~5obTMMh*@74E>ZWU+n z`$%Wq68`sA;O8srH>U+5w!y7MX8e$5+-!I`I@c^M%V>3yS(;e5T8^0-^XHeFZqDdg zadQTb&jK4crN%WJNX|yq4>7u%dq(d}p?>@9U-xHd`YlN^Q(F{rYDTXnXKlva93Qqz pK&%!Z$3M{_tOe+8sQ$)smU-FBo15M9Z})?O)zj6_Wt~$(69A4IlMVm? literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png b/app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png new file mode 100644 index 0000000000000000000000000000000000000000..5b68501e04cfc980c210bc3f719cc3ae7712222d GIT binary patch literal 1491 zcmbtU`#aMM82`?eHqzN#%1BL|kwiGunuOdI8wp1`PD~7QNkgk>bDz6XJ*2TB%-zf_ zj@uch;*5@-+~cgYbT*egagglH51sP|ocDP?@8`XIp67kvU*2>#f}@gxh5`TpN;oGw zcNx3w04gu@IS5Iuj6f83M_Ztde_%nD*adpyg7A32Ko&y*P+AB8*^$VgAp-z_Ss(x` zW6(~GCHHUFjRpQM-VvJ2xwrzruG2U>8xJZ-{0JMYW}}))$uH7}ozp-x!i!XU3ECQ( zYIZzFWZX}X7m9I-c<%A_VE2nqg&T-F`snaDR^q~Ix>tsuMl)Qk$j|9G8ok|J<9{(I zmb4@i&G4EUre_Mxgj>Q63TZ8j$1%ku)8TMATWcs3q>X~e5(XYcG9^-}ZJ|V>;ALN5 zpUHT=8L}xkyzBk7_NnIPW+onw?|veA?ucxdO&aqjcI*jz+su+jSV54Yoqrlp8L3#j~1`F0HVc3 zs}!Ci5bUW63a^rWPu z>WYerG*DzN{xE&L?b)+uY&ZR_hLsDV@w)(z(19RN#53xQy{LZE9TJJ;>-gg{kV)oj zd6zs99L%fHJR5}T)hWBVSr#ee$${K=F;b*Z<@i(z-a1XX#+0J3){0AAH-oZz)GJ!q zfE^K|8w)F(?rlG;TdMa_vB+Ljn!U(c!e;dsoGR6wV(vz&t9xUxSS&qxZwl=1rAnZI z#R-p$94=g(UcO$>;Yd#Alo(vbHDj0whJ!%l4|@(O&+9y&XlZH5N9XErA0PXT8gSoG zJ-?A{6O!jvYDVwkgjExc0xkkeMq!LEsgx{K&w2VCQwbH(zrfw1$c>a4o)whjO~+c^ zw0sR>gbKYkS;ov`o6HBabTFiI)CpZ>sCo7er2_lN==7qN(cSUA#kmeI!SIWRbEuQ| zEcz|b@_Ct9$XmMigCI5S#MG*)s#x6(pNy`LDkf>sQS9`|$~!(Wu~Abhpy!-D=3+23 zt16_P2tFwylFD2+<>}S_aG8RQ8RBz?HBf^bHk-X4zRzovKS%QF8Lm|+dFiNnq1Qk5 zv$$WsC&Gc`T>IKZd`fdP_9%TFWA`A?=@XXkTc8!kAk6z24qOrC(bMnI>}9)`uA_AZ zO?6+Ocp3s$cAqL9jLpR3C z*S9Wh-@x?O4G}>Hw6uN?m}yg_G8MEl@$jMj%rECwb0W?|jVcp-DqqYV>_r{8b(#f zjYt$#>2f1?>GM|$6aE)3*YJCcGdexO6`G=pOkr>uu~Uo33RRrEC$M_cosDz$o0GDS o=vcNqRl6+s_O!lzu(^VsLjlefKe`$HIt0iJXHT%Jv-L~-2cl}K$N&HU literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/icon_add_games.webp b/app/src/main/res/drawable-xxxhdpi/icon_add_games.webp new file mode 100644 index 0000000000000000000000000000000000000000..fc412c8bbabb2c3440332bbbbe3d928bf6ed62de GIT binary patch literal 3594 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 + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_editor_insert_game.xml b/app/src/main/res/layout/activity_editor_insert_game.xml index 1ed9c790e8..2278b66dfa 100644 --- a/app/src/main/res/layout/activity_editor_insert_game.xml +++ b/app/src/main/res/layout/activity_editor_insert_game.xml @@ -5,8 +5,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - - @@ -32,7 +30,6 @@ @@ -104,6 +103,7 @@ android:textColor="@color/text_333333" /> @@ -154,6 +152,7 @@ android:textColor="@color/text_333333" /> diff --git a/app/src/main/res/layout/fragment_add_user_played_game.xml b/app/src/main/res/layout/fragment_add_user_played_game.xml new file mode 100644 index 0000000000..f53ddaef94 --- /dev/null +++ b/app/src/main/res/layout/fragment_add_user_played_game.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_choose_games.xml b/app/src/main/res/layout/fragment_choose_games.xml new file mode 100644 index 0000000000..a51dacfd0e --- /dev/null +++ b/app/src/main/res/layout/fragment_choose_games.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_search_game.xml b/app/src/main/res/layout/fragment_search_game.xml new file mode 100644 index 0000000000..462a6ea270 --- /dev/null +++ b/app/src/main/res/layout/fragment_search_game.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_choose_games.xml b/app/src/main/res/layout/item_choose_games.xml new file mode 100644 index 0000000000..3cd59056e4 --- /dev/null +++ b/app/src/main/res/layout/item_choose_games.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_menu_save.xml b/app/src/main/res/layout/layout_menu_save.xml new file mode 100644 index 0000000000..e49260fb44 --- /dev/null +++ b/app/src/main/res/layout/layout_menu_save.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/menu/menu_save.xml b/app/src/main/res/menu/menu_save.xml new file mode 100644 index 0000000000..5f934c0ac6 --- /dev/null +++ b/app/src/main/res/menu/menu_save.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file