【光环助手V5.5.0】创建/编辑游戏单(选择游戏/添加游戏UI) https://git.ghzs.com/pm/halo-app-issues/-/issues/1604

This commit is contained in:
jack
2021-11-06 15:55:06 +08:00
parent 623156bdb5
commit 001cbfcdb6
31 changed files with 1146 additions and 236 deletions

View File

@ -0,0 +1,26 @@
package com.gh.common.util
open class SingletonHolder<out T>(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
}
}
}
}

View File

@ -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)
}
}
}

View File

@ -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<Fragment>) {
fragments.add(AddSearchGameFragment().apply { bundleOf(EntranceUtils.KEY_NAVIGATION_TITLE to "添加游戏") })
fragments.add(AddUserPlayedGameFragment())
}
override fun initTabTitleList(tabTitleList: MutableList<String>) {
tabTitleList.add("搜索游戏")
tabTitleList.add("玩过游戏")
}
}

View File

@ -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)
}
}
}
}

View File

@ -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
}

View File

@ -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<GameEntity, PlayedGameViewModel>() {
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<GameEntity> {
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
}
}

View File

@ -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)
}
}
}

View File

@ -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<GameEntity>(context) {
public override fun setListData(updateData: MutableList<GameEntity>?) {
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<GameEntity>(binding.root)
interface ItemDragListener {
fun startDragItem(holder: RecyclerView.ViewHolder)
fun setToTop(holder: RecyclerView.ViewHolder)
fun deleteItem(entity: GameEntity)
}
}

View File

@ -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)
}
}

View File

@ -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<ArrayList<GameEntity>> = MutableLiveData()
companion object : SingletonHolder<ChooseGamesRepository>(::ChooseGamesRepository)
}

View File

@ -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 <T : ViewModel?> create(modelClass: Class<T>): T {
return ChooseGamesViewModel(
HaloApp.getInstance().application,
ChooseGamesRepository.getInstance()
) as T
}
}
}

View File

@ -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 {

View File

@ -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 = ""
}

View File

@ -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<GameEntity, GameEntity>(application) {
class PlayedGameViewModel(application: Application, var userId: String, val isKeepTagStyle: Boolean = false) :
ListViewModel<GameEntity, GameEntity>(application) {
override fun provideDataObservable(page: Int): Observable<MutableList<GameEntity>>? {
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<ResponseBody>() {
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<ResponseBody>() {
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 <T : ViewModel> create(modelClass: Class<T>): T {
return PlayedGameViewModel(HaloApp.getInstance().application, mUserId) as T
return PlayedGameViewModel(HaloApp.getInstance().application, mUserId, isKeepTagStyle) as T
}
}

View File

@ -26,7 +26,7 @@ import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class UserPlayedGameFragment: ListFragment<GameEntity, PlayedGameViewModel>() {
open class UserPlayedGameFragment: ListFragment<GameEntity, PlayedGameViewModel>() {
private var mUserId = ""
private var mAdapter: UserPlayedGameAdapter? = null

View File

@ -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<GameEntity, NormalListViewModel<GameEntity>>() {
class GameActivity : NormalActivity() {
val searchEt by bindView<EditText>(R.id.search_input)
val searchTv by bindView<TextView>(R.id.search_button)
val searchBack by bindView<View>(R.id.search_back)
val appBar by bindView<AppBarLayout>(R.id.list_appbar)
val noneText by bindView<TextView>(R.id.reuse_tv_none_data)
val defaultList by bindView<RecyclerView>(R.id.default_list)
val defaultListContainer by bindView<View>(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<MutableList<GameEntity>>? {
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<GameEntity> {
val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this)
return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel<GameEntity>
}
private fun initDefaultData() {
RetrofitManager.getInstance(this).api
.getEditorInsertDefaultData(UserManager.getInstance().userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<EditorInsertDefaultEntity>>() {
override fun onResponse(response: List<EditorInsertDefaultEntity>?) {
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 = "插入游戏"

View File

@ -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<GameEntity>(context) {
open class GameAdapter(context: Context) : ListAdapter<GameEntity>(context) {
public override fun setListData(updateData: MutableList<GameEntity>?) {
super.setListData(updateData)

View File

@ -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<GameEntity, NormalListViewModel<GameEntity>>() {
val searchEt by bindView<EditText>(R.id.search_input)
val searchTv by bindView<TextView>(R.id.search_button)
val searchBack by bindView<View>(R.id.search_back)
val appBar by bindView<AppBarLayout>(R.id.list_appbar)
val noneText by bindView<TextView>(R.id.reuse_tv_none_data)
val defaultList by bindView<RecyclerView>(R.id.default_list)
val defaultListContainer by bindView<View>(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<MutableList<GameEntity>>? {
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<GameEntity> {
val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this)
return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel<GameEntity>
}
private fun initDefaultData() {
RetrofitManager.getInstance(requireContext()).api
.getEditorInsertDefaultData(UserManager.getInstance().userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<EditorInsertDefaultEntity>>() {
override fun onResponse(response: List<EditorInsertDefaultEntity>?) {
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
}