gpt4 book ai didi

Proper handling of functions on individual elements of a RecyclerView that contains many elements(正确处理包含多个元素的循环视图的各个元素上的函数)

转载 作者:bug小助手 更新时间:2023-10-25 14:54:08 32 4
gpt4 key购买 nike



I am creating a book-themed application in Android. Briefly within my application I have three sections where a user can enter books, specifically: Daleggere, Incorso, Letti (in Italian, but translated would be: to be read, in progress, read). Each of these sections is an android recyclerview with an associated Adapter, also this recyclerview is populated through a Firebase database in real time. I created an interface in the Adapter to perform operations upon clicking buttons that I have in a layout (that can be opened and closed through the hideShow function) of each individual recyclerview item. Everything seemed to be working, but today I realized that if I go to add more than 9 books within my list, when I act on one of them, each of my actions is copied for the element 9 times ahead of the one I interacted with (if I open the layout of the first element it also opens the layout of the ninth, if I like the second book it also puts like on the tenth etc.) This problem is not only graphical, but also in the database I am assigned for example "like" to element ten (taking the example from before). This is the Fragment class CatalogoLetti:

我正在用Android创建一个以书籍为主题的应用程序。简单地说,在我的应用程序中,我有三个部分,用户可以在其中输入书籍,特别是:Daleggere,Incorso,Letti(意大利语,但翻译为:To be Read,in Process,Read)。每个部分都是一个带有关联适配器的Android回收器视图,并且该回收器视图是通过Firebase数据库实时填充的。我在Adapter中创建了一个界面,用于在单击每个回收器查看项目的布局(可以通过hideShow函数打开和关闭)中的按钮时执行操作。一切似乎都很正常,但今天我意识到,如果我在我的列表中添加9本以上的书,当我对其中一本书执行操作时,我的每个操作都会被复制到我交互的元素前面9次(如果我打开第一个元素的布局,它也会打开第九个元素的布局,如果我喜欢第二本书,它也会把Like放在第十本书上,依此类推)。这个问题不仅是图形化的,而且在数据库中,我被分配给元素10的例子是“Like”(以前面的例子为例)。这是片段类CatalogoLetti:


class CatalogoLetti : Fragment() {
private lateinit var binding: FragmentCatalogoLettiBinding
private lateinit var recyclerView : RecyclerView
private lateinit var viewModel: CatalogoViewModel
private lateinit var adapter: MyAdapterL
private lateinit var listaLibri: ArrayList<LibriL>
private lateinit var select: Spinner
private val sezioni = arrayListOf("Da Leggere","Letti")

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate<FragmentCatalogoLettiBinding>(
inflater,
R.layout.fragment_catalogo_letti, container, false
)

binding.backbuttonL.setOnClickListener{
val navController = findNavController()
navController.navigate(R.id.action_catalogoLetti_to_catalogoHome)
}


return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(CatalogoViewModel::class.java)

listaLibri = ArrayList()

recyclerView = binding.listaLibriLeggere
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.setHasFixedSize(true)

adapter = MyAdapterL(listaLibri)
recyclerView.adapter = adapter


adapter.setOnCLickItemListener(object : MyAdapterL.onItemClickListener {
override fun onItemClick(position: Int) {

}

override fun hideShow(element: LinearLayout, comment: ImageButton) {
// Gestione del click per mostrare/nascondere un sezione
val linearL = element
val btn = comment
if(linearL.visibility == View.GONE) {
linearL.visibility = View.VISIBLE
btn.setBackgroundResource(R.drawable.comment_filled_icon)
}
else {
linearL.visibility = View.GONE
btn.setBackgroundResource(R.drawable.comment_icon)
}

}

override fun likeDislike(like: ImageButton, dislike: ImageButton, position: Int) {
// Gestione del click sui pulsanti "Mi piace" e "Non mi piace"
val btnLike = like
val btnDislike = dislike
val bookPos = position
val bookId = getIdPos(bookPos)

btnLike.setOnClickListener {
lifecycleScope.launch {
if (listaLibri[position].valutazione == 1) {
if (bookId != null) {
viewModel.removelike(bookId)
btnLike.setImageResource(R.drawable.pollice_icon)
listaLibri[position].valutazione = 0
}
} else {
if (bookId != null) {
viewModel.like(bookId)
btnLike.setImageResource(R.drawable.like_click_icon)
btnDislike.setImageResource(R.drawable.pollice_icon)
listaLibri[position].valutazione = 1
}
}
}
}

btnDislike.setOnClickListener {
lifecycleScope.launch {
if (listaLibri[position].valutazione == 2) {
if (bookId != null) {
viewModel.removelike(bookId)
btnDislike.setImageResource(R.drawable.pollice_icon)
listaLibri[position].valutazione = 0
}
} else {
if (bookId != null) {
viewModel.dislike(bookId)
btnDislike.setImageResource(R.drawable.dislike_click)
btnLike.setImageResource(R.drawable.pollice_icon)
listaLibri[position].valutazione = 2
}
}

}
}
}

override fun comment(recensione: TextInputLayout, position: Int) {
// Gestione dell'inserimento di un commento su un libro letto
val commento = recensione.editText

if (commento != null) {
commento.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {

}

override fun onTextChanged(
s: CharSequence?,
start: Int,
before: Int,
count: Int
) {

}

override fun afterTextChanged(s: Editable?) {
if(s != null && s.isNotEmpty() && s.last() == '\n'){
s.replace(s.length - 1, s.length, "")
val review = s.toString()
val bookPos = position

val bookId = getIdPos(bookPos)
if (bookId != null) {
viewModel.comment(review, bookId)

}
}

}


})
}
}
override fun dettaglioBook(cover: ImageButton, position: Int) {
// Gestione del click sulla copertina per visualizzare i dettagli di un libro letto
lifecycleScope.launch {
val libro = async {getLibro(position)}

val action =
CatalogoLettiDirections.actionCatalogoLettiToLibroLetto(
libro.await()!!,
"catalogoLetti"
)
findNavController().navigate(action)
}
}

override fun remove(button: ImageButton, position: Int) {
// Gestione del click sul pulsante rappresentante una x per rimuovere un libro letto
val dButton = button
val bookPos = position
val bookId = getIdPos(bookPos)
dButton.setOnClickListener {
var dialog: AlertDialog? = null
val builder = AlertDialog.Builder(requireContext())
val dialogView = layoutInflater.inflate(R.layout.dialog_elimina, null)
val btnConfirm = dialogView.findViewById<Button>(R.id.btn_confirm)
val btnCancel = dialogView.findViewById<Button>(R.id.btn_cancel)
builder.setView(dialogView)

btnConfirm.setOnClickListener {
if (bookId != null) {
viewModel.removeBook(bookId, "letti")
Toast.makeText(
requireContext(),
"Libro eliminato con successo!",
Toast.LENGTH_SHORT
).show()
}else{
Toast.makeText(
requireContext(),
"Errore nell'eliminazione!",
Toast.LENGTH_SHORT
).show()
}
dialog?.dismiss()
}

btnCancel.setOnClickListener {
dialog?.dismiss()
}

dialog = builder.create()
dialog?.show()
}
}

})

viewModel.checkBookCatalogo()
viewModel.libriLetti.observe(viewLifecycleOwner, Observer { LettiBooksList ->
loadBooks(LettiBooksList)
})

}

private fun loadBooks(books: List<LibriL>?){
// Carica i libri letti nella lista listaLibri
listaLibri.clear()
if (books != null) {
listaLibri.addAll(books)
adapter.notifyDataSetChanged()
}
}

private fun getIdPos(position : Int): String? {
// Ottiene l'ID del libro in una deteerminata posizione
if(listaLibri.isNotEmpty()){
val bookId = listaLibri[position].id
return bookId
}
return null
}

private suspend fun getLibro(position: Int): LibriL? {
// Ottiene i dettagli di un libro letto dal database Firebase
val bookId = listaLibri[position].id
var bookD: LibriL? = null

if (FirebaseAuth.getInstance().currentUser != null) {
val cUser = FirebaseAuth.getInstance().currentUser!!
val database =
FirebaseDatabase.getInstance("https://booktique-87881-default-rtdb.europe-west1.firebasedatabase.app/")
val usersRef = database.reference.child("Utenti")
val childRef = usersRef.child(cUser.uid)
val catalogoRef = childRef.child("Catalogo")
val lettiRef = catalogoRef.child("Letti")

if (bookId != null) {
val dataSnapshot = lettiRef.child(bookId).get().await()
bookD = dataSnapshot.getValue(LibriL::class.java)
}
}
return bookD
}

}

And this is the Adapter, MyAdapterL:

这是适配器MyAdapterL:


class MyAdapterL (private val listaLibri : ArrayList<LibriL>) :
RecyclerView.Adapter<MyAdapterL.MyViewHolder>() {

private lateinit var bListener : onItemClickListener

interface onItemClickListener{
fun onItemClick(position: Int)
fun hideShow(element: LinearLayout, comment : ImageButton)

fun likeDislike(like: ImageButton, dislike : ImageButton, position: Int)

fun comment(recensione : TextInputLayout, position: Int)

fun dettaglioBook(cover: ImageButton, position: Int)

fun remove(button: ImageButton, position: Int)
}

fun setOnCLickItemListener(listener : onItemClickListener){
bListener = listener
}

class MyViewHolder(itemView : View, listener: onItemClickListener) : RecyclerView.ViewHolder(itemView){

val cover : ImageButton = itemView.findViewById(R.id.coverL)
val titolo : TextView = itemView.findViewById(R.id.titoloL)
val autore : TextView = itemView.findViewById(R.id.autoreL)
val btnLike : ImageButton = itemView.findViewById(R.id.likeL)
val btnDislike : ImageButton = itemView.findViewById(R.id.dislikeL)
val comment : TextInputLayout = itemView.findViewById(R.id.textInputLayout)

init {

itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}

itemView.findViewById<ImageButton>(R.id.commentL).setOnClickListener {
listener.hideShow(itemView.findViewById(R.id.hideLayoutL), itemView.findViewById(R.id.commentL))
listener.likeDislike(btnLike,btnDislike,absoluteAdapterPosition)
listener.comment(comment,absoluteAdapterPosition)
}

itemView.findViewById<ImageButton>(R.id.coverL).setOnClickListener{
listener.dettaglioBook(itemView.findViewById(R.id.coverL),bindingAdapterPosition)

}

itemView.findViewById<ImageButton>(R.id.deleteL).setOnClickListener {
listener.remove(itemView.findViewById(R.id.deleteL),bindingAdapterPosition)
}

}

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.lista_libri_letti,parent,false)
return MyViewHolder(itemView,bListener)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = listaLibri[position]

Glide.with(holder.itemView.context)
.load(currentItem.copertina)
.into(holder.cover)
holder.titolo.text = abbreviaInfo(currentItem?.titolo ?: "",25)

holder.autore.text = abbreviaInfo(currentItem?.autori ?: "",25)

if(currentItem?.valutazione == 1)
holder.btnLike.setImageResource(R.drawable.like_click_icon)
else if(currentItem?.valutazione == 2)
holder.btnDislike.setImageResource(R.drawable.dislike_click)

holder.comment.editText?.setText(currentItem?.recensione ?: "")
}

override fun getItemCount(): Int {
return listaLibri.size
}

fun abbreviaInfo(stringa: String, lunghezzaMassima: Int): String {
return if (stringa.length <= lunghezzaMassima) {
stringa
} else {
val sottostringa = stringa.take(lunghezzaMassima)
"$sottostringa..."
}
}

}

I thought that this problem was due to the fact that in all my functions I use the position of the element within my list and that actually the recyclerview to save memory only counted 9 elements at a time. But by printing the position of the element in position 12 for example, the result is correct and it is 12, moreover by clicking on the cover of each of the books (elements of my recyclerview) I have the possibility to enter a detail page of it. But here, to my surprise, there is no problem and even if I click on the cover of the book in position 20 it opens the right book. So I don't know at this point maybe the problem is in the init of my adapter, when I go to open the layout that allows me to perform the various actions on the book here:

我认为这个问题是因为在我的所有函数中,我都使用了元素在列表中的位置,而实际上,为了节省内存而进行回收的视图一次只计算了9个元素。但例如,通过打印位置12的元素的位置,结果是正确的,它是12,此外,通过点击每本书的封面(我的回收视图的元素),我有可能进入它的详细页面。但在这里,令我惊讶的是,没有任何问题,即使我在20号位置点击这本书的封面,它也会打开正确的书。因此,我不知道在这一点上,当我打开允许我在书上执行各种操作的布局时,可能问题出在我的适配器的初始化中:


itemView.findViewById<ImageButton>(R.id.commentL).setOnClickListener {
listener.hideShow(itemView.findViewById(R.id.hideLayoutL), itemView.findViewById(R.id.commentL))
listener.likeDislike(btnLike,btnDislike,absoluteAdapterPosition)
listener.comment(comment,absoluteAdapterPosition)
}

I'm relatively new to the Android world, thanks a lot in advance!

我对Android世界还比较陌生,在此之前非常感谢!


更多回答
优秀答案推荐
更多回答

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