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

时间:2017-07-06 13:30:20

标签: android android-layout kotlin type-inference

当我尝试按ID找到RecycleView时,我收到以下错误。

  

错误: -   类型推断失败:没有足够的信息来推断参数 T

Error

代码:

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

10 个答案:

答案 0 :(得分:85)

尝试类似:

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

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

Kotlin Android Extensions:

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

它是如何工作的?第一次拨打recycler_view时,系统会调用findViewById缓存

答案 1 :(得分:46)

您在API级别26,其中findViewById的返回类型现在是通用T而不是View,因此可以推断。您可以看到相关的更改日志here

所以你应该能够做到这一点:

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

或者这个:

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

答案 2 :(得分:6)

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

在这种情况下,它不能这样你必须像这样明确地指定它

findViewById<RecyclerView>(R.id.recycler_view)

虽然不太确定类型但是你应该如何指定它

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

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

答案 3 :(得分:5)

Kotlin中,我们可以在不使用findViewById语法的情况下获取视图的ID。

例如,我们使用以下布局,我们将获取视图的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语法。

有关此主题的详细信息,请参阅以下链接: - Click here

答案 4 :(得分:3)

为您的代码添加此行,无论您使用的是控制器。

val tvHello = findViewById<TextView>(R.id.tvHello)

答案 5 :(得分: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
}

答案 6 :(得分:0)

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

将其粘贴到您的游戏中

 apply plugin: 'kotlin-android-extensions'

然后你不需要为var分配id,你可以像

一样
 recycler_view.setAdapter(youradapter);

答案 7 :(得分:0)

代码:另一种方法。

class KotlinActivity : AppCompatActivity() {


        var recycler_view: RecyclerView? = null

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_kotlin)

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


        }
    }

答案 8 :(得分:0)

您甚至不必创建一个对象来处理视图。 你可以使用id。例如, 的科特林

recycle_view.adapter = adapter

相同, 的爪哇

RecycleView recycle_view = (RecycleView) findViewById(recycle_view);
recycle_view.setAdapter(adapter);

答案 9 :(得分:0)

无法访问像op face这样的ui组件时,需要在应用gradle中添加以下内容:

plugins {
    ...
    id 'kotlin-android-extensions'
}

即使添加了这一行,android studio仍然无法自动解析kotlin合成物的导入,因此您可能需要使缓存无效并重新启动。

如果仍然无法正常工作,则根据视图手动导入

    活动/片段视图:导入 kotlinx.android.synthetic.main。<您的活动视图>。*
  • 普通意见: 导入kotlinx.android.synthetic.main。 .view。*

更新-2

如果您收到此信息警告-

警告:不建议使用“ kotlin-android-extensions” Gradle插件。

插件'kotlin-android-extensions'将被弃用。 因此,在您的应用程序gradle中添加以下内容

android {
    ...
    buildFeatures {
        viewBinding true
    }
}