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.
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+(.+)
confindViewById<$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
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!
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 😉
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")!!
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.
puedes intentar cambiar
this.label = ... as TextView
athis.label = row?.findViewById<TextView>
y hazlo análogamente paraval 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