Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Projeto] Problemas na exibição de cards no recyclerview

Quando já tem um card adicionado e vou adicionar outro logo em seguida, esse adicionado recentemente substitui o card anterior, como faço para manter ambos um em baixo do outro fazendo uma lista do recyclerview? Pesquisei sobre o shared preferences e cheguei implementar ele, mas quando eu fui adicionar outro card contendo outro já existente esse novo card não apareceu.

class BudgetsFragment : Fragment() {

    private lateinit var adapter: CardAdapter
    private lateinit var recyclerView: RecyclerView
    private lateinit var cardList: List<CardItem>

    private val retrofit = Retrofit.Builder()
        .baseUrl("https://647fc34cf061e6ec4d485612.mockapi.io/")
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    private val apiService: CardService = retrofit.create(CardService::class.java)

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(R.layout.fragment_budgets, container, false)

        recyclerView = rootView.findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(context)

        val itemId = arguments?.getInt("itemId", -1) ?: -1

        if (::cardList.isInitialized && cardList.isNotEmpty()) {
            adapter = CardAdapter(cardList.toMutableList())
            recyclerView.adapter = adapter
        } else {
            apiService.getCards().enqueue(object : Callback<List<CardItem>> {
                override fun onResponse(call: Call<List<CardItem>>, response: Response<List<CardItem>>) {
                    if (response.isSuccessful) {
                        val cards = response.body() ?: emptyList()
                        val filteredList = cards.filter { it.id == itemId }

                        if (filteredList.isEmpty()) {
                            Toast.makeText(context, "Seu orçamento está vazio.", Toast.LENGTH_SHORT).show()
                        }

                        cardList = filteredList

                        adapter = CardAdapter(cardList.toMutableList())
                        recyclerView.adapter = adapter
                    }
                }

                override fun onFailure(call: Call<List<CardItem>>, t: Throwable) {}
            })
        }

        return rootView
    }
}
class CardAdapter(
    private var cardList: List<CardItem>
) : RecyclerView.Adapter<CardAdapter.CardViewHolder>() {

    class CardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textViewCardTitle: TextView = itemView.findViewById(R.id.textViewCardTitle)
        val imageViewCardItem: ImageView = itemView.findViewById(R.id.imageViewCardItem)
        val imageButtonDeleteCard: ImageButton = itemView.findViewById(R.id.imageButtonDeleteCard)
    }

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

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

        holder.textViewCardTitle.text = currentItem.nome

        Picasso.get().load(currentItem.imagem).into(holder.imageViewCardItem)

        holder.imageButtonDeleteCard.setOnClickListener {
            removeCard(position)
        }
    }

    private fun removeCard(position: Int) {
        val updatedList = cardList.toMutableList()
        updatedList.removeAt(position)

        cardList = updatedList.toList()
        notifyItemRemoved(position)
    }

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

Função do button do DetailsFragment que envia o card:

                        val buttonDetails = view.findViewById<AppCompatButton>(R.id.buttonDetails)
                        buttonDetails.setOnClickListener {
                            val bundle = Bundle()
                            bundle.putInt("itemId", detailsItem.id)
                            val navController = findNavController()
                            navController.navigate(R.id.nav_budgets, bundle)
                        }
2 respostas
solução!

Olá, Giovanni!

Pelo que pude entender, você está tendo um problema ao adicionar novos cards ao RecyclerView no fragmento BudgetsFragment. O novo card adicionado substitui o card anterior, e você deseja que eles sejam exibidos um abaixo do outro, formando uma lista.

O problema está ocorrendo porque toda vez que você chama o método onCreateView() do fragmento BudgetsFragment, você verifica se a lista de cards já está inicializada e não está vazia. Se estiver, você usa essa lista para criar o adaptador e configurar o RecyclerView. Caso contrário, você faz uma chamada de API para obter os cards e cria o adaptador com a lista filtrada.

A solução para manter ambos os cards é ajustar a lógica no método onCreateView(). Em vez de recriar o adaptador sempre que o fragmento é criado, você pode manter uma única instância do adaptador e apenas atualizar a lista de cards que ele exibe.

Aqui está uma sugestão de como fazer isso:

  1. Mova a inicialização do adaptador para o início da classe BudgetsFragment e adicione uma lista vazia como argumento inicial:
class BudgetsFragment : Fragment() {

    private lateinit var adapter: CardAdapter
    private lateinit var recyclerView: RecyclerView
    private var cardList: MutableList<CardItem> = mutableListOf() // Inicializa uma lista vazia

    // Restante do código...
  1. Na função onResponse(), ao invés de criar um novo adaptador e configurar o RecyclerView, atualize apenas a lista de cards no adaptador e notifique as mudanças:
override fun onResponse(call: Call<List<CardItem>>, response: Response<List<CardItem>>) {
    if (response.isSuccessful) {
        val cards = response.body() ?: emptyList()
        val filteredList = cards.filter { it.id == itemId }

        if (filteredList.isEmpty()) {
            Toast.makeText(context, "Seu orçamento está vazio.", Toast.LENGTH_SHORT).show()
        }

        cardList.clear() // Limpa a lista atual de cards
        cardList.addAll(filteredList) // Adiciona os cards filtrados à lista

        adapter.notifyDataSetChanged() // Notifica as mudanças ao adaptador
    }
}

Com essas alterações, o RecyclerView deve exibir os cards um abaixo do outro corretamente, e você poderá adicionar novos cards à lista sem substituir os cards existentes.

Espero que isso resolva o problema! Se precisar de mais assistência ou tiver outras dúvidas, estou aqui para ajudar. Boa sorte com o seu projeto!

Consegui resolver!