android - 如何在 RecyclerView 中突出显示并自动单击最近添加的项目
问题描述
我有两个场景,所以第一个是我想突出显示并自动执行单击 RecyclerView 中最近添加的项目,第二个是如果用户选择或单击任何项目,该时间也应该突出显示和点击所以第二个场景我已经实现了,但我不知道如何突出显示并自动执行单击列表中最后添加的项目。
我的适配器类
class CarItemAdapter(
private val activity: MainActivity,
private val carList: ArrayList<MyEntity>,
private val myViewModel: MyViewModel,
private val settings: Settings
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var listener: OnItemsClickListener? = null
var rowIndex = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return when (viewType) {
VIEW_TYPE_ADDITEM -> ViewHolderAddCarItem(SettingsCarAddItemTileBinding.inflate(layoutInflater, parent, false))
VIEW_TYPE_ITEM -> ViewHolderCarItem(SettingsCarItemTileBinding.inflate(layoutInflater, parent, false))
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolderCarItem -> holder.bind(carList[position -1], position-1)
is ViewHolderAddCarItem -> holder.bind()
}
}
inner class ViewHolderAddCarItem internal constructor(private var binding: SettingsCarAddItemTileBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind() {
binding.lifecycleOwner = activity
binding.handler = EventHandler()
binding.userSpecificCarSubtitle.setText(R.string.user_specific_car_subtitle)
}
inner class EventHandler {
fun onItemClicked() {
activity.showSubPage(AddVehiclePage(activity), true)
}
}
}
inner class ViewHolderCarItem internal constructor(private var binding: SettingsCarItemTileBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(myEntity: MyEntity, position: Int) {
binding.lifecycleOwner = activity
val bmp = BitmapFactory.decodeByteArray(myEntity.image, 0, Objects.requireNonNull<ByteArray>(myEntity.image).size)
binding.carImage.setImageBitmap(bmp)
binding.carName.text = myEntity.label
binding.layoutCar.setOnClickListener {
listener?.onItemClick(myEntity)
settings.carNumber = myEntity.carNumber
settings.selectedCarType = activity.getString(R.string.settings_category_view_sub_title_for_user_specific_car)
settings.isCarSelected = true
rowIndex = position
notifyDataSetChanged()
}
binding.deleteButton.setOnClickListener {
GlobalScope.launch(Dispatchers.IO) { bbdCarViewModel.deleteByFinNumber(myEntity.carNumber) }
settings.isBBDCarSelected = false
carList.removeAt(position)
notifyDataSetChanged()
}
if (rowIndex == position) {
binding.layoutCar.setBackgroundColor(activity.getColor(R.color.petrol))
binding.carName.setTextColor(activity.getColor(R.color.white))
} else {
binding.layoutCar.setBackgroundColor(activity.getColor(R.color.coolGray))
binding.carName.setTextColor(activity.getColor(R.color.coolGray_80k))
}
}
}
override fun getItemViewType(position: Int): Int {
return if (position == 0 && position <= carList.size) {
VIEW_TYPE_ADDITEM
} else VIEW_TYPE_ITEM
}
override fun getItemCount(): Int {
return carList.size + 1
}
interface OnItemsClickListener {
fun onItemClick(myEntity: MyEntity)
}
fun setWhenClickListener(listener: OnItemsClickListener) {
this.listener = listener
}
companion object {
const val VIEW_TYPE_ITEM = 0
const val VIEW_TYPE_ADDITEM = 1
}
}
请帮我
解决方案
我们可以为适配器类添加占位符,并通过唯一的 id 在其中存储突出显示的项目。然后在绑定函数中,我们可以突出显示具有这些 id 的项目:
1.添加占位符
我们可以使用占位符来保存突出显示的项目来处理活动状态。
它可能是一个 HashSet , Long 的类型是用于项目 id 的,我们将在 init 块中将其设置为稳定。
class CarItemAdapter(...) : ... {
...
val activeHolder: HashSet<Long> = HashSet()
init {
// Represents each item in the data set with a unique indentifier
setHasStableIds(true)
}
...
2.将最近添加的项目添加到placeHolder
现在我们为每个项目获得了一个唯一标识符,以及一个用于保存突出显示项目的活动状态的占位符。
我们希望最后添加的项目被突出显示,所以假设您在 EventHandler 的 onclick 方法中添加新项目,更新 mothed 如下:
inner class EventHandler {
fun onItemClicked() {
with(activeHolder){
val lastItemId = getItemId(carList.size - 1)
// Remove last item's id from our holder to prevent last two items being highlighted.
if (contains(lastItemId)) remove(lastItemId)
// Suppose we add new item to carList here
carList.add(newItem)
// add last item id of new list to the holder
add(getItemId(carList.size - 1))
}
notifyDataSetChanged()
}
}
在上面的代码中,我们假设将新 Item 添加到 list 是 inside carList.add(newItem)
,如果不是这种情况,请将上面的 with(){} 代码块包裹在carList.add(newCar)
.
3.通过onClick动作添加和删除项目到占位符
这个很简单,只是一个单行:
binding.layoutCar.setOnClickListener {
...
with(activeHolder) { if (contains(itemId)) remove(itemId) else add(itemId) }
...
notifyDataSetChanged()
}
4、压轴;执行突出显示
inner class ViewHolderCarItem internal constructor(private var binding: SettingsCarItemTileBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(myEntity: MyEntity, position: Int) {
...
binding.layoutCar.setOnClickListener {
...
with(activeHolder) { if (contains(itemId)) remove(itemId) else add(itemId) }
...
notifyDataSetChanged()
}
binding.deleteButton.setOnClickListener {
...
}
// Activates last item, or item's clicked
itemView.isActivated = activeHolder.contains(itemId)
if(itemView.isActivated) {
// Do anything you want by highlighted items.
}
}
}
我希望这个答案有所帮助。
更新
要执行单击最后一个突出显示的项目:
在活动的 onCreate() 方法中:
lifecycle.coroutineScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
delay(300)
recyclerView.findViewHolderForAdapterPosition(recyclerView.size-1)?.itemView?.performClick()
}
}
注意:对于 repeatOnLifecycle() 方法,您需要androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha01
依赖。
推荐阅读
- flutter - “颤振,异常:Gradle 任务 assembleDebug 失败,退出代码 1”可能是什么问题?
- sql - 如何根据查询结果返回表中的随机记录?
- c# - 如何防止在 ASP.NET Core 的 Razor 视图 HTML 中禁用或只读输入文件的模型绑定?
- python - 如何从 JSON 格式的 API 的经纬度坐标中获取点的几何形状
- object-files - 如何使用 dwarf 将目标文件中的指令映射到源代码行
- c - 在C中计算sinx的泰勒级数
- android - 在模拟器中安装 Flutter Release apk
- solidity - × Unhandled Rejection (Error): 无效片段对象 (argument="value", value=
- drupal - Drupal 8 - “Drupal 已安装”
- python - pd.read_csv 错误:第 52 行中预期有 2 个字段,看到 3