“No hay suficiente información para inferir el parámetro T” con Kotlin y Android

6 minutos de lectura

avatar de usuario
Timo Güntner

Estoy tratando de replicar el siguiente ListView en mi aplicación de Android usando Kotlin: https://github.com/bidrohi/KotlinListView.

Desafortunadamente, recibo un error que no puedo resolver por mí mismo. Aquí está mi código:

MainActivity.kt:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val listView = findViewById(R.id.list) as ListView
    listView.adapter = ListExampleAdapter(this)
}

private class ListExampleAdapter(context: Context) : BaseAdapter() {
    internal var sList = arrayOf("Eins", "Zwei", "Drei")
    private  val mInflator: LayoutInflater

    init {
        this.mInflator = LayoutInflater.from(context)
    }

    override fun getCount(): Int {
        return sList.size
    }

    override fun getItem(position: Int): Any {
        return sList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
        val view: View?
        val vh: ListRowHolder

        if(convertView == null) {
            view = this.mInflator.inflate(R.layout.list_row, parent, false)
            vh = ListRowHolder(view)
            view.tag = vh
        } else {
            view = convertView
            vh = view.tag as ListRowHolder
        }

        vh.label.text = sList[position]
        return view
    }
}

private class ListRowHolder(row: View?) {
    public val label: TextView

    init {
        this.label = row?.findViewById(R.id.label) as TextView
    }
}
}

Los diseños son exactamente como aquí: https://github.com/bidrohi/KotlinListView/tree/master/app/src/main/res/layout

El mensaje de error completo que recibo es este:
Error:(92, 31) Error en la inferencia de tipo: No hay suficiente información para inferir el parámetro T en fun findViewById(p0: Int): T! Por favor, especifíquelo explícitamente.

Agradecería cualquier ayuda que pueda obtener.

  • puedes intentar cambiar this.label = ... as TextView a this.label = row?.findViewById<TextView> y hazlo análogamente para val listView = ...? Avíseme si esto funciona para que pueda hacer que esta sea una respuesta adecuada en ese caso.

    – Christian Bruggemann

    23 de julio de 2017 a las 16:04

  • ¿Qué línea da error?

    – vodán

    23 de julio de 2017 a las 16:37

  • ¿Puedes demostrar el problema con un ejemplo más pequeño?

    – vodán

    23 de julio de 2017 a las 16:37

  • @ChristianBrüggemann Así: i.imgur.com/ZeWKjt5.png y esto: i.imgur.com/Can7w0p.png ? Con sus ediciones ahora hay estos errores: i.imgur.com/qqPAjrL.png

    – Timo Güntner

    23 de julio de 2017 a las 17:37

  • Pruebe esto this.label = fila?.findViewById(R.id.label) como TextView

    – Alf Moh

    23 de julio de 2017 a las 18:27

avatar de usuario
nmw

Debe utilizar el nivel de API 26 (o superior). Esta versión ha cambiado la firma de View.findViewById() – mira aquí https://developer.android.com/about/versions/oreo/android-8.0-changes#fvbi-signature

Entonces, en su caso, donde el resultado de findViewById es ambiguo, debe proporcionar el tipo:

1/ Cambiar

val listView = findViewById(R.id.list) as ListView a

val listView = findViewById<ListView>(R.id.list)

2/ Cambiar

this.label = row?.findViewById(R.id.label) as TextView a

this.label = row?.findViewById<TextView>(R.id.label) as TextView

Tenga en cuenta que en 2/ el yeso solo es necesario porque row es anulable. Si label
era anulable también, o si hizo row no anulable, no sería necesario.

  • He aquí cómo resolver esto por lotes: Abra el Reemplazar en ruta cuadro de diálogo (Ctrl+Shift+R) y marque la casilla de expresión regular. Reemplazar findViewById\((.+?)\)\s+as\s+(.+) con findViewById<$2>\($1\) y ejecute el reemplazo en todos los archivos. Resolvió casi todos mis errores.

    -Gustav Karlsson

    7 de octubre de 2017 a las 8:17


  • ¿Por qué es suficiente en Java inferir el tipo de vista de forma predeterminada y no es suficiente en Kotlin? findViewById(R.id.tabLayout).setOnClickListener(v-> Log.d(TAG, "login: ")); esto está bien para Java.

    – Actividad principal

    31 de enero de 2018 a las 17:09

  • findViewById\((.+?)\)\s+as\s+([A-Za-z0-9?]+) funciona mejor para mí. Evita que un código de una línea no haya terminado @GustavKarlsson

    – usuario3680200

    24 de febrero de 2019 a las 18:24

  • El enlace no dice eso.

    – Alston

    9 de noviembre de 2019 a las 9:08

avatar de usuario
Trinea

Andoid O cambia la API findViewById de

vista pública findViewById (int id);

a

público final T findViewById (int id)

entonces, si su objetivo es API 26, puede cambiar

val listView = findViewById(R.id.list) como ListView

a

val listView = findViewById(R.id.list)

o

val listView: ListView = findViewById(R.id.list)

Esta funcionando

Nivel de API 25 o inferior use este

    var et_user_name = findViewById(R.id.et_user_name) as EditText

API nivel 26 o superior use esto

    val et_user_name: EditText = findViewById(R.id.et_user_name)

¡Feliz codificación!

avatar de usuario
alf moh

Cambie su código a esto. Donde ocurrieron los principales cambios están marcados con asteriscos.

package com.phenakit.tg.phenakit

import android.content.Context
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v7.app.AppCompatActivity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ListView
import android.widget.TextView

public class MainActivity : AppCompatActivity() {

    private var mTextMessage: TextView? = null

    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                mTextMessage!!.setText(R.string.title_home)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_dashboard -> {
                mTextMessage!!.setText(R.string.title_dashboard)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_notifications -> {
                setContentView(R.layout.activity_list_view)
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mTextMessage = findViewById(R.id.message) as TextView?
        val navigation = findViewById(R.id.navigation) as BottomNavigationView
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)


        **val listView = findViewById<ListView>(R.id.list)**



        **listView?.adapter = ListExampleAdapter(this)**
    }

    private class ListExampleAdapter(context: Context) : BaseAdapter() {
        internal var sList = arrayOf("Eins", "Zwei", "Drei")
        private  val mInflator: LayoutInflater

        init {
            this.mInflator = LayoutInflater.from(context)
        }

        override fun getCount(): Int {
            return sList.size
        }

        override fun getItem(position: Int): Any {
            return sList[position]
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
            val view: View?
            val vh: ListRowHolder

            if(convertView == null) {
                view = this.mInflator.inflate(R.layout.list_row, parent, false)
                vh = ListRowHolder(view)
                view.tag = vh
            } else {
                view = convertView
                vh = view.tag as ListRowHolder
            }

            vh.label.text = sList[position]
            return view
        }
    }

    private class ListRowHolder(row: View?) {
        public var label: TextView

        **init { this.label = row?.findViewById<TextView?>(R.id.label) as TextView }**
    }
}

Te sugiero que uses synthetics Extensión de Android Kotlin:

https://kotlinlang.org/docs/tutorials/android-plugin.html

https://antonioleiva.com/kotlin-android-extensiones/

En tu caso el código será algo como esto:

init {
   this.label = row.label
}

Tan simple como eso 😉

avatar de usuario
fazal hussain

En android 12 eliminar como de su código y poner su model en delante de getParcelableExtra.

cambio

intent.getParcelableExtra("MyModel") as MyModel

a

intent.getParcelableExtra `<MyModel>` ("MyModel")!!

avatar de usuario
shivlal kumavat

Encontré este error mientras usaba el
DataBindingUtil.setContentView(this,R.layout.activity_main)

El error vino aquí porque se supone que esto return la unión asociada con el layout_main(inflatted layout) así que resolví este error por:

ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main)

Por lo tanto, su error puede deberse principalmente al manejo del valor de retorno. Intente configurar eso y verifique.

¿Ha sido útil esta solución?