es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Llamando al método desde Fragment en el Adaptador de RecyclerView – la propiedad lateinit textView no ha sido inicializada.

Tengo una lista de elementos. Cuando deslizo uno de los elementos, quiero actualizar un textView en el Fragmento.

Uso un RecyclerView. En el adaptador, detecto cuando el usuario desliza algo, y luego trato de llamar a un método en el Fragmento para actualizar un TextView.

Sin embargo, cuando lo intento, se bloquea con “La propiedad TextView no se ha inicializado”. He intentado inicializar el TextView en el adaptador en su lugar, pero no creo que sea correcto y parece imposible ya que findViewById no funciona realmente en un adaptador ya que el TextView específico no está en el diseño de elementos, sino que se muestra en el diseño de Fragment (y debe ser así ya que no quiero que TextView esté en cada elemento individual).

Mi adaptador (simplificado):

class SwipeAdapter constructor(private val mCandidatesArrayList: ArrayList) : RecyclerView.Adapter<recyclerview.viewholder>() {

private val mSwipeFragment = SwipeFragment() // Aquí inicializo mi fragmento

fun createHelperCallback(): ItemTouchHelper.Callback {
    return object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
        override fun onMove(
            recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            return false
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
            val position = viewHolder.bindingAdapterPosition
            mSwipeFragment.updateTextView() //Esto lanza el error
        }
    }
}

}

Y mi Fragment (simplificado):

class SwipeFragment : Fragment() {
private lateinit var textView : TextView

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    //Inicializando el textView
    textView = root.findViewById(R.id.textview)
}

fun updateTextView() { 
    textView.setText("Hola") //estableciendo el texto
}

}</recyclerview.viewholder>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error “Propiedad LateInit TextView no ha sido inicializada” indica que la variable textView en SwipeFragment aún no ha sido inicializada. Esto sucede porque el método onCreateView donde se inicializa la variable textView aún no ha sido llamado en el punto donde se intentó actualizar el texto.

    Una posible solución es pasar una referencia de SwipeFragment al constructor de SwipeAdapter y almacenarlo como una variable miembro para ser usada posteriormente. De esta manera, se puede llamar al método updateTextView directamente en la instancia SwipeFragment, sin tener que crear una nueva SwipeFragment.

    Así es como puede modificar SwipeAdapter para tomar la instancia SwipeFragment como parámetro:

    class SwipeAdapter internal constructor(
        private val mCandidatesArrayList: ArrayList<swipecandidate>,
        private val mSwipeFragment: SwipeFragment
    ) :
    RecyclerView.Adapter<recyclerview.viewholder>() {
    
        //... Código del adaptador
    
        fun createHelperCallback(): ItemTouchHelper.Callback {
            return object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
                //... Código de retorno de llamada
    
                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
                    val position = viewHolder.bindingAdapterPosition
                    mSwipeFragment.updateTextView()
                }
            }
        }
    }
    

    Y así es como puede modificar el código de la actividad donde está creando SwipeAdapter:

    class MainActivity : AppCompatActivity() {
    
        private lateinit var mSwipeFragment: SwipeFragment
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // Inicialice la instancia SwipeFragment aquí
            mSwipeFragment = SwipeFragment()
    
            //... Otro código de inicialización
    
            // Cree la instancia SwipeAdapter y pase SwipeFragment como parámetro
            val swipeAdapter = SwipeAdapter(mCandidatesArrayList, mSwipeFragment)
    
            //... Otro código de configuración del adaptador
        }
    
        //... Más código de la actividad
    }
    

    De esta manera, SwipeAdapter puede llamar al método updateTextView directamente en la instancia SwipeFragment sin tener que depender de findViewById o crear una nueva instancia SwipeFragment.</recyclerview.viewholder>

Comments are closed.