Kotlin 和 Android 的“没有足够的信息来推断 T 参数”

我试图在我的 Android 应用程序中使用 Kotlin: https://github.com/bidrohi/KotlinListView复制以下 ListView。

不幸的是,我得到了一个错误,我无法解决自己。 这是我的密码:

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)类型推断失败: 在 fun findViewById (p0: Int) : T 中没有足够的信息来推断参数 T! 请明确指定。

如果你能帮我,我会很感激的。

105600 次浏览

将您的代码更改为此。发生主要更改的位置用星号标记。

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 }**
}
}

您必须使用 API 级别26(或更高)。这个版本改变了 View.findViewById()的签名-见这里的 https://developer.android.com/about/versions/oreo/android-8.0-changes#fvbi-signature

因此,在 findViewById的结果不明确的情况下,需要提供类型:

1/更改

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

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

2/更改

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

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

注意,在2/中只需要强制转换,因为 row是可空的 也可以为空,或者如果你使 row不为空,它就不会被要求。

改变 findViewById api

Public View findViewById (int id) ;

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)

它的工作

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)

编码愉快!

我建议你使用 synthetics kotlin Android 扩展:

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

Https://antonioleiva.com/kotlin-android-extensions/

在您的例子中,代码将是这样的:

init {
this.label = row.label
}

就这么简单;)

在 android 12中,从代码中删除 作为,并将 model放在 getParcelableExtra前面的 < > 中。

改变

intent.getParcelableExtra("MyModel") as MyModel

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

我在使用 DataBindingUtil.setContentView(this,R.layout.activity_main)

出现这个错误是因为这里假定 return是与 layout_main(inflatted layout)相关联的绑定,所以我通过以下方法解决了这个错误:

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

因此,您的错误可能主要是在处理返回值时出现的。