Skip to content

Commit

Permalink
[Feat]: 媒体详情页优化
Browse files Browse the repository at this point in the history
  • Loading branch information
why committed Dec 9, 2023
1 parent f459422 commit 2b1f7aa
Show file tree
Hide file tree
Showing 37 changed files with 484 additions and 902 deletions.
3 changes: 3 additions & 0 deletions app/src/main/java/com/xiaoyv/bangumi/helper/RouteHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ object RouteHelper {

fun jumpIndexDetail(id: String) {

}
fun jumpTagDetail(tag: String) {

}

fun jumpGroupDetail(groupId: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class PersonOverviewAdapter(
const val TYPE_VOICE = 6
const val TYPE_CHARACTER = 7
const val TYPE_OPUS = 8
const val TYPE_COMMENT = 9
}

data class Item(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package com.xiaoyv.bangumi.ui.media.detail.overview

import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseMultiItemAdapter
import com.chad.library.adapter.base.BaseMultiItemAdapter.OnItemViewTypeListener
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewBoardBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewCharacterBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewCommentBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewDetailBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewEpBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewIndexBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewMakerBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewGridBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewPreviewBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewRatingBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewRelativeBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewReviewBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewSaveBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewSummaryBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewTagBinder
import com.xiaoyv.common.api.parser.entity.MediaCommentEntity
import com.xiaoyv.common.api.parser.entity.MediaDetailEntity
import com.xiaoyv.common.config.bean.SampleAvatar
import com.xiaoyv.common.helper.callback.RecyclerItemTouchedListener

/**
Expand All @@ -25,24 +24,43 @@ import com.xiaoyv.common.helper.callback.RecyclerItemTouchedListener
* @author why
* @since 11/30/23
*/
class OverviewAdapter(touchedListener: RecyclerItemTouchedListener) :
BaseMultiItemAdapter<OverviewAdapter.OverviewItem>() {
class OverviewAdapter(
touchedListener: RecyclerItemTouchedListener,
onClickSave: (Item, Int) -> Unit,
onClickEpItem: (MediaDetailEntity.MediaProgress) -> Unit,
onClickCrtItem: (MediaDetailEntity.MediaCharacter) -> Unit,
onClickTagItem: (MediaDetailEntity.MediaTag) -> Unit,
onClickRelatedItem: (MediaDetailEntity.MediaRelative) -> Unit,
onClickCollectorItem: (SampleAvatar) -> Unit,
onClickIndexItem: (SampleAvatar) -> Unit,
onClickCommentItem: (MediaCommentEntity) -> Unit,
onClickCommentUser: (MediaCommentEntity) -> Unit,
) : BaseMultiItemAdapter<OverviewAdapter.Item>() {

init {
this.addItemType(TYPE_SAVE, OverviewSaveBinder {})
.addItemType(TYPE_EP, OverviewEpBinder(touchedListener) {})
.addItemType(TYPE_TAG, OverviewTagBinder {})
.addItemType(TYPE_SUMMARY, OverviewSummaryBinder())
val gridPool = RecyclerView.RecycledViewPool()

this.addItemType(TYPE_SAVE, OverviewSaveBinder(onClickSave))
.addItemType(TYPE_EP, OverviewEpBinder(touchedListener, onClickEpItem))
.addItemType(TYPE_TAG, OverviewTagBinder(onClickTagItem))
.addItemType(TYPE_SUMMARY, OverviewSummaryBinder(true))
.addItemType(TYPE_PREVIEW, OverviewPreviewBinder())
.addItemType(TYPE_DETAIL, OverviewDetailBinder())
.addItemType(TYPE_DETAIL, OverviewSummaryBinder(false))
.addItemType(TYPE_RATING, OverviewRatingBinder())
.addItemType(TYPE_CHARACTER, OverviewCharacterBinder(touchedListener) {})
.addItemType(TYPE_MAKER, OverviewMakerBinder {})
.addItemType(TYPE_RELATIVE, OverviewRelativeBinder(touchedListener) {})
.addItemType(TYPE_INDEX, OverviewIndexBinder(touchedListener) {})
.addItemType(TYPE_REVIEW, OverviewReviewBinder(touchedListener,{}) {})
.addItemType(TYPE_BOARD, OverviewBoardBinder(touchedListener) {})
.addItemType(TYPE_COMMENT, OverviewCommentBinder(touchedListener,{}) {})
.addItemType(TYPE_CHARACTER, OverviewCharacterBinder(touchedListener, onClickCrtItem))
.addItemType(TYPE_RELATIVE, OverviewRelativeBinder(touchedListener, onClickRelatedItem))
.addItemType(
TYPE_COLLECTOR,
OverviewGridBinder(gridPool, touchedListener, onClickCollectorItem)
)
.addItemType(
TYPE_INDEX,
OverviewGridBinder(gridPool, touchedListener, onClickIndexItem)
)
.addItemType(
TYPE_COMMENT,
OverviewCommentBinder(touchedListener, onClickCommentItem, onClickCommentUser)
)
.onItemViewType(OnItemViewTypeListener { position, list ->
return@OnItemViewTypeListener list[position].type
})
Expand All @@ -57,16 +75,14 @@ class OverviewAdapter(touchedListener: RecyclerItemTouchedListener) :
const val TYPE_DETAIL = 6
const val TYPE_RATING = 7
const val TYPE_CHARACTER = 8
const val TYPE_MAKER = 9
const val TYPE_RELATIVE = 10
const val TYPE_RELATIVE = 9
const val TYPE_COLLECTOR = 10
const val TYPE_INDEX = 11
const val TYPE_REVIEW = 12
const val TYPE_BOARD = 13
const val TYPE_COMMENT = 14
const val TYPE_COMMENT = 12
}

data class OverviewItem(
var mediaDetailEntity: MediaDetailEntity,
data class Item(
var entity: Any,
var type: Int,
var title: String
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,22 @@
@file:Suppress("UNCHECKED_CAST")

package com.xiaoyv.bangumi.ui.media.detail.overview

import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.LifecycleOwner
import com.chad.library.adapter.base.BaseMultiItemAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import com.xiaoyv.bangumi.databinding.FragmentOverviewBinding
import com.xiaoyv.bangumi.databinding.FragmentOverviewSaveBinding
import com.xiaoyv.bangumi.helper.RouteHelper
import com.xiaoyv.bangumi.ui.media.action.MediaSaveActionDialog
import com.xiaoyv.bangumi.ui.media.detail.MediaDetailViewModel
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewBoardBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewCharacterBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewCommentBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewDetailBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewEpBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewIndexBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewPreviewBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewRatingBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewRelativeBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewReviewBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewSaveBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewSummaryBinder
import com.xiaoyv.bangumi.ui.media.detail.overview.binder.OverviewTagBinder
import com.xiaoyv.blueprint.base.mvvm.normal.BaseViewModelFragment
import com.xiaoyv.blueprint.constant.NavKey
import com.xiaoyv.common.api.parser.entity.MediaDetailEntity
import com.xiaoyv.common.config.annotation.TopicType
import com.xiaoyv.common.helper.callback.RecyclerItemTouchedListener
import com.xiaoyv.common.helper.UserHelper
import com.xiaoyv.widget.binder.BaseQuickBindingHolder
import com.xiaoyv.widget.kts.useNotNull
import com.xiaoyv.common.helper.callback.RecyclerItemTouchedListener
import com.xiaoyv.common.kts.forceCast
import com.xiaoyv.common.widget.scroll.AnimeLinearLayoutManager

/**
* Class: [OverviewFragment]
Expand All @@ -42,69 +26,41 @@ import com.xiaoyv.widget.kts.useNotNull
*/
class OverviewFragment : BaseViewModelFragment<FragmentOverviewBinding, OverviewViewModel>() {

private val mediaViewModel by activityViewModels<MediaDetailViewModel>()
private val activityViewModel by activityViewModels<MediaDetailViewModel>()

private val touchedListener = RecyclerItemTouchedListener {
mediaViewModel.vpEnableLiveData.value = it
activityViewModel.vpEnableLiveData.value = it
}

private var viewHolders: HashMap<Int, BaseQuickBindingHolder<*>> = hashMapOf()

/**
* RecyclerView 多 Type 效果不太好,这里改写直接进入全部渲染
*/
private val viewBinderTypes: HashMap<Int, BaseMultiItemAdapter.OnMultiItemAdapterListener<OverviewAdapter.OverviewItem, *>> by lazy {
hashMapOf<Int, BaseMultiItemAdapter.OnMultiItemAdapterListener<OverviewAdapter.OverviewItem, *>>().apply {
put(OverviewAdapter.TYPE_SAVE, OverviewSaveBinder {
if (UserHelper.isLogin) {
MediaSaveActionDialog.show(
childFragmentManager,
viewModel.mediaDetailLiveData.value?.collectState
) {
viewModel.refreshCollectState(it)
refreshCollectStateView()
}
} else {
RouteHelper.jumpLogin()
}
})
put(OverviewAdapter.TYPE_EP, OverviewEpBinder(touchedListener) {
private val overviewAdapter by lazy {
OverviewAdapter(
touchedListener = touchedListener,
onClickSave = { item, position ->
showCollectPanel(item, position)
},
onClickEpItem = {
RouteHelper.jumpTopicDetail(it.id, TopicType.TYPE_EP)
})
put(OverviewAdapter.TYPE_TAG, OverviewTagBinder {})
put(OverviewAdapter.TYPE_SUMMARY, OverviewSummaryBinder())
put(OverviewAdapter.TYPE_PREVIEW, OverviewPreviewBinder())
put(OverviewAdapter.TYPE_DETAIL, OverviewDetailBinder())
put(OverviewAdapter.TYPE_RATING, OverviewRatingBinder())
put(OverviewAdapter.TYPE_CHARACTER, OverviewCharacterBinder(touchedListener) {
},
onClickCrtItem = {
RouteHelper.jumpPerson(it.id, true)
})
// put(OverviewAdapter.TYPE_MAKER, OverviewMakerBinder {
// RouteHelper.jumpPerson(it.id)
// })
put(OverviewAdapter.TYPE_RELATIVE, OverviewRelativeBinder(touchedListener) {
},
onClickTagItem = {
RouteHelper.jumpTagDetail(it.tagName)
},
onClickRelatedItem = {
RouteHelper.jumpMediaDetail(it.id)
})
put(OverviewAdapter.TYPE_INDEX, OverviewIndexBinder(touchedListener) {})
put(OverviewAdapter.TYPE_REVIEW, OverviewReviewBinder(touchedListener, {
RouteHelper.jumpBlogDetail(it.id)
}, {
},
onClickCollectorItem = {
RouteHelper.jumpUserDetail(it.id)
},
onClickIndexItem = {
RouteHelper.jumpIndexDetail(it.id)
},
onClickCommentItem = {},
onClickCommentUser = {
RouteHelper.jumpUserDetail(it.userId)
}))
put(OverviewAdapter.TYPE_BOARD, OverviewBoardBinder(touchedListener) {})
put(OverviewAdapter.TYPE_COMMENT, OverviewCommentBinder(touchedListener, {

}, {
RouteHelper.jumpUserDetail(it.userId)
}))
}
}


private val overviewAdapter by lazy {
OverviewAdapter(RecyclerItemTouchedListener {
mediaViewModel.vpEnableLiveData.value = it
})
}
)
}

override fun initArgumentsData(arguments: Bundle) {
Expand All @@ -113,52 +69,36 @@ class OverviewFragment : BaseViewModelFragment<FragmentOverviewBinding, Overview

override fun initView() {


}

override fun initData() {
viewModel.queryMediaInfo()
binding.rvRecycler.layoutManager =
AnimeLinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false).apply {
extraLayoutSpaceScale = 6f
}
binding.rvRecycler.adapter = overviewAdapter
binding.rvRecycler.itemAnimator = null

// 手动创建
viewHolders.clear()
binding.llContainer.removeAllViews()
viewBinderTypes.forEach { (key, listener) ->
val holder = listener.onCreate(hostActivity, binding.llContainer, key)
binding.llContainer.addView(holder.itemView)
viewHolders[key] = holder as BaseQuickBindingHolder<*>
}
viewModel.queryMediaInfo()
}

override fun LifecycleOwner.initViewObserver() {
binding.stateView.initObserver(
lifecycleOwner = this,
loadingBias = 0.2f,
loadingViewState = viewModel.loadingViewState,
doOnShowContent = {
binding.llContainer.isVisible = true
}
canShowContent = { false }
)

viewModel.mediaDetailLiveData.observe(this) {
mediaViewModel.onMediaDetailLiveData.value = it

if (it == null) {
binding.stateView.showTip()
}
activityViewModel.onMediaDetailLiveData.value = it
}

viewModel.mediaBinderListLiveData.observe(this) {
// 手动填充数据
it.forEachIndexed { index, overviewItem ->
val adapterListener =
viewBinderTypes[overviewItem.type] as? BaseMultiItemAdapter.OnMultiItemAdapterListener<OverviewAdapter.OverviewItem, BaseQuickBindingHolder<*>>
val bindingHolder = viewHolders[overviewItem.type]
if (bindingHolder != null && adapterListener != null) {
adapterListener.onBind(bindingHolder, index, overviewItem)
}
}
}
overviewAdapter.submitList(it)

binding.stateView.showContent()
}

UserHelper.observe(this) {
viewModel.queryMediaInfo()
Expand All @@ -169,18 +109,17 @@ class OverviewFragment : BaseViewModelFragment<FragmentOverviewBinding, Overview

}

/**
* 手动刷新收藏条目
*/
private fun refreshCollectStateView() {
val position = viewBinderTypes.keys.indexOf(OverviewAdapter.TYPE_SAVE)
val adapterListener = viewBinderTypes[OverviewAdapter.TYPE_SAVE] as OverviewSaveBinder
val bindingHolder =
viewHolders[OverviewAdapter.TYPE_SAVE] as BaseQuickBindingHolder<FragmentOverviewSaveBinding>
useNotNull(viewModel.mediaDetailLiveData.value) {
val newItem = OverviewAdapter.OverviewItem(this, OverviewAdapter.TYPE_SAVE, "收藏")

adapterListener.onBind(bindingHolder, position, newItem)

private fun showCollectPanel(item: OverviewAdapter.Item, position: Int) {
if (!UserHelper.isLogin) {
RouteHelper.jumpLogin()
return
}
val forceCast = item.entity.forceCast<MediaDetailEntity>()
MediaSaveActionDialog.show(childFragmentManager, forceCast.collectState) {
val entity = viewModel.refreshCollectState(it) ?: return@show
item.entity = entity
overviewAdapter[position] = item
}
}

Expand Down
Loading

0 comments on commit 2b1f7aa

Please sign in to comment.