Не удалось «findViewById» в Котлине. Ошибка "Ошибка определения типа"


80

Когда я пытаюсь найти 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
    }
}

Ответы:


101

Попробуйте что-нибудь вроде:

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

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

Расширения Kotlin для Android:

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

Как это работает? При первом вызове recycler_viewвызов findViewByIdвыполняется и сохраняется в кэше .


В последней версии я получаю предупреждение об удалении типа из <>. Поскольку Android-студия заставляет меня использовать только алмазный оператор, <>когда я его использую, он выдает ошибку.
Асиф Муштак

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мы можем получить идентификатор представления без использования 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синтаксиса.

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


1
Гениальное решение! Мне очень помогли!
gundrabur

7

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

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

findViewById<RecyclerView>(R.id.recycler_view)

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

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

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


2

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

Вставьте это в свой градиент

 apply plugin: 'kotlin-android-extensions'

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

 recycler_view.setAdapter(youradapter);

Укажите причину, по которой проголосовали против.
Anmol317 06

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
Пожалуйста, добавьте пояснение к вашему коду. Не рекомендуется использовать только код.
Вилли Ментцель

1
добавлен. @WilliMentzel
Mehul Kabaria 06

0

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

recycle_view.adapter = adapter

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

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

0

Не удалось получить доступ к компонентам пользовательского интерфейса, например, OP выглядит так, как показано ниже, внутри приложения gradle:

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

Несмотря на то, что после добавления этой строки студия Android все еще не смогла автоматически разрешить импорт для синтетики kotlin, поэтому вам может потребоваться аннулировать кеш и перезапустить.

Если все еще не работает, импортируйте вручную в зависимости от просмотров

  • вид активности / фрагмента: import kotlinx.android.synthetic.main. <your_activity_view>. *
  • обычные представления: import kotlinx.android.synthetic.main. <your_layout_view> .view. *

Обновление - 2

Если вы получаете это информационное предупреждение -

Предупреждение: плагин Gradle 'kotlin-android-extensions' устарел.

плагин kotlin-android-extensions будет устаревшим. Так что добавьте ниже в свое приложение gradle

android {
    ...
    buildFeatures {
        viewBinding true
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.