Saludos a todos,

Estoy desarrollando una aplicación en Android por mi cuenta, aplicando los 
conocimientos aprendidos en los cursos "Android Basics in Kotlin", "Modern 
Android app architecture", "Advanced Android in Kotlin" y "Accessibility". 
La aplicación carga datos de productos y categorías desde Firebase Realtime 
Database y los muestra en diferentes RecyclerView, dependiendo de la 
categoría seleccionada.

Mi problema surge al rotar la pantalla, ya que los registros en el 
RecyclerView se pierden. He intentado implementar LiveData, ViewBinding, 
MVVM y Repository, pero no logro encontrar la solución.

Me gustaría solicitar su ayuda para entender y corregir este problema. 
Quiero seguir aprendiendo y mejorar mis habilidades en el desarrollo de 
aplicaciones Android con Kotlin.

Agradezco cualquier sugerencia o consejo que puedan ofrecerme.

Muchas gracias de antemano.

-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to android-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/4abc479e-168c-4169-8c89-dff59e0edcb5n%40googlegroups.com.
class ProductListViewModel : ViewModel() {

    private val productRepository = ProductRepository()
    // Products
    private val productList: LiveData<List<Product>> = 
productRepository.getProductList()
    // Types
    private val productTypeList: LiveData<List<ProductType>> = 
productRepository.getProductTypeList()

    fun getProductList(): LiveData<List<Product>> {
        return productList
    }
    fun getProductTypeList(): LiveData<List<ProductType>> {
        return productTypeList
    }

    fun getProductsByCategory(category: String): LiveData<List<Product>> {
        return productRepository.getProductsByCategory(category)
    }

}
class ProductListFragment : Fragment(), ProductItemClickListener, 
ProductTypeItemClickListener {

    enum class SortOrder {
        ASC,
        DESC
    }

    private var _binding: FragmentProductListBinding? = null
    private val binding get() = _binding!!

    // Product Types
    private lateinit var rvProductTypes: RecyclerView
    private lateinit var productTypeAdapter: ProductCategoryAdapter

    // Products
    private lateinit var rvProducts: RecyclerView
    private lateinit var productAdapter: ProductAdapter


    // ViewModel
    private val productListViewModel: ProductListViewModel by viewModels()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, 
savedInstanceState: Bundle?): View? {
        _binding = FragmentProductListBinding.inflate(inflater, container, 
false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Product Type
        rvProductTypes = binding.rvProductCategory
        rvProductTypes.layoutManager = LinearLayoutManager(requireContext(), 
LinearLayoutManager.HORIZONTAL, false)

        productTypeAdapter = ProductCategoryAdapter()
        rvProductTypes.adapter = productTypeAdapter

        // Asignar el listener al adapter
        productTypeAdapter.setItemClickListener(this)

        productListViewModel.getProductTypeList().observe(viewLifecycleOwner) { 
productTypeList ->
            productTypeAdapter.productTypeList = productTypeList
            productTypeAdapter.notifyDataSetChanged()
        }

        // Products
        rvProducts = binding.rvProducts
        rvProducts.layoutManager = LinearLayoutManager(requireContext(), 
LinearLayoutManager.HORIZONTAL, false)

        productAdapter = ProductAdapter()
        rvProducts.adapter = productAdapter

        // Asignar el listener al adapter
        productAdapter.setItemClickListener(this)

        productListViewModel.getProductList().observe(viewLifecycleOwner) { 
productList ->
            productAdapter.productList = productList
            productAdapter.notifyDataSetChanged()
        }

        // Filter
        binding?.ivFilterProducts?.setOnClickListener { view ->
            // Código del evento onClick del botón
            val popup = PopupMenu(requireContext(), view)
            popup.inflate(R.menu.menu_product_sort)
            popup.setOnMenuItemClickListener { item ->
                when (item.itemId) {
                    R.id.sort_asc -> {
                        sortProducts(SortOrder.ASC)
                        true
                    }
                    R.id.sort_desc -> {
                        sortProducts(SortOrder.DESC)
                        true
                    }
                    else -> false
                }
            }
            popup.show()
        }
    }

    /**
     * Sorts the product list by name in the specified order and updates the 
adapter.
     * @param sortOrder The order in which to sort the products.
     */
    private fun sortProducts(sortOrder: SortOrder) {
        val sortedProductList = when (sortOrder) {
            SortOrder.ASC -> 
productListViewModel.getProductList().value?.sortByNameAsc()
            SortOrder.DESC -> 
productListViewModel.getProductList().value?.sortByNameDesc()
        }
        sortedProductList?.let {
            productAdapter.productList = it
            productAdapter.notifyDataSetChanged()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    // Declara el TAG en la parte superior de tu clase
    private val TAG = "onProductTypeItemClick"
    private var beforePosition = RecyclerView.NO_POSITION
    private var afterPosition = RecyclerView.NO_POSITION

    /**
     * Este método se llama cuando se hace clic en un ProductType en el 
RecyclerView.
     * Muestra un Toast con el nombre y la edad del usuario.
     */
    override fun onProductTypeItemClick(productType: ProductType) {
        // Crear el mensaje a mostrar en el Toast
        val message = "Nombre: ${productType.name}"

        // Mostrar un Toast con el mensaje
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()

        // Obtener la posición del registro seleccionado
        val position = productTypeAdapter.productTypeList.indexOf(productType)

        // Mostrar la posición en el Logcat
        Log.d(TAG, "XXXXXbeforePosition: $beforePosition")
        Log.d(TAG, "XXXXXPosition: $position")

        // Pintar el background de la posición seleccionada
        // 1. Obtener la vista de la tarjeta seleccionada
        val selectedViewHolder = 
rvProductTypes.findViewHolderForAdapterPosition(position)
        // 2. Obtener la vista de la tarjeta a modificar
        val selectedView = 
selectedViewHolder?.itemView?.findViewById<ConstraintLayout>(R.id.cl_product_background)
        // 3. Obtener la vista de la tarjeta anteriormente seleccionada
        val beforeViewHolder = 
rvProductTypes.findViewHolderForAdapterPosition(beforePosition)
        val beforeView = 
beforeViewHolder?.itemView?.findViewById<ConstraintLayout>(R.id.cl_product_background)

        // Cambiar el fondo de la tarjeta seleccionada
        selectedView?.setBackgroundResource(R.drawable.selected_item_background)

        // Reestablecer el fondo de la tarjeta anteriormente seleccionada
        beforeView?.setBackgroundResource(R.drawable.default_item_background)

        // Actualizar el valor de la posición anterior
        beforePosition = position
    }

    override fun onProductTypeIdItemClick(productTypeId: String) {
        Log.e("onProductTypeItemClick", "START 
onProductTypeIdItemClick_____________________________________________________________")
        Log.e("onProductTypeItemClick", "roductTypeId: $productTypeId")
        Toast.makeText(context, "productTypeId: $productTypeId", 
Toast.LENGTH_SHORT).show()

        rvProducts.adapter = productAdapter // deberías actualizar el adaptador 
de productos en lugar del de tipos de producto

        
productListViewModel.getProductsByCategory(productTypeId).observe(viewLifecycleOwner,
 { productList ->
            productAdapter.productList = productList
            productAdapter.notifyDataSetChanged()
        })

        Log.e(TAG, "rvProductTypes: ${rvProductTypes}")
        Log.e(TAG, "size: ${rvProductTypes.size}")
        Log.e("onProductTypeItemClick", "END 
onProductTypeIdItemClick_____________________________________________________________")
    }

    /**
     * Product
     * */
    override fun onProductItemClick(product: Product) {
        // Crear el mensaje a mostrar en el Toast
        val message = "Nombre: ${product.name}"

        // Mostrar un Toast con el mensaje
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()

        Log.e("onProductItemClick", "product ${product} ")  // id=null, 
name=Producto xxx1, description=Descripción del Producto 1, price=10.0, 
available=true, type=0001
    }

    override fun onProductIdItemClick(productId: String) {
        Log.e("onProductIdItemClick", "productId: $productId")
        Toast.makeText(context, "Producto Id: $productId", 
Toast.LENGTH_SHORT).show()
    }

}

Reply via email to