3
respostas

Não consegui completar o desafio de Pop-up

Já realizei inúmeras modificações, inclusive as mostradas nos tópicos anteriores, porém nada funciona, ou ele não reconhece o clique longo, ou ele não realiza a remoção do item quando clicado. Poderiam por favor me ajudar, não consigo identificar onde estou errando ! ;/

package com.example.orgsrafael.recycletview

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.PopupMenu
import androidx.recyclerview.widget.RecyclerView
import com.example.orgsrafael.R
import com.example.orgsrafael.database.AppDataBase
import com.example.orgsrafael.databinding.ProdutoItemBinding
import com.example.orgsrafael.extensions.carregarImagem
import com.example.orgsrafael.extensions.conversorMoedaBrasileira
import com.example.orgsrafael.model.Produto
import com.example.orgsrafael.ui.activity.CHAVE_PRODUTO_ID
import com.example.orgsrafael.ui.activity.DetalhesProdutosListaActivity

class ListaProdutosAdapter(
    private val context: Context,
    list: List<Produto> = emptyList(),
    var clicaNoItem: (produto: Produto) -> Unit = {},
    var quandoClicaEmEditar: (produto: Produto) -> Unit = {},
    var quandoClicaEmRemover: (produto: Produto) -> Unit = {}


) : RecyclerView.Adapter<ListaProdutosAdapter.ViewHolder>() {

    private val produtoDao by lazy {
        AppDataBase.instanceDb(context).produtoDao()
    }

    private val listaAtualizada = list.toMutableList()


    inner class ViewHolder(private val binding: ProdutoItemBinding, produto: Produto) :
        RecyclerView.ViewHolder(binding.root), PopupMenu.OnMenuItemClickListener {

        private lateinit var produto: Produto

        init {
            itemView.setOnLongClickListener {
                PopupMenu(context, itemView).apply {
                    inflate(R.menu.menu_popup_deletar)
                    setOnMenuItemClickListener(this@ViewHolder)
                    show()
                };true
            }
        }


        fun vincula(produto: Produto) {
            val nome = binding.produtoItemNome
            nome.text = produto.nome
            val descricao = binding.activityProdutoItemDescricao
            descricao.text = produto.descricao
            val valor = binding.activityProdutoItemValor
            val valorEmReais: String = produto.valor.conversorMoedaBrasileira()
            valor.text = valorEmReais

            val viewVisibilidade = if (produto.imagem != null) {
                View.VISIBLE
            } else {
                View.GONE
            }
            binding.imageView.visibility = viewVisibilidade

            binding.imageView.carregarImagem(produto.imagem)
        }

        override fun onMenuItemClick(item: MenuItem?): Boolean {
            item?.let {
                if (::produto.isInitialized) {
                    when (it.itemId) {
                        R.id.menu_popup_remover -> {
                            quandoClicaEmRemover(produto)
                        }
                    }

                }
            }
            return true
        }


    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(context)
        val binding = ProdutoItemBinding.inflate(inflater, parent, false)
        return ViewHolder(binding)
    }

    override fun getItemCount(): Int = listaAtualizada.size


    override fun onBindViewHolder(holder: ListaProdutosAdapter.ViewHolder, position: Int) {
        val produto = listaAtualizada[position]
        holder.vincula(produto)
        vaiParaDetalhesProdutoActivity(holder, produto)
    }

    private fun vaiParaDetalhesProdutoActivity(
        holder: ViewHolder,
        produto: Produto
    ) {
        holder.itemView.setOnClickListener {
            val intent =
                Intent(holder.itemView.context, DetalhesProdutosListaActivity::class.java)
                    .apply {
                        putExtra(CHAVE_PRODUTO_ID, produto.id)
                    }
            holder.itemView.context.startActivity(intent)
        }
    }


    fun atualiza(produtos: List<Produto>) {
        this.listaAtualizada.clear()
        this.listaAtualizada.addAll(produtos)
        notifyDataSetChanged()
    }


}
3 respostas

Segue A baixo a classe Lista Produtos Activity:

package com.example.orgsrafael.ui.activity

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.orgsrafael.database.AppDataBase
import com.example.orgsrafael.databinding.ActivityListaProdutosBinding
import com.example.orgsrafael.model.Produto
import com.example.orgsrafael.recycletview.ListaProdutosAdapter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private const val TAG = "ListaProdutosActivity"

class ListaProdutosActivity : AppCompatActivity() {

    private val adapter = ListaProdutosAdapter(this)
    private val binding by lazy {
        ActivityListaProdutosBinding.inflate(layoutInflater)
    }
    private val produtoDao by lazy {
        AppDataBase.instanceDb(this).produtoDao()
    }

    private val scope = CoroutineScope(Dispatchers.IO)
    private var produtoId: Long = 0L
    private var produto: Produto? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        title = "Lista de Produtos"
        configuraRecycler()
        configuraFab()
    }


    override fun onResume() {
        super.onResume()
        scope.launch {
            val produtos = withContext(Dispatchers.IO) {
                produtoDao.getAll()
            }
            withContext(Main) {
                adapter.atualiza(produtos)
            }
        }
    }


    private fun configuraRecycler() {
        val recyclerView = binding.activityRecyclerLista
        recyclerView.adapter = adapter
        adapter.clicaNoItem = {
            val intent = Intent(
                this,
                DetalhesProdutosListaActivity::class.java
            ).apply {
                putExtra(CHAVE_PRODUTO_ID, it.id)
            }
            startActivity(intent)
        }
        adapter.quandoClicaEmRemover = {
            produtoDao.delete()
            Log.i(TAG, "configuraRecyclerView: Remover $it")
            val intent = Intent(
                this,
                ListaProdutosActivity::class.java
            )
            startActivity(intent)
            finish()
        }
    }

    private fun vaiParaFormulario2(it: Produto) {
        val intent = Intent(
            this,
            DetalhesProdutosListaActivity::class.java
        ).apply {
            putExtra(CHAVE_PRODUTO_ID, it.id)
        }
        startActivity(intent)
    }

    private fun configuraFab() {
        val fab = binding.activityBotapAdicionarFab
        fab.setOnClickListener {
            vaiParaFormulario()
        }
    }

    private fun vaiParaFormulario() {
        val intent = Intent(this, FormularioProdutoActivity::class.java)
        startActivity(intent)
    }

}

Olá, Mariane! Entendo que você esteja tendo dificuldades com o desafio de implementação do menu de pop-up. Vamos tentar resolver isso juntas!

Analisando o seu código, percebi que você está inicializando o produto no ViewHolder, mas não está atualizando o valor dele no método vincula(produto: Produto). Isso pode estar causando o problema de não remoção do item, já que o produto não está sendo corretamente identificado quando você tenta removê-lo.

Aqui está um exemplo de como você pode tentar corrigir isso:

fun vincula(produto: Produto) {
    this.produto = produto // Adicione esta linha para atualizar o valor do produto
    val nome = binding.produtoItemNome
    nome.text = produto.nome
    // Resto do código...
}

Em relação ao clique longo não ser reconhecido, isso pode estar acontecendo porque você está definindo o setOnLongClickListener dentro do init do ViewHolder. Isso faz com que o listener seja configurado apenas uma vez, quando o ViewHolder é criado. No entanto, o ViewHolder pode ser reutilizado várias vezes com diferentes produtos. Para resolver isso, você pode mover a definição do setOnLongClickListener para dentro do método vincula(produto: Produto), assim o listener será configurado corretamente para cada produto.

Veja como ficaria:

fun vincula(produto: Produto) {
    this.produto = produto
    val nome = binding.produtoItemNome
    nome.text = produto.nome
    // Resto do código...

    itemView.setOnLongClickListener {
        PopupMenu(context, itemView).apply {
            inflate(R.menu.menu_popup_deletar)
            setOnMenuItemClickListener(this@ViewHolder)
            show()
        };true
    }
}

Espero que essas sugestões possam te ajudar a resolver o problema. Espero ter ajudado. Qualquer dúvida manda aqui. Bons estudos.

Muito obrigada pela ajuda ! Consegui resolver o problema e ja adicionei ao escopo da Coroutine. Todas as funções do APP agora estão normais. Só achei estranho o fato de ter praticamente copiado o exercício do github e mesmo assim ele não ter funcionado, se compararmos o que você me passou com o código da aula, de fato esta diferente...