在 Kotlin 中无法“findViewById”。收到错误“类型推断失败”
Posted
技术标签:
【中文标题】在 Kotlin 中无法“findViewById”。收到错误“类型推断失败”【英文标题】:Not able to "findViewById" in Kotlin. Getting error "Type inference failed" 【发布时间】:2017-12-10 13:10:53 【问题描述】:当我尝试通过 id 查找 RecycleView
时出现以下错误。
错误:- 类型推断失败:没有足够的信息来推断参数 T
代码:
class FirstRecycleViewExample : AppCompatActivity()
val data = arrayListOf<String>()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.first_recycleview)
val recycler_view = findViewById(R.id.recycler_view) as RecyclerView ///IN THIS LINE I AM GETTING THE ERROR
data.add("First Data")
data.add("Second Data")
data.add("Third Data")
data.add("Forth Data")
data.add("Fifth Data")
//creating our adapter
val adapter = CustomRecycleAdapter(data)
//now adding the adapter to recyclerview
recycler_view.adapter = adapter
【问题讨论】:
【参考方案1】:尝试类似:
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
您也可以使用Kotlin android Extensions
。检查文档here。
有了它,你可以直接在你的代码中调用recycler_view
。
Kotlin Android 扩展:
在您的应用程序中gradle.build
添加apply plugin: 'kotlin-android-extensions'
在您的课程中添加 import kotlinx.android.synthetic.main.<layout>.*
的导入,其中 <layout>
是您的布局文件名。
就是这样,您可以直接在代码中调用recycler_view
。
它是如何工作的?第一次调用recycler_view
时,对findViewById
的调用完成并缓存。
【讨论】:
在最新版本中,我收到警告要从 中删除类型。由于Android工作室强迫我在使用它时只使用钻石运算符<>
,所以它给出了错误。【参考方案2】:
您处于 API 级别 26,其中 findViewById
的返回类型现在是通用的 T
而不是 View
,因此可以推断。可以查看相关的更新日志here。
所以你应该能够做到这一点:
val recycler_view = findViewById<RecyclerView>(R.id.recycler_view)
或者这个:
val recycler_view: RecyclerView = findViewById(R.id.recycler_view)
【讨论】:
【参考方案3】:已弃用
在Kotlin
中,我们可以在不使用findViewById
语法的情况下获取视图的id。
例如,我们使用下面的布局,我们将获取视图的 id 并执行操作
布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<TextView
android:id="@+id/welcomeMessage"
android:layout_
android:layout_
android:layout_gravity="center"
android:text="Hello World!"/>
</FrameLayout>
我们可以通过以下代码找到视图的id
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
welcomeMessage.text = "Hello Kotlin!" ////WE ARE GETTING THE IDS WITHOUT USING THE FINDVIEWBYID syntax
怎么做?
为了能够使用它,您需要一个特殊的导入(我在下面写的那个),但 IDE 能够自动导入它。再简单不过了!
import kotlinx.android.synthetic.main.YOUR_LAYOUT_NAME.*/// HERE "YOUR_LAYOUT_NAME" IS YOUR LAYOUT NAME WHICH U HAVE INFLATED IN onCreate()/onCreateView()
我们需要在不使用findviewbyid
语法的情况下导入这个属性来获取视图的id。
有关此主题的更多信息,请参阅此链接:- Click here
更新
现在不推荐使用 kotlin-android-extensions ,而不是使用 kotlin 提供的绑定,我们现在可以使用 View-Binding 并且它的工作原理与上述解决方案相同,只是您需要使用在你的应用程序gradle下面
android
...
buildFeatures
viewBinding true
【讨论】:
绝妙的解决方案!帮了我很多! 使用这个解决方案有什么缺点吗?该解决方案看起来很棒,并且可以使代码更简洁。 @Ikdhruw 你也可以使用视图绑定,因为我已经更新了上面的解决方案【参考方案4】:通常 Kotlin 可以使用括号中提供的信息推断您的类型。
在这种情况下,它不能,所以你必须像这样明确指定它
findViewById<RecyclerView>(R.id.recycler_view)
虽然不太确定类型,但你应该这样指定它
我想补充一点,使用Anko,您可以进一步简化您的代码,如下所示:
val recycler_view : RecyclerView = find(R.id.recycler_view)
【讨论】:
【参考方案5】:为您的代码添加这一行作为您使用的控制器。
val tvHello = findViewById<TextView>(R.id.tvHello)
【讨论】:
【参考方案6】:您可以忽略在 kotlin 中为变量提供 id。你只需要使用一个插件
将其粘贴到您的 gradle 中
apply plugin: 'kotlin-android-extensions'
然后你不需要为var分配id,你可以这样做
recycler_view.setAdapter(youradapter);
【讨论】:
请提供拒绝投票的理由。【参考方案7】:无法访问像 OP 一样的 ui 组件,在 app gradle 中需要如下所示:
plugins
...
id 'kotlin-android-extensions'
即使在添加此行之后,android studio 仍然无法自动解析 kotlin 合成的导入,因此您可能需要使缓存无效并重新启动。
如果仍然无法正常工作,请根据视图手动导入
活动/片段视图:导入 kotlinx.android.synthetic.main.更新 - 2
如果您收到此信息警告 -
警告:“kotlin-android-extensions”Gradle 插件已弃用。
插件“kotlin-android-extensions”将被弃用。 因此,在您的应用程序 gradle 中添加以下内容
android
...
buildFeatures
viewBinding true
【讨论】:
【参考方案8】:试试这个:
这里bind
通用函数用于绑定视图。它的一般功能可以用于任何视图。
class MyActivity : AppCompatActivity()
private lateinit var recycler_view : RecyclerView
override fun onCreate(savedInstanceState: Bundle?)
...
recycler_view = bind(R.id.recycler_view)
fun <T : View> Activity.bind(@IdRes res : Int) : T
@Suppress("UNCHECKED_CAST")
return findViewById(res) as T
【讨论】:
请为您的代码添加解释。不鼓励仅使用代码回答。 已添加。 @WilliMentzel【参考方案9】:您甚至不必创建一个对象来使用视图执行操作。 你可以只使用id。例如, 科特林
recycle_view.adapter = adapter
等同于, Java
RecycleView recycle_view = (RecycleView) findViewById(recycle_view);
recycle_view.setAdapter(adapter);
【讨论】:
以上是关于在 Kotlin 中无法“findViewById”。收到错误“类型推断失败”的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin Android 视图绑定:findViewById vs Butterknife vs Kotlin Android Extension
Kotlin Android Extensions: 与 findViewById 说再见 (KAD 04) -- 更新版
Kotlin的android扩展:对findViewById说再见(KAD 04)