无法在Kotlin中“ findViewById”。出现错误“类型推断失败”


79

我尝试RecycleView按ID查找ID时遇到以下错误。

错误:- 类型推断失败:没有足够的信息来推断参数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
    }
}

Answers:


100

尝试类似:

val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)

您也可以使用Kotlin Android Extensions它。在此处检查文档。
有了它,您可以recycler_view直接在代码中调用。

Kotlin Android扩展:

  • 在您的应用中gradle.build添加apply plugin: 'kotlin-android-extensions'
  • 在您的课程中,添加import,import kotlinx.android.synthetic.main.<layout>.*其中<layout>布局的文件名在哪里。
  • 就是这样,您可以recycler_view直接在代码中调用。

它是如何工作的?第一次调用时recycler_view,将findViewById完成并缓存对的调用。


在最新版本中,我收到警告,请从<>中删除类型。由于Android Studio迫使我<>在使用它时仅使用菱形运算符,因此它给出了错误。
Asif Mushtaq

46

您的API级别为26,现在的返回类型findViewById是通用类型,T而不是View因此可以推断出来。您可以在此处查看相关的变更日志。

因此,您应该可以执行以下操作:

val recycler_view = findViewById<RecyclerView>(R.id.recycler_view)

或这个:

val recycler_view: RecyclerView = findViewById(R.id.recycler_view)

7

在其中Kotlin我们可以获取视图的ID,而无需使用 findViewById语法。

例如,我们使用以下布局,我们将获取视图的ID并执行操作

布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/welcomeMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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() 

我们需要导入此属性以获取视图的ID,而不使用findviewbyid语法。

有关此主题的更多信息,请参阅此链接:-单击此处


1
出色的解决方案!对我有很大帮助!
gundrabur

7

通常Kotlin可以使用方括号中提供的信息来推断您的类型。

在这种情况下,不能这样做,因此您必须像这样明确地指定它

findViewById<RecyclerView>(R.id.recycler_view)

虽然不是很确定类型,但是那是你应该如何指定它的

我想补充一点,使用Anko,您可以像下面这样进一步简化代码:

val recycler_view : RecyclerView =  find(R.id.recycler_view)


1

试试这个:

这里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
}

1
请在您的代码中添加说明。不鼓励仅用代码回答。
Willi Mentzel

1
添加。@WilliMentzel
Mehul Kabaria

0

您可以忽略给kotlin中的变量赋予id。您只需要使用一个插件

将此粘贴到您的gradle中

 apply plugin: 'kotlin-android-extensions'

然后您不需要为var分配ID,您可以像

 recycler_view.setAdapter(youradapter);

请提供拒绝投票的理由。
Anmol317

0

您甚至不必创建对象即可通过视图执行操作。您可以只使用ID。例如, 科特林

recycle_view.adapter = adapter

Java相同

RecycleView recycle_view = (RecycleView) findViewById(recycle_view);
recycle_view.setAdapter(adapter);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.