gpt4 book ai didi

android - 当列表按降序排序时,DiffUtil 正在改变我的位置

转载 作者:行者123 更新时间:2023-12-05 00:02:18 28 4
gpt4 key购买 nike

我正在使用 diff util 来提高我的 recyclerview 的性能,而不是调用 notifyDataSetChanged()。 recyclerview 有一个带有一些芯片的标题,可以通过 aplhabetical 顺序重新排序列表,最高分数等
当我单击标题中的筹码时,列表会对其重新排序,从而影响我的位置。例如,如果我按最高分数排序并且分数 100% 是位置 1(在标题之后),我单击芯片以反向重新排序。分数 100% 现在将位于列表的底部,而 0% 将位于顶部。但现在我必须一直滚动到顶部才能再次看到标题芯片。我希望列表重新排序,但我不希望我在屏幕上的位置改变。
enter image description here
这是我的适配器代码:

class DigitalTestsResultsAdapter(
private val interaction: Interaction? = null,
private val dateUtil: DateUtil,
private val theme: ThemeModel?,
private val username: String?
) : ListAdapter<ResultResponseModel, RecyclerView.ViewHolder>(ResultsDiffCallBack()) {

private val itemViewTypeHeader: Int = 0
private val itemViewTypeItem: Int = 1
private var filteredList = emptyList<ResultResponseModel>()
private val adapterScope = CoroutineScope(Dispatchers.Default)

class ResultsDiffCallBack : DiffUtil.ItemCallback<ResultResponseModel>() {
override fun areItemsTheSame(
oldItem: ResultResponseModel,
newItem: ResultResponseModel
): Boolean {
return oldItem.certificateUrl == newItem.certificateUrl
}

@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(
oldItem: ResultResponseModel,
newItem: ResultResponseModel
): Boolean {
return oldItem == newItem
}
}

fun filterList(list: List<ResultResponseModel>, type: String) {
adapterScope.launch {
when (type) {

"courseName" -> {
filteredList = list.sortedBy { it.courseName }
}

"isCpd" -> {
filteredList = list.sortedBy { it.courseName }.sortedByDescending { it.isCPD }
}

"organisationName" -> {
filteredList = list.sortedBy { it.organisationName }
}

"roleName" -> {
filteredList = list.sortedBy { it.roleName }
}

"score" -> {
filteredList = list.sortedByDescending { it.score }
}

"submitTime" -> {
filteredList = list.sortedByDescending { it.submitTime }
}
}
withContext(Dispatchers.Main) {
submitList(filteredList)
}
}
}


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {

itemViewTypeHeader -> {
DigitalTestsResultsHeaderViewHolder(
RvDigitalTestResultsHeaderBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}

itemViewTypeItem -> {
DigitalTestsResultsViewHolder(
RvDigitalTestsResultsBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
),
interaction = interaction
)
}

else -> throw ClassCastException("Unknown viewType $viewType")

}
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {

is DigitalTestsResultsHeaderViewHolder -> {
holder.bind()
}

is DigitalTestsResultsViewHolder -> {
holder.bind(currentList[position])
}

}
}

override fun getItemViewType(position: Int): Int {
return if (position == 0) {
itemViewTypeHeader
} else {
itemViewTypeItem
}
}

override fun getItemCount(): Int {
return if (!currentList.isNullOrEmpty()) {
currentList.size
} else 0
}

inner class DigitalTestsResultsHeaderViewHolder
constructor(
private val binding: RvDigitalTestResultsHeaderBinding
) : RecyclerView.ViewHolder(binding.root) {

fun bind() {
with(binding) {
with(theme) {

userName.text = itemView.context.getString(R.string.hi_username, username)
userName.setTextColourHex(this?.textModel?.primaryColor)
chipCv.setCardBackgroundColourHex(this?.interfaceModel?.secondaryColor)

testsChipGroup.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {

R.id.chipCertified -> {
chipCertified.isChecked = true
filterList(currentList, "isCpd")
}

R.id.chipCourse -> {
chipCourse.isChecked = true
filterList(currentList, "courseName")
}

R.id.chipHighestScore -> {
chipHighestScore.isChecked = true
filterList(currentList, "score")
}

R.id.chipRecent -> {
chipRecent.isChecked = true
filterList(currentList, "submitTime")
}

R.id.chipRole -> {
chipRole.isChecked = true
filterList(currentList, "roleName")
}

R.id.chipSchoolName -> {
chipSchoolName.isChecked = true
filterList(currentList, "organisationName")
}
else -> {

}
}
}
}
}
}
}

inner class DigitalTestsResultsViewHolder
constructor(
private val binding: RvDigitalTestsResultsBinding,
private val interaction: Interaction?
) : RecyclerView.ViewHolder(binding.root) {

@SuppressLint("SetTextI18n")
fun bind(item: ResultResponseModel?) {
with(binding) {
with(theme) {

viewCertificateBtn.setOnClickListener {
interaction?.onItemSelected("certificateBtn", absoluteAdapterPosition, item)
}

retakeTestBtn.setOnClickListener {
interaction?.onItemSelected("retakeTestBtn", absoluteAdapterPosition, item)
}

resultsProgressBar.progress = item?.score?.toFloat() ?: 0f

if (isValidHex(item?.roleColour)) {
resultsProgressBar.circleProgressColor = Color.parseColor(item?.roleColour)
resultsProgressBar.pointerColor = Color.parseColor(item?.roleColour)
}

score.text = item?.score.toString() + "%"
title.text = item?.courseName
date.text = dateUtil.formatStringDateToDDMMYYYY(item?.submitTime)
role.text = item?.roleName
schoolName.text = item?.organisationName

title.setTextColourHex(this?.textModel?.primaryColor)
retakeTestBtn.setTextColourHex(this?.textModel?.primaryColor)
mainCv.setCardBackgroundColourHex(this?.interfaceModel?.secondaryColor)
roleCv.setCardBackgroundColourHex(item?.roleColour)

// Check if course is CPD and display CPD icon
if (item?.isCPD == true) cpdLogo.visibility =
View.VISIBLE else cpdLogo.visibility = View.INVISIBLE
}
}
}
}

interface Interaction {
fun onItemSelected(
tag: String,
position: Int,
result: ResultResponseModel?
)
}
}

最佳答案

使用 registerAdapterDataObserver 注册适配器以观察以在数据更改时通知您adapter.registerAdapterDataObserver()当数据更改时,将 recyclerView 滚动到第一项位置
使用 recyclerview.scrollToPosition(position)也可以看看:
Recycler view scroll to specific position
Diffutil in recycleview, making it autoscroll if a new item is added

关于android - 当列表按降序排序时,DiffUtil 正在改变我的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70379617/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com