java.lang.NullPointerException: отсутствует необходимое представление с идентификатором:

Android Studio 3.6

в app/build.gradle:

android {
viewBinding.enabled = true

Вот мой xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/bluetoothBottonMainContainer"
        android:layout_width="0dp"
        android:layout_height="104dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <View
            android:id="@+id/viewPointNotSelect"
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:background="@drawable/circle_transparent"
            app:layout_constraintBottom_toBottomOf="@+id/separator"
            app:layout_constraintEnd_toStartOf="@+id/separator"
app:layout_constraintTop_toTopOf="parent" />

и еще один xml unclude prev. xml:

 <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/bottonContainer"
        android:layout_width="0dp"
        android:layout_height="104dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <include
            android:id="@+id/qrBottonContainer"
            layout="@layout/qr_bottom_container"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

вот моя деятельность:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = QrBluetoothSwipeActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
}

приложение создается и запускается. Приятно.

Теперь я двигаю id - android:id="@+id/bluetoothBottonMainContainer"

во внешний контейнер следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bluetoothBottonMainContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="104dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <View
            android:id="@+id/viewPointNotSelect"
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:background="@drawable/circle_transparent"
            app:layout_constraintBottom_toBottomOf="@+id/separator"
            app:layout_constraintEnd_toStartOf="@+id/separator"
            app:layout_constraintTop_toTopOf="parent" />

приложение построено, но при запуске я получаю ошибку выполнения в этой строке:

binding = QrBluetoothSwipeActivityBinding.inflate(layoutInflater)

ошибка:

10-25 11:11:51.290 E/AndroidRuntime(14128): FATAL EXCEPTION: main
10-25 11:11:51.290 E/AndroidRuntime(14128): Process: com.myproject.debug, PID: 14128
10-25 11:11:51.290 E/AndroidRuntime(14128): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myproject.debug/com.myproject.ui.actviity.QRBluetoothSwipeActivity}: java.lang.NullPointerException: Missing required view with ID: bluetoothBottonMainContainer
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread.-wrap11(ActivityThread.java)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.os.Handler.dispatchMessage(Handler.java:102)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.os.Looper.loop(Looper.java:148)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread.main(ActivityThread.java:5417)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at java.lang.reflect.Method.invoke(Native Method)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
10-25 11:11:51.290 E/AndroidRuntime(14128): Caused by: java.lang.NullPointerException: Missing required view with ID: bluetoothBottonMainContainer
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.myproject.databinding.BluetoothBottomContainerBinding.bind(BluetoothBottomContainerBinding.java:114)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.myproject.databinding.QrBluetoothSwipeActivityBinding.bind(QrBluetoothSwipeActivityBinding.java:76)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.myproject.databinding.QrBluetoothSwipeActivityBinding.inflate(QrBluetoothSwipeActivityBinding.java:62)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.myproject.databinding.QrBluetoothSwipeActivityBinding.inflate(QrBluetoothSwipeActivityBinding.java:52)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at com.myproject.ui.actviity.QRBluetoothSwipeActivity.onCreate(QRBluetoothSwipeActivity.kt:31)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.Activity.performCreate(Activity.java:6251)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
10-25 11:11:51.290 E/AndroidRuntime(14128):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
10-25 11:11:51.290 E/AndroidRuntime(14128):     ... 9 more
10-25 11:11:51.291 W/ActivityManager(  780):   Force finishing activity com.myproject.debug/com.myproject.ui.actviity.QRBluetoothSwipeActivity
10-25 11:11:51.307 I/Icing   (11529): Indexing done com.google.android.gms-apps

33 ответа

Если кто-то получает это с TabLayout и ViewBindingвключен, то вы могли установить идентификатор для. Удаление идентификатора из TabItem решил проблему для меня.

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

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

activity_layout.xml

<LinearLayout>
    <include android:id="@+id/widget1" layout="@layout/my_widget" />
</LinearLayout>

my_wideget.xml

<LinearLayout
    android:id="@+id/widget1">
</LinearLayout>

Остерегайтесь, если вы используете <merge>внутри вашего включенного XML-макета логика иная, как указано здесь:
Подробное изучение привязки представления Android

Если мы попытаемся дать этому идентификатор, привязка представления не будет генерировать идентификатор в классе привязки, поэтому мы не сможем получить доступ к представлению, как это было в случае обычного включения.
В этом случае у нас есть PlaceholderBinding, который является автоматически сгенерированным классом для placeholder.xml (наш <merge>макет файла). Мы должны назвать это bind() и передайте корневое представление макета, в который мы его включили.

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include layout="@layout/placeholder" />

</androidx.constraintlayout.widget.ConstraintLayout>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = FragmentOrderBinding.inflate(layoutInflater, container, false)
        placeholderBinding = PlaceholderBinding.bind(binding.root)
        placeholderBinding.tvPlaceholder.text = getString(R.string.please_wait)
        return binding.root
    }

Обновить

Это должно быть исправлено в последних бета-версиях и версиях Android Studio Carnary.

Тем не менее существует проблема при использовании привязки вида с элементами вкладок макета вкладки материала, о которой здесь сообщается и которая еще не исправлена.


Это ошибка в View Binding, о которой сообщается в системе отслеживания проблем в следующих местах.

Вы также можете получить эту ошибку, если неправильно привяжете ячейку к представлению в recyclerView. Если вы привяжете представление к неправильному макету, вы получите сообщение об ошибке о том, что оно не может найти ожидаемые дочерние представления.

Это ставило меня в тупик на долгое время.

Решение состоит в том, чтобы убедиться, что макет, который вы привязываете к представлению, совпадает с макетом ViewBinding.

Вам следует удалить идентификатор TabItem и использовать API TabLayout для получения элемента. Этот способ обхода работает, если вы используете Material Design.

проверьте это: ответ Github

В моем случае в другом модуле был другой файл с таким же именем.

У меня был item_view.xml в модуле A и item_view.xml в модуле B, поэтому привязка данных не могла их различить.

Я изменил имя одного из них, и это исправлено.

В моем случае я удалил идентификатор внутри включенного макета, и он работает правильно!

main.xml

    <RelativeLayout>   
    ....
    <include
        include="@layout/included_layout"   
        android:id="@+id/view_included_layout"/>
    </RelativeLayout>

include_layout.xml

`   <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/top_level_layout">  <!-- Remove this id -->    
        ....
    </LinearLayout>
`

Моя версия Android Studio - 3.6.2, а версия build.gradle - 3.6.1

Решение - удалить идентификатор основного контейнера. И поместите в другой контейнер внутри родителя.

1.- Макет

    <include
    android:id="@+id/example"
    layout="@layout/account_current_payment_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
    

2.- Включить макет

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/example2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent">
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Это происходит со мной прямо сейчас. Я просто заметил, что это произошло потому, что в моих файлах xml их можно вызывать: Activity_main.xml / Activity_other.xml. У меня был виджет (в данном случае кнопка) с тем же идентификатором (+id / bttNext)

(это означает, что у activity_main.xml и Activity_other раньше была кнопка с одинаковым +id)

как только я тестирую свое приложение на устройстве:

java.lang.NullPointerException: отсутствует необходимое представление с идентификатором:

появившийся

как только я изменил кнопку + id второй активности (скажем, переименовал bttNext1) aspp работал нормально

Подводя итог: избегайте использования одного и того же идентификатора в кнопках (и других виджетах), не имеет значения, если они находятся в разных действиях

Я пробовал много способов, но все не сработало.

Наконец, проблема в том, что в другом модуле есть XML с таким же именем.

просто удалите каталог .gradle и активируйте кеши / перезапустите проект, сохраните резервную копию проекта. Я столкнулся с той же проблемой, решенной этим методом.

Для меня проблема заключалась в том, что я все еще использовал версию Android 3.x, но использовал новую версию Gradle 4.0.0.

Нажал "О программе-> Проверить наличие обновлений", обновил Android Studio, и ошибки больше нет.

Я встречаю ту же ошибку. Чтобы избежать этой ошибки, вы можете добавить представление оболочки в свой "внешний контейнер".

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/bluetoothBottonMainContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="104dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <View
            android:id="@+id/viewPointNotSelect"
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:background="@drawable/circle_transparent"
            app:layout_constraintBottom_toBottomOf="@+id/separator"
            app:layout_constraintEnd_toStartOf="@+id/separator"
            app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Я получал ошибку, потому что в моем случае mainappиmoduleтакая же планировка(layout_calling_waiting) с разными видами, которые не удалось найти в макете приложения. Таким образом, ошибка waas давала.

Получил эту проблему с пользовательским представлением, где ошибочно взят this вместо того super

      constructor(context: Context, attrs: AttributeSet?) : this(context,attrs) { //<-Change this to super

}

Эта ошибка также может произойти, если вы по ошибке используете XML-макет для фрагмента, но используете другой для привязки. Я делал, когда обнаружил ошибку

      class LoginFragment :Fragment(R.layout.login_fragment) { 
private val binding by viewBinding(LoginFragmentNewBinding::bind)//here I am referring to a new xml file called login_fragment_new which is different from the one in the Fragment's constructor (i.e login_fragment)
}

и с помощью того же файла xml исправил это для меня.

Я столкнулся с той же проблемой, и я решил ее, удалив эту строку в макете.

      tools:context=".ui.SplashScreenActivity

В моем случае эта проблема была связана с одинаковыми именами файлов xml в разных модулях.

Почему возникла проблема:

У меня было 2 файла xml с одинаковым именем (item_tag.xml) в разных модулях (app,landing). Компилятор не знает, какой из них нужно использовать, и я получил ошибку во время выполнения (каждый раз, когда я открывал экран с этимbinding).

Решение:

Я переименовал файл xml, и один из них сталitem_landing_tag.xml(и был сгенерированItemLandingTagBindingкласс вместоItemTagBinding).

Надеюсь, это поможет кому-то :)

Get RootView() возвращает включенный макет и может вносить в него изменения

Для моей базы my_main_layout.xml было -

      <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

  <ScrollView style="@style/ScrollViewContainerStyle">

    <include
        android:id="@+id/include_1"
        layout="@layout/layout"></include>
    
    <include
        android:id="@+id/include_1"
        layout="@layout/layout"></include>
    
    <include
        android:id="@+id/include_1"
        layout="@layout/layout"></include>
    </include></layout>

 </ScrollView>

И мой включенный layout.xml было -

      <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
    android:id="@+id/tv_title"
    tools:text="This is a tile" />
</LinearLayout>

Я просто решил свою проблему, обернув ее <layout> -

      <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:visibility="visible">
<TextView
    android:id="@+id/tv_title"
    tools:text="This is a tile" />
</LinearLayout>
</layout>

Решил это с помощью: Invalidate Caches and Clean Project.
В моем случае я скопировал некоторые виджеты из одного макета в другой, после чего изменил идентификаторы (чтобы идентификаторы не повторялись).
Отладочная сборка работала корректно, но при попытке запустить выпускную сборку выдавалось исключение.

Может быть уже поздно, но. Для всех, кто сталкивался с этим вопросом. Я сначала попробовал все, что видел здесь, но безуспешно. Я обнаружил, что использование идентификаторов кейсов змейки решает проблему. У меня был идентификатор tabContainer, и он вызывал NPE. Переименование его в tab_container устранило ошибку для меня.

У меня тоже была эта проблема, но, по-видимому, это было именно то, на что указывала ошибка, нулевой указатель, представление было «потреблено» моим пользовательским контейнером представления, который принимал только первое дочернее представление после infaltion и следующее представление с идентификатором, указанным ошибка была удалена из иерархии, поэтому программа просмотра не могла их связать.

Та же проблема, но только в пользовательской активности просмотра я установил правильные атрибуты.

В котлине:

class CanvasNew @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null):View(context,attrs){

Мое решение было похожим, но немного другим, у меня было включение в мой диалог

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:minHeight="@dimen/complete_programme_min_height"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<include
    android:id="@+id/include" <!-- Removing this line worked -->
    layout="@layout/background_triangle_medium_violet_gradient" />

Решение может быть:

      init {
    id = context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.id)).let { typedArray ->
        val value = typedArray.getResourceId(0, View.NO_ID)
        typedArray.recycle()
        value
    }
    val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    binding = AnyBinding.inflate(inflater, this)
}

У меня были разные макеты для телефонов и планшетов, и в одном из макетов отсутствовал идентификатор представления, его добавление решило проблему.

Вsrc/main/res/layout-sw600dp/fragment_satellite.xmlУ меня была точка зрения:

      ....
<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginBottom="@dimen/row005"
        />
....

но не было представления с таким же идентификатором@+id/container, поэтому добавив его вsrc/main/res/layout/fragment_satellite.xmlрешил проблему.

Запустите свой код с противоположным { minifyEnabled }

Если так сейчас:

      debug {
      minifyEnabled false
}

Затем запустите так:

      debug {
      minifyEnabled true
}

Или наоборот.

Другие вопросы по тегам