Не в состоянии "findViewById" в Котлине. Получение ошибки " Ошибка вывода типа"


Я получаю следующую ошибку, когда я пытаюсь найти RecycleView по 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
    }
}
9 57

9 ответов:

попробуйте что-то вроде:

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

можно использовать Kotlin Android Extensions слишком для этого. Проверьте doc здесь.
С его помощью вы можете позвонить recycler_view прямо в коде.

Котлин Android Расширения:

  • в приложении gradle.build добавить apply plugin: 'kotlin-android-extensions'
  • в вашем классе добавить импорт для import kotlinx.android.synthetic.main.<layout>.* здесь <layout> - это имя вашего макета.
  • вот и все, можете звонить recycler_view прямо в код.

как это работает? Первый раз, когда вы звоните recycler_view вызов findViewById делается и cached.

вы находитесь на уровне API 26, где тип возврата findViewById теперь является общим T вместо View и поэтому можно сделать вывод. Вы можете увидеть соответствующий список изменений здесь.

так что вы должны быть в состоянии сделать это:

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

или такой:

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

обычно Kotlin может определить ваш тип, используя информацию, приведенную в скобках.

в этом случае он не может, поэтому вам придется указать его явно так

findViewById<RecyclerView>(R.id.recycler_view)

не совсем уверен в типе, хотя, но именно так вы должны указать его

Я хотел бы добавить, что, используя Анко, вы можете еще больше упростить свой код следующим образом:

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

на Kotlin мы можем получить идентификатор представления без использования findViewById синтаксис.

например, мы используем следующий макет, из которого мы получим идентификатор представления и выполним операцию

планировка

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

мы можем найти идентификатор представления, используя следующий код

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 синтаксис.

для получения дополнительной информации по этой теме, пожалуйста, обратитесь по этой ссылке : -Нажмите здесь

добавьте следующую строку в ваш код, что вы используете контроллер.

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

попробуйте это:

здесь 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
}

вы можете игнорировать присвоение идентификаторов переменным в kotlin. Вам просто нужно использовать плагин

вставьте это в ваш gradle

 apply plugin: 'kotlin-android-extensions'

и тогда вам не нужно назначать идентификаторы var, вы можете просто сделать это как

 recycler_view.setAdapter(youradapter);

код: другой способ сделать это.

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)


        }
    }

вам даже не нужно создавать объект с целью. Вы можете просто использовать идентификатор. Например, Котлин

recycle_view.adapter = adapter

это то же самое, что, Java

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