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.
Te sugiero que uses la extensión de Android de synthetics 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 sencillo como eso ;)
Esta funcionando
Nivel de API 25 o inferior use este
var et_user_name = findViewById(R.id.et_user_name) as EditTextAPI nivel 26 o superior use esto
val et_user_name: EditText = findViewById(R.id.et_user_name)¡Feliz codificación!
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 }** } }Debe utilizar el nivel de API 26 (o superior). Esta versión ha cambiado la firma de View.findViewById() ; consulte 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 para
val listView = findViewById<ListView>(R.id.list)
2/ Cambiar
this.label = row?.findViewById(R.id.label) as TextView para
this.label = row?.findViewById<TextView>(R.id.label) as TextView
Tenga en cuenta que en 2/ la conversión solo se requiere porque la row admite valores NULL. Si la label también fuera anulable, o si hizo que la row no fuera anulable, no sería necesaria.
Andoid O cambia la API findViewById de
vista pública findViewById (int id);
para
público final T findViewById (int id)
entonces, si su objetivo es API 26, puede cambiar
val listView = findViewById(R.id.list) como ListView
para
val listView = findViewById(R.id.list)
o
val listView: ListView = findViewById(R.id.list)