新版本显示不全,旧版本没这个问题
smallgirl opened this issue · 6 comments
smallgirl commented
Xigong93 commented
方便提供一下adapter的伪代码吗?
smallgirl commented
adapter 的每个item 高度不一样,是不是这个导致的?
//最终小节的父节点,可以有视频
private class ParentFinalVH(val itemBinding: ItemSegmentChildBinding) :
RecyclerView.ViewHolder(itemBinding.root)
//普通父节点,可折叠
private class ParentNotFinalVH(val itemBinding: ItemSegmentParentBinding) :
RecyclerView.ViewHolder(itemBinding.root)
//最终小节子节点,没有下一级,可能没有视频
private class ChildFinalVH(val itemBinding: ItemSegmentChildBinding) :
RecyclerView.ViewHolder(itemBinding.root)
//非最终小节子节点,没有视频,有下一级
private class ChildNotFinalVH(val itemBinding: ItemSegmentMiddleBinding) :
RecyclerView.ViewHolder(itemBinding.root)
class SegmentAdapter(
var onItemClick: (
lesson: Lesson, itemShowDownload: Boolean, groupPosition: Int,
childPosition: Int
) -> Unit
) : ExpandableAdapter<RecyclerView.ViewHolder>() {
companion object {
private const val PARENT_FINAL_NODE = 11//父节点最终小节
private const val PARENT_NOT_FINAL_NODE = 12//父节点不是最终小节
private const val CHILD_FINAL_NODE = -11
private const val CHILD_NOT_FINAL_NODE = -12
}
//数据结构为两层树结构,第二层一下都会扁平按顺序放在第一层的children中
/**
* parent1
* |- child1.1
* |- child1.1.1
* |- child1.1.2
* parent2
* |- child2.1
* |- child2.2
* |- child2.2.1
* ...
*/
var list: MutableList<SegmentWrappedLesson> = mutableListOf()
var itemShowDownload: Boolean = false//是否下载标记
fun setSegments(list: List<SegmentWrappedLesson>) {
this.list.clear()
this.list.addAll(list)
setDataInternal()
notifyDataSetChanged()
}
override fun getGroupItemViewType(groupPosition: Int) =
if (list[groupPosition].lesson.type == 1)//判断是否是最终小节
PARENT_FINAL_NODE
else
PARENT_NOT_FINAL_NODE
override fun getChildItemViewType(groupPosition: Int, childPosition: Int) =
if (list[groupPosition].children?.get(childPosition)?.type ?: 0 == 1)
CHILD_FINAL_NODE
else
CHILD_NOT_FINAL_NODE
//父目录vh
override fun onCreateGroupViewHolder(
viewGroup: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(viewGroup.context)
return if (viewType == PARENT_NOT_FINAL_NODE)
ParentNotFinalVH(
ItemSegmentParentBinding.inflate(inflater, viewGroup, false)
)
else
ParentFinalVH(ItemSegmentChildBinding.inflate(inflater, viewGroup, false))
}
//子目录vh
override fun onCreateChildViewHolder(
viewGroup: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(viewGroup.context)
return if (viewType == CHILD_NOT_FINAL_NODE)
ChildNotFinalVH(
ItemSegmentMiddleBinding.inflate(inflater, viewGroup, false)
)
else
ChildFinalVH(ItemSegmentChildBinding.inflate(inflater, viewGroup, false))
}
override fun onBindChildViewHolder(
holder: RecyclerView.ViewHolder,
groupPosition: Int,
childPosition: Int,
payloads: List<Any>
) {
val lesson = list[groupPosition].children?.get(childPosition)
lesson?.let {
(holder as? ChildNotFinalVH)?.apply {//非最终小节,只展示标题
setIndentation(itemBinding.lessonName, lesson.treeLevel)//子节点设置层级缩进
itemBinding.lessonName.text = lesson.lessonName
}
(holder as? ChildFinalVH)?.apply {//最终小节,可能有视频,可能没视频
setIndentation(itemBinding.lessonName, lesson.treeLevel)//子节点设置层级缩进
setSegmentInfo(holder.itemBinding, lesson, groupPosition, childPosition)
}
}
}
override fun onBindGroupViewHolder(
holder: RecyclerView.ViewHolder,
groupPosition: Int,
expand: Boolean,
payloads: List<Any>
) {
val lesson = list[groupPosition].lesson
(holder as? ParentNotFinalVH)?.apply {//普通父节点
itemBinding.lessonName.text = lesson.lessonName
if (payloads.isEmpty()) {
itemBinding.lessonExpandIv.rotation =
if (isExpand(groupPosition)) 0f
else 180f
}
}
(holder as? ParentFinalVH)?.apply {//最终父节点,可能有视频,
setSegmentInfo(holder.itemBinding, lesson, groupPosition, -1)
}
}
//最终小节,可能是父节点,可能是子节点,设置lesson信息
@SuppressLint("SetTextI18n")
private fun setSegmentInfo(
binding: ItemSegmentChildBinding,
lesson: Lesson,
groupPosition: Int,
childPosition: Int,
) {
binding.lesson = lesson
//有视频
if (lesson.isHasVideo) {
//播放,下载状态
binding.lessonPlayIv.visibility = View.VISIBLE
binding.lessonProgressBar.progress = lesson.rate.toInt()
binding.lessonProgress.text = "${
TimeUtils.getPlayTimeHour(lesson.playTime.toLong(), false, true)
},已学${lesson.rate.toInt()}%"
if (itemShowDownload) {
setDownloadState(lesson.downloadState, binding.lessonPlayIv)
} else {
binding.lessonPlayIv.setImageResource(R.drawable.ic_catalog_play)
}
//最近学习标记
binding.studyHere.visibility =
if (lesson.lastListen == 1 && !itemShowDownload) View.VISIBLE else View.GONE
//又是视频的才可以点击下载和播放
binding.itemSegmentLayout.setOnClickListener {
onItemClick(
lesson,
itemShowDownload,
groupPosition,
childPosition
)
}
} else {//没有视频
//隐藏播放,下载状态
binding.lessonPlayIv.visibility = View.GONE
//最近学习标记
binding.studyHere.visibility = View.GONE
binding.itemSegmentLayout.setOnClickListener(null)
}
binding.executePendingBindings()
}
//设置下载状态
private fun setDownloadState(state: Int, downImg: AppCompatImageView) {
when (state) {
DownloadConst.DownloadState.TASK_STATE_WAITING -> {
downImg.setImageResource(R.drawable.ic_download_waiting)
}
DownloadConst.DownloadState.TASK_STATE_DOWNLOADING -> {
downImg.setImageResource(R.drawable.ic_download_ing)
}
DownloadConst.DownloadState.TASK_STATE_PAUSE -> {
downImg.setImageResource(R.drawable.ic_download_pause)
}
DownloadConst.DownloadState.TASK_STATE_FAIL -> {
downImg.setImageResource(R.drawable.ic_download_fail)
}
DownloadConst.DownloadState.TASK_STATE_COMPLETE -> {
downImg.setImageResource(R.drawable.ic_download_success)
}
else -> {
downImg.setImageResource(R.drawable.ic_download_none)
}
}
}
//父布局必须ConstraintLayout的textview
// <!--根据不同的层级标题缩进-->
// <!--根据UI图:第x章不缩进,x.x不缩进,x.x.x直到最终节都缩进-->
private fun setIndentation(lessonNameTv: TextView, indentation: Int) {
//设置层级缩进
with(lessonNameTv.layoutParams as ConstraintLayout.LayoutParams) {
this.marginStart = PixelUtils.dp2px(
lessonNameTv.context,
if (indentation > 1) (indentation - 1) * 14f else 0f
)
lessonNameTv.layoutParams = this
}
}
override fun onGroupViewHolderExpandChange(
holder: RecyclerView.ViewHolder,
groupPosition: Int,
animDuration: Long,
expand: Boolean
) {
val arrowImage = when {
holder as? ParentNotFinalVH != null -> holder.itemBinding.lessonExpandIv
else -> return
}
setArrowSpin(arrowImage, expand, animDuration, true)
}
//设置目录折叠的三角方向
private fun setArrowSpin(
view: View?,
isExpand: Boolean,
animDuration: Long,
isAnimate: Boolean
) {
view ?: return
if (isExpand) {
if (isAnimate) {
ObjectAnimator.ofFloat(view, View.ROTATION, 0f)
.setDuration(animDuration)
.start()
} else {
view.rotation = 0f
}
// 不要使用这种动画,Item离屏之后,动画会取消
// arrowImage.animate()
// .setDuration(animDuration)
// .rotation(0f)
// .start()
} else {
if (isAnimate) {
ObjectAnimator.ofFloat(view, View.ROTATION, 180f)
.setDuration(animDuration)
.start()
} else {
view.rotation = 180f
}
}
}
override fun getGroupCount(): Int {
return list.size
}
override fun getChildCount(groupPosition: Int): Int {
return list[groupPosition].children?.size ?: 0
}
}
smallgirl commented
上面是旧版本的adapter显示正常,新版的是只是把RecyclerView.ViewHolder 换成ExpandableAdapter.ViewHolder 就显示不全,有大片空白,还有文字显示一半的情况。
Xigong93 commented
谢谢,我已经复现了,马上改一下
Xigong93 commented
你好,刚刚发了一下0.8.6
已经修复了这个问题,请再试一下。
smallgirl commented
可以了 谢谢。