"Недостаточно информации для вывода параметра T" с помощью Kotlin и Android
Я пытаюсь воспроизвести следующий ListView в своем приложении для Android с помощью Kotlin: https://github.com/bidrohi/KotlinListView.
К сожалению, я получаю сообщение об ошибке, которое я не могу решить самостоятельно.
Здесь мой код:
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
}
}
}
Макеты точно такие же: https://github.com/bidrohi/KotlinListView/tree/master/app/src/main/res/layout
Полное сообщение об ошибке, которое я получаю, следующее:
Ошибка: (92, 31) Ошибка ввода типа: недостаточно информации для вывода параметра T в fun findViewById (p0: Int): T!
Пожалуйста, укажите это явно.
Буду признателен за любую помощь, которую я могу получить.
Ответы
Ответ 1
Вы должны использовать уровень API 26. Эта версия изменила подпись View.findViewById()
- см. здесь https://developer.android.com/preview/api-overview.html#fvbi-signature
Итак, в вашем случае, когда результат findViewById
неоднозначен, вам нужно указать тип:
1/Измените
val listView = findViewById(R.id.list) as ListView
to
val listView = findViewById<ListView>(R.id.list)
2/Измените
this.label = row?.findViewById(R.id.label) as TextView
to
this.label = row?.findViewById<TextView>(R.id.label) as TextView
Обратите внимание, что в 2/приведение требуется только потому, что row
имеет значение NULL. Если label
тоже недействителен, или если вы сделали row
недействительным, это не требуется.
Ответ 2
Andoid O изменить findViewById api из
public Просмотр findViewById (int id);
to
public final T findViewById (int id)
поэтому, если вы нацелены на API 26, вы можете изменить
val listView = findViewById (R.id.list) как ListView
к
val listView = findViewById (R.id.list)
или
val listView: ListView = findViewById (R.id.list)
Ответ 3
Измените свой код на это. Там, где произошли основные изменения, отмечены звездочками.
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)
[email protected] true
}
R.id.navigation_dashboard -> {
mTextMessage!!.setText(R.string.title_dashboard)
[email protected] true
}
R.id.navigation_notifications -> {
setContentView(R.layout.activity_list_view)
[email protected] 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 }**
}
}
Ответ 4
Работает
API-уровень 25 или ниже использует этот
var et_user_name = findViewById(R.id.et_user_name) as EditText
Уровень API 26 или выше используется
val et_user_name: EditText = findViewById(R.id.et_user_name)
Счастливое кодирование!
Ответ 5
Я предлагаю вам использовать расширение synthetics
kotlin для Android:
https://kotlinlang.org/docs/tutorials/android-plugin.html
https://antonioleiva.com/kotlin-android-extensions/
В вашем случае код будет примерно таким:
init {
this.label = row.label
}
Проще всего:)