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

我想在我的Android应用程序中使用Kotlin复制以下ListView: 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)types推断失败:没有足够的信息来推断参数T在fun findViewById(p0:Int):T! 请明确指定。

我会很感激任何帮助,我可以得到。

您必须使用API​​级别26(或以上)。 这个版本改变了View.findViewById()的签名 – 请参阅https://developer.android.com/preview/api-overview.html#fvbi-signature

所以在你的情况下, findViewById的结果是不明确的,你需要提供的types:

1 /变化

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

val listView = findViewById(R.id.list)

2 /更改

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

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

请注意,在2 / cast只是因为row是可以为空的。 如果label也是可空的,或者如果你使row不可空,那就不需要了。

Andoid O更改find​​ViewById api

public查看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)

将您的代码更改为此。 发生主要变化的地方标有星号。

 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(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(R.id.label) as TextView }** } } 

它的工作

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 } 

就如此容易 ;)