如何在回收站视图中正确 select 和 deselect 项目?
How to properly select and deselect items in recycler view?
我是 Android Kotlin 的初学者,我正在开发一个练习应用程序,它需要从回收器视图中选择的数据放在数组列表中。在我更改我的微调器值并重新加载项目之前,选择工作正常,一旦重新加载项目,需要单击两次才能取消选择,但仍未从所选数据 arrayList 中删除。 (每当更改微调器值时,都会从 API 加载数据)。我知道这段代码很乱,有很多不必要的东西,如果有人能帮我清理代码并解决问题,我会很高兴。
class RecyclerViewAdapter(val dataList:ArrayList<ModelClass>):RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){
object ob {
val dataSelected= ArrayList<ModelClass>()
}
private var _binding: ItemViewBinding? = null
private val binding get() = _binding!!
private lateinit var nListener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener:onItemClickListener){
nListener=listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewAdapter.ViewHolder {
val v=LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)
_binding= ItemViewBinding.bind(v)
return ViewHolder(binding.root)
}
fun bindItems(data:ModelClass){
binding.itemQuant.text=data.item_quant
binding.itemName.text=data.item_name
binding.mfgName.text=data.mfg
binding.quantity.text=data.item_stock.toString()
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.restore()
bindItems(dataList[position])
holder.select()
}
@SuppressLint("ResourceAsColor")
inner class ViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
fun restore(){
for (i in 0 until ob.dataSelected.size){
for (j in 0 until dataList.size){
if (ob.dataSelected[i].sku_code==(dataList[j]).sku_code) {
if(adapterPosition == j){
itemView.isSelected = true
itemView.setBackgroundColor(R.color.black)
println("****")
}
}
}
}
}
fun select(){
itemView.setOnClickListener {
val position: Int = adapterPosition
if (ob.dataSelected.contains(dataList[position]) ){
itemView.setBackgroundResource(0)
itemView.isSelected = false
ob.dataSelected.remove(dataList[position])
for (i in 0 until ob.dataSelected.size){
println(ob.dataSelected[i].sku_code)
}
}
else {
itemView.isSelected = true
itemView.setBackgroundColor(R.color.black)
ob.dataSelected.add((dataList.get(position)))
for (i in 0 until ob.dataSelected.size){
println(ob.dataSelected[i].sku_code)
}
}
}
}
}
override fun getItemCount(): Int {
return dataList.size
}
override fun getItemId(position: Int): Long = position.toLong()
}
.
.
.
.
.
.
编辑:
class RecyclerViewAdapter(val dataList:ArrayList,val onItemClicked: (Int) -> Unit):RecyclerView.Adapter(){
对象对象{
val dataSelected= ArrayList()
}
private var checkedPosition = -1
fun setData(listModel: List<ModelClass>) {
dataList.clear()
dataList.addAll(listModel)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemViewBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ViewHolder(binding, parent.context)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(dataList[position])
}
override fun getItemCount() = dataList.size
inner class ViewHolder(
val binding: ItemViewBinding,
val context: Context
): RecyclerView.ViewHolder(binding.root) {
@SuppressLint("ResourceAsColor", "ResourceType")
fun bindItems(data: ModelClass) = with(binding) {
/*
* Map Your data Here
* example: tvTitle.text = model.title
* */
binding.itemQuant.text=data.item_quant
binding.itemName.text=data.item_name
binding.mfgName.text=data.mfg
binding.quantity.text=data.item_stock.toString()
when (checkedPosition) {
-1 -> {
itemView.setBackgroundResource(0)
}
else -> when (checkedPosition) {
adapterPosition -> {
itemView.setBackgroundColor(R.color.black)
}
else -> {
itemView.setBackgroundResource(0)
}
}
}
root.setOnClickListener {
itemView.setBackgroundResource(R.color.black)
if (checkedPosition != adapterPosition) {
notifyItemChanged(checkedPosition)
checkedPosition = adapterPosition
}
// Handle the clicked item
if (ob.dataSelected.contains(dataList[adapterPosition])){
ob.dataSelected.remove(dataList[adapterPosition])
itemView.isSelected=false
for (i in ob.dataSelected){
println(i.sku_code)
}
itemView.setBackgroundColor(R.color.black)
}
else {
ob.dataSelected.add(dataList[adapterPosition])
itemView.isSelected=true
for (i in ob.dataSelected){
println(i.sku_code)
}
itemView.setBackgroundResource(0)
}
onItemClicked.invoke(adapterPosition)
}
}
}
}
这里试试这个,我试过重构你的代码
class RecyclerViewAdapter(
val onItemClicked: (Int) -> Unit
) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
private val data = ArrayList<ModelClass>()
private var checkedPosition = -1 // -1: No Item Selected, 0: First Item Selected
fun setData(listModel: List<ModelClass>) {
data.clear()
data.addAll(listModel)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemViewBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ViewHolder(binding, parent.context)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(data[position])
}
override fun getItemCount() = data.size
inner class ViewHolder(
val binding: ItemViewBinding,
val context: Context
): RecyclerView.ViewHolder(binding.root) {
fun bindItems(model: ModelClass) = with(binding) {
/*
* Map Your data Here
* example: tvTitle.text = model.title
* */
when (checkedPosition) {
-1 -> {
clLayout.setBackgroundResource(0)
}
else -> when (checkedPosition) {
absoluteAdapterPosition -> {
clLayout.setBackgroundResource(R.drawable.bg_curved_grey)
}
else -> {
clLayout.setBackgroundResource(0)
}
}
}
root.setOnClickListener {
clLayout.setBackgroundResource(R.drawable.bg_curved_grey)
if (checkedPosition != absoluteAdapterPosition) {
notifyItemChanged(checkedPosition)
checkedPosition = absoluteAdapterPosition
}
// Handle the clicked item
onItemClicked.invoke(absoluteAdapterPosition)
}
}
}
}
这里是你如何在你的Activity或片段
中使用它
private val recyclerViewAdapter: RecyclerViewAdapter by lazy {
//RecyclerViewAdapter(this::onClickedItem) you can call the function below like this or
//RecyclerViewAdapter { onClickedItem(it) } or
RecyclerViewAdapter { position ->
onClickedItem(position )
}
}
private fun onClickedItem(position: Int) {
//do something
Toast.makeText(this, position.toString, Toast.LENGTH_SHORT).show()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.recyclerview.apply {
layoutManager = LinearLayoutManager(this)
adapter = recyclerViewAdapter
}
// yourdata = dataList:ArrayList<ModelClass>
recyclerViewAdapter.setData(yourData)
}
一些解释
它是一个高阶函数,你可以在这里阅读更多Higher order function
val onItemClicked: (Int) -> Unit
用这段代码我们可以删除这个
private lateinit var nListener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener:onItemClickListener){
nListener=listener
}
用这段代码
fun setData(listModel: List<ModelClass>) {
data.clear()
data.addAll(listModel)
notifyDataSetChanged()
}
我们使适配器可以灵活处理任何数据集List<ModelClass>
我是 Android Kotlin 的初学者,我正在开发一个练习应用程序,它需要从回收器视图中选择的数据放在数组列表中。在我更改我的微调器值并重新加载项目之前,选择工作正常,一旦重新加载项目,需要单击两次才能取消选择,但仍未从所选数据 arrayList 中删除。 (每当更改微调器值时,都会从 API 加载数据)。我知道这段代码很乱,有很多不必要的东西,如果有人能帮我清理代码并解决问题,我会很高兴。
class RecyclerViewAdapter(val dataList:ArrayList<ModelClass>):RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){
object ob {
val dataSelected= ArrayList<ModelClass>()
}
private var _binding: ItemViewBinding? = null
private val binding get() = _binding!!
private lateinit var nListener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener:onItemClickListener){
nListener=listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewAdapter.ViewHolder {
val v=LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)
_binding= ItemViewBinding.bind(v)
return ViewHolder(binding.root)
}
fun bindItems(data:ModelClass){
binding.itemQuant.text=data.item_quant
binding.itemName.text=data.item_name
binding.mfgName.text=data.mfg
binding.quantity.text=data.item_stock.toString()
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.restore()
bindItems(dataList[position])
holder.select()
}
@SuppressLint("ResourceAsColor")
inner class ViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
fun restore(){
for (i in 0 until ob.dataSelected.size){
for (j in 0 until dataList.size){
if (ob.dataSelected[i].sku_code==(dataList[j]).sku_code) {
if(adapterPosition == j){
itemView.isSelected = true
itemView.setBackgroundColor(R.color.black)
println("****")
}
}
}
}
}
fun select(){
itemView.setOnClickListener {
val position: Int = adapterPosition
if (ob.dataSelected.contains(dataList[position]) ){
itemView.setBackgroundResource(0)
itemView.isSelected = false
ob.dataSelected.remove(dataList[position])
for (i in 0 until ob.dataSelected.size){
println(ob.dataSelected[i].sku_code)
}
}
else {
itemView.isSelected = true
itemView.setBackgroundColor(R.color.black)
ob.dataSelected.add((dataList.get(position)))
for (i in 0 until ob.dataSelected.size){
println(ob.dataSelected[i].sku_code)
}
}
}
}
}
override fun getItemCount(): Int {
return dataList.size
}
override fun getItemId(position: Int): Long = position.toLong()
} . . . . . . 编辑:
class RecyclerViewAdapter(val dataList:ArrayList,val onItemClicked: (Int) -> Unit):RecyclerView.Adapter
对象对象{ val dataSelected= ArrayList()
}
private var checkedPosition = -1
fun setData(listModel: List<ModelClass>) {
dataList.clear()
dataList.addAll(listModel)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemViewBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ViewHolder(binding, parent.context)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(dataList[position])
}
override fun getItemCount() = dataList.size
inner class ViewHolder(
val binding: ItemViewBinding,
val context: Context
): RecyclerView.ViewHolder(binding.root) {
@SuppressLint("ResourceAsColor", "ResourceType")
fun bindItems(data: ModelClass) = with(binding) {
/*
* Map Your data Here
* example: tvTitle.text = model.title
* */
binding.itemQuant.text=data.item_quant
binding.itemName.text=data.item_name
binding.mfgName.text=data.mfg
binding.quantity.text=data.item_stock.toString()
when (checkedPosition) {
-1 -> {
itemView.setBackgroundResource(0)
}
else -> when (checkedPosition) {
adapterPosition -> {
itemView.setBackgroundColor(R.color.black)
}
else -> {
itemView.setBackgroundResource(0)
}
}
}
root.setOnClickListener {
itemView.setBackgroundResource(R.color.black)
if (checkedPosition != adapterPosition) {
notifyItemChanged(checkedPosition)
checkedPosition = adapterPosition
}
// Handle the clicked item
if (ob.dataSelected.contains(dataList[adapterPosition])){
ob.dataSelected.remove(dataList[adapterPosition])
itemView.isSelected=false
for (i in ob.dataSelected){
println(i.sku_code)
}
itemView.setBackgroundColor(R.color.black)
}
else {
ob.dataSelected.add(dataList[adapterPosition])
itemView.isSelected=true
for (i in ob.dataSelected){
println(i.sku_code)
}
itemView.setBackgroundResource(0)
}
onItemClicked.invoke(adapterPosition)
}
}
}
}
这里试试这个,我试过重构你的代码
class RecyclerViewAdapter(
val onItemClicked: (Int) -> Unit
) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
private val data = ArrayList<ModelClass>()
private var checkedPosition = -1 // -1: No Item Selected, 0: First Item Selected
fun setData(listModel: List<ModelClass>) {
data.clear()
data.addAll(listModel)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemViewBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ViewHolder(binding, parent.context)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(data[position])
}
override fun getItemCount() = data.size
inner class ViewHolder(
val binding: ItemViewBinding,
val context: Context
): RecyclerView.ViewHolder(binding.root) {
fun bindItems(model: ModelClass) = with(binding) {
/*
* Map Your data Here
* example: tvTitle.text = model.title
* */
when (checkedPosition) {
-1 -> {
clLayout.setBackgroundResource(0)
}
else -> when (checkedPosition) {
absoluteAdapterPosition -> {
clLayout.setBackgroundResource(R.drawable.bg_curved_grey)
}
else -> {
clLayout.setBackgroundResource(0)
}
}
}
root.setOnClickListener {
clLayout.setBackgroundResource(R.drawable.bg_curved_grey)
if (checkedPosition != absoluteAdapterPosition) {
notifyItemChanged(checkedPosition)
checkedPosition = absoluteAdapterPosition
}
// Handle the clicked item
onItemClicked.invoke(absoluteAdapterPosition)
}
}
}
}
这里是你如何在你的Activity或片段
中使用它private val recyclerViewAdapter: RecyclerViewAdapter by lazy {
//RecyclerViewAdapter(this::onClickedItem) you can call the function below like this or
//RecyclerViewAdapter { onClickedItem(it) } or
RecyclerViewAdapter { position ->
onClickedItem(position )
}
}
private fun onClickedItem(position: Int) {
//do something
Toast.makeText(this, position.toString, Toast.LENGTH_SHORT).show()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.recyclerview.apply {
layoutManager = LinearLayoutManager(this)
adapter = recyclerViewAdapter
}
// yourdata = dataList:ArrayList<ModelClass>
recyclerViewAdapter.setData(yourData)
}
一些解释
它是一个高阶函数,你可以在这里阅读更多Higher order function
val onItemClicked: (Int) -> Unit
用这段代码我们可以删除这个
private lateinit var nListener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener:onItemClickListener){
nListener=listener
}
用这段代码
fun setData(listModel: List<ModelClass>) {
data.clear()
data.addAll(listModel)
notifyDataSetChanged()
}
我们使适配器可以灵活处理任何数据集List<ModelClass>