Tengo una aplicación que se supone que abre un cuadro de diálogo emergente cuando el usuario hace clic en el elemento, pero se bloquea cuando se hace clic. Comenzó a fallar cuando agregué la línea (esto como AppCompatActivity).supportFragmentManager . ¡Aquí está el código para el adaptador, ayuda por favor!
class CategoryAdapter(var context: Context ,private val workoutList: ArrayList<CategoryModel?>): RecyclerView.Adapter<CategoryAdapter.ViewHolder>() { inner class ViewHolder(private val itemBinding: WorkoutsListRowBinding): RecyclerView.ViewHolder(itemBinding.root) { fun bindItem(item: CategoryModel, position: Int) { itemBinding.workoutItem.text = item.name (this as AppCompatActivity).supportFragmentManager if (position % 2 == 0) { itemBinding.workoutItem.setBackgroundColor(Color.parseColor("#072227")) itemBinding.workoutItem.setTextColor(Color.parseColor("#FFFFFF")) } else { itemBinding.workoutItem.setBackgroundColor(Color.parseColor("#FFFFFF")) itemBinding.workoutItem.setTextColor(Color.parseColor("#000000")) } itemBinding.workoutItem.setOnClickListener{ var dialog = CustomDialogFragment() dialog.show(supportFragmentManager, "customDialog") Snackbar.make(itemView, "${item.name}", Snackbar.LENGTH_SHORT).show() } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val itemBinding = WorkoutsListRowBinding .inflate(LayoutInflater.from(parent.context), parent, false) return ViewHolder(itemBinding) } override fun getItemCount() = workoutList.size override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bindItem(workoutList[position]!!, position) } }Aquí está el código para el fragmento.
class WorkoutListFragment : Fragment() { private lateinit var categoryAdapter: CategoryAdapter private lateinit var binding: FragmentWorkoutListBinding var workoutList = ArrayList<CategoryModel?>() var workoutDAO: CategoryDAO = CategoryDaoArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentWorkoutListBinding.inflate(inflater, container, false) val view = binding.root populateList() categoryAdapter = CategoryAdapter(requireActivity()!!.getApplicationContext() ,workoutList) binding.workoutListView.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) binding.workoutListView.adapter = categoryAdapter return view } fun populateList() { workoutList = workoutDAO.getWorkouts()!! } }Así como el código para el cuadro de diálogo personalizado.
class CustomDialogFragment: DialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val rootView: View = inflater.inflate(R.layout.custom_popup_dialogue, container, false) return rootView } }Mensajes de error encontrados en el logcat
2022-02-09 01:32:18.137 7210-7210/com.mobdeve.s11.mco2.deleon.coronel.grnd E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mobdeve.s11.mco2.deleon.coronel.grnd, PID: 7210 java.lang.ClassCastException: com.mobdeve.s11.mco2.deleon.coronel.grnd.adapters.CategoryAdapter$ViewHolder cannot be cast to androidx.appcompat.app.AppCompatActivity at com.mobdeve.s11.mco2.deleon.coronel.grnd.adapters.CategoryAdapter$ViewHolder.bindItem(CategoryAdapter.kt:26) at com.mobdeve.s11.mco2.deleon.coronel.grnd.adapters.CategoryAdapter.onBindViewHolder(CategoryAdapter.kt:57) at com.mobdeve.s11.mco2.deleon.coronel.grnd.adapters.CategoryAdapter.onBindViewHolder(CategoryAdapter.kt:20) at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065) at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107) at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114) at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303) at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627) at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587) at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665) at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134) at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851) at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at androidx.viewpager.widget.ViewPager.onLayout(ViewPager.java:1775) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585) at android.widget.LinearLayout.onLayout(LinearLayout.java:1494) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585) at android.widget.LinearLayout.onLayout(LinearLayout.java:1494) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) 2022-02-09 01:32:18.137 7210-7210/com.mobdeve.s11.mco2.deleon.coronel.grnd E/AndroidRuntime: at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at com.android.internal.policy.DecorView.onLayout(DecorView.java:727) at android.view.View.layout(View.java:17651) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6338) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874) at android.view.Choreographer.doCallbacks(Choreographer.java:686) at android.view.Choreographer.doFrame(Choreographer.java:621) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6138) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)this as AppCompatActivity no tiene sentido. Su adaptador no es una actividad, por lo que no puede convertir su adaptador como una actividad y esto provocará un bloqueo de ClassCastException.
Si necesita acceder a su administrador de fragmentos en esta clase, debe agregarlo como una propiedad.
class CategoryAdapter( val context: Context, private val workoutList: List<CategoryModel>, private val fragmentManager: FragmentManager ): RecyclerView.Adapter<CategoryAdapter.ViewHolder>() { //... }Entonces puedes usarlo en esta clase libremente. El fragmento que instancia esta clase puede pasar el administrador de fragmentos al constructor, así:
categoryAdapter = CategoryAdapter(requireActivity(), workoutList, requireActivity().supportFragmentManager)Sin embargo, siguiendo el concepto OOP de separación de preocupaciones , creo que una mejor estrategia es exponer una devolución de llamada para que la use su Actividad. Un adaptador de vista no debería tener que saber sobre fragmentos específicos y transacciones de fragmentos, etc.
class CategoryAdapter( val context: Context, private val workoutList: List<CategoryModel>, private val onItemClicked: (CategoryModel)->Unit ): RecyclerView.Adapter<CategoryAdapter.ViewHolder>() { //... fun bindItem(item: CategoryModel, position: Int) { itemBinding.workoutItem.text = item.name if (position % 2 == 0) { itemBinding.workoutItem.setBackgroundColor(Color.parseColor("#072227")) itemBinding.workoutItem.setTextColor(Color.parseColor("#FFFFFF")) } else { itemBinding.workoutItem.setBackgroundColor(Color.parseColor("#FFFFFF")) itemBinding.workoutItem.setTextColor(Color.parseColor("#000000")) } itemBinding.workoutItem.setOnClickListener{ onItemClicked(item) } } } //...y luego en su Fragmento que crea una instancia del adaptador, puede pasar un oyente que hace que la transacción del fragmento funcione, así:
categoryAdapter = CategoryAdapter(requireActivity(), workoutList) { clickedItem -> val dialog = CustomDialogFragment() dialog.show(requireActivity().supportFragmentManager, "customDialog") Snackbar.make(itemView, "${item.name}", Snackbar.LENGTH_SHORT).show() }Tenga en cuenta que cambié ArrayList a List. Una ArrayList implica que se mutará, pero la mutación de una Lista que está siendo utilizada por un adaptador provocará errores y bloqueos.