Android studio findviewbyid возвращает null

findViewByID возвращает null

Прежде всего: да, я читал все другие темы по этой теме. И не только с этого сайта . (видите ли, я немного расстроен)

Большинство из них дает совет использовать android:id вместо просто id в файле XML. Я сделал.

От других я узнал, что View.findViewById работает иначе, чем Activity.findViewById . Я тоже справился с этим.

В своем location_layout.xml я использую:

В своей деятельности я делаю:

И в моем пользовательском классе просмотра:

Который возвращает null . При этом мое действие работает нормально. Возможно, это из-за различий Activity.findViewById и View.findViewById . Итак, я сохранил контекст, переданный конструктору таможенного представления локально, и попробовал:

Который также вернул null .

Затем я изменил свое собственное представление, чтобы расширить ViewGroup вместо View , и изменил location_layout.xml , чтобы позволить TextView быть прямым потомком моего настраиваемого представления, так что View.findViewById должен работать должным образом. Сюрприз: ничего не решило.

Так что, черт возьми, я делаю не так?

Буду признателен за любые комментарии.

29 ответов

Возможно, потому что вы звоните слишком рано. Подождите, пока onFinishInflate() . Вот пример проекта, демонстрирующий пользовательский View доступ к его содержимому.

Возможно, вы звоните findViewById перед звонком setContentView ? В этом случае попробуйте позвонить findViewById ПОСЛЕ звонка setContentView

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

FindViewById может иметь значение null, если вы вызываете неправильный суперконструктор в настраиваемом представлении. Тег ID является частью attrs, поэтому, если вы игнорируете attrs, вы удаляете идентификатор.

Это было бы неправильно

Наряду с классическими причинами, упомянутыми в другом месте:

  • Убедитесь, что вы звонили setContentView() до findViewById()
  • Убедитесь, что нужный id находится в представлении или макете, которое вы предоставили setContentView()
  • Убедитесь, что id случайно не дублируется в разных макетах.

Есть один, который я нашел для пользовательских представлений в стандартных макетах, что противоречит документации:

    Замените каждое настраиваемое представление на FrameLayout с теми же свойствами макета, которые вы хотели бы иметь в настраиваемом представлении. Дайте ему соответствующий id , скажем frame_for_custom_view .

который помещает пользовательский вид в рамку.

В моем случае в моем проекте было 2 активности: main.xml и main2.xml . С самого начала main2 был копией main , и все работало хорошо, пока я не добавил новый TextView в main2 , поэтому R.id.textview1 стал доступен для остальная часть приложения. Затем я попытался получить его стандартным вызовом:

И он всегда был нулевым. Оказалось, что в конструкторе onCreate я создавал не main2 , а другой. Я имел:

Я заметил это после того, как приехал сюда, на сайт.

Ответ для тех, кто использует ExpandableListView и сталкивается с этим вопросом на основе его заголовка.

У меня была эта ошибка при попытке работать с TextView в моем дочернем и групповом представлениях как часть реализации ExpandableListView.

В своих реализациях методов getChildView () и getGroupView () вы можете использовать что-то вроде следующего.

Я новичок в Android / Eclipse, по ошибке добавил элементы пользовательского интерфейса в activity_main.xml вместо fragment_main.xml . Мне потребовалось несколько часов, чтобы понять это .

FWIW, я не вижу, чтобы кто-то решил это так же, как мне нужно. Никаких жалоб во время компиляции, но я получал нулевое представление во время выполнения и вызывал вещи в правильном порядке. Это, findViewById () после setContentView (). Проблема оказалась в том, что мое представление определено в content_main.xml, но в моем activity_main.xml мне не хватало этого одного утверждения:

Когда я добавил это в activity_main.xml, больше никакого NullPointer.

У меня была такая же проблема. Я использовал стороннюю библиотеку, которая позволяет вам переопределить их адаптер для GridView и указать собственный макет для каждой ячейки GridView.

Я наконец понял, что происходит. Eclipse по-прежнему использовал XML-файл макета библиотеки для каждой ячейки в GridView, хотя и не давал никаких указаний на это. В моем настраиваемом адаптере он указывал, что он использовал ресурс xml из моего собственного проекта, хотя во время выполнения этого не было.

Поэтому я убедился, что мои пользовательские макеты и идентификаторы xml отличаются от тех, которые все еще находятся в библиотеке, очистил проект, а затем он начал читать правильные пользовательские макеты, которые были в моем проекте.

Читайте также:  Древние времена для андроид

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

В моем конкретном случае я пытался добавить нижний колонтитул к ListView. Следующий вызов onCreate () возвращал null.

Эта проблема была решена путем изменения этого параметра для увеличения размера нижнего колонтитула вместо поиска по идентификатору.

В моем случае я использовал ExpandableListView и установил android:transcriptMode=»normal» . Это приводило к исчезновению нескольких детей в расширяемой группе, и я получал исключение NULL, когда когда-либо использовал прокрутку списка.

Для меня у меня было два макета xml для одного и того же действия — один в портретном режиме и один в альбомном. Конечно, я изменил идентификатор объекта в ландшафтном xml, но забыл сделать то же изменение в портретной версии. Убедитесь, что если вы измените один, вы сделаете то же самое с другим xml, иначе вы не получите сообщение об ошибке, пока не запустите / не отладите его, и он не сможет найти идентификатор, который вы не изменили. О глупые ошибки, почему ты должен меня так наказывать?

Установите содержимое действия из ресурса макета. т.е. setContentView(R.layout.basicXml) ;

В дополнение к вышеуказанным решениям вы убедитесь, что
tools:context=».TakeMultipleImages» в макете такое же значение в файле mainfest.xml:
android:name=».TakeMultipleImages» для того же элемента деятельности. это происходит при использовании копирования и вставки для создания нового действия

У меня такая же проблема, но я думаю, что ею стоит поделиться с вами, ребята. Если вам нужно найтиViewById в настраиваемом макете, например:

Вы не можете получить представление в конструкторе. Вы должны вызвать findViewById после того, как представление будет раздуто. Это метод, который вы можете изменить onFinishInflate

Просто хотел подбросить сюда свой конкретный случай. Может помочь кому-нибудь в будущем.

Я использовал эту директиву в своем XML-коде Android UI следующим образом:

Детский вид (retry_button):

.findViewById (R.id.retry) всегда будет возвращать значение null. Но если я переместил идентификатор из дочернего представления в тег include, он начал работать.

Мой случай не похож на предыдущий, никаких решений не сработало. Я предполагаю, что мое мнение было слишком глубоким в иерархии макетов. Я переместил его на один уровень вверх, и он больше не был нулевым.

НАДУВАТЬ ПЛАН !! (который содержит идентификатор)

В моем случае findViewById () вернул null, потому что макет, в котором был написан элемент, не был раздут .

FindViewById (R.id.listview) вернул значение null, потому что я не выполнял inflater.inflate (R.layout.fragment_layout, . . ); перед этим.

Надеюсь, этот ответ поможет некоторым из вас.

В моем случае я раздул макет, но дочерние представления возвращали null. Изначально у меня было такое:

Однако, когда я изменил его на следующее, он сработал:

Ключ был в том, чтобы специально ссылаться на уже раздутый макет, чтобы получить дочерние представления. То есть, чтобы добавить footerView :

  • footerView .findViewById .

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

В моем идентификаторе поля пароля loginActivity.xml был «пароль». В своей регистрационной активности я просто исправил это, указав id r_password, тогда он вернул не нулевой объект:

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

FindViewById также может возвращать значение null, если вы находитесь внутри фрагмента. Как описано здесь: findViewById во фрагменте

Вы должны вызвать getView (), чтобы вернуть представление верхнего уровня внутри фрагмента. Затем вы можете найти элементы макета (кнопки, текстовые представления и т. Д.)

Я столкнулся с аналогичной проблемой, когда пытался создать собственный вид для ListView .

Я решил это просто так:

Способы отладки и поиска проблемы:

  • Закомментируйте все findViewById в своей деятельности.
  • Закомментируйте все, кроме onCreate и setContentView
  • Запустите проект и посмотрите, установлен ли какой-либо макет

В моем случае я использовал activity_main.xml как в моем модуле приложения, так и в модуле библиотеки. Поэтому, когда я выполнил вышеуказанные шаги, вместо макета, который я разработал в библиотеке, макет внутри модуля приложения был раздут.

Поэтому я изменил имя файла activity_main.xml на activity_main_lib.xml.

Читайте также:  Антивирус для андроида что лучше

Поэтому убедитесь, что у вас нет повторяющихся названий макетов во всем проекте .

Моим решением было просто очистить проект.

Я пробовал все вышеперечисленное, ничего не работало . поэтому мне пришлось сделать мой ImageView static public static ImageView texture; , а затем texture = (ImageView) findViewById(R.id.texture_back); , я не думаю, что это хороший подход хотя, но в моем случае это действительно сработало 🙂

В моем случае findViewById вернул значение null, когда я переместил вызов из родительского объекта в объект адаптера, созданный родительским объектом. Попробовав перечисленные здесь приемы безуспешно, я переместил findViewById обратно в родительский объект и передал результат в качестве параметра во время создания экземпляра объекта адаптера. Например, я сделал это в родительском объекте:

Затем я передал hdSpinner в качестве параметра при создании объекта адаптера:

Источник

FindViewByID возвращает null

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

Большинство из них приходят с советами по использованию android:id вместо простого id в XML-файле. Я сделал.

Из других я узнал, что View.findViewById работает не так, как Activity.findViewById . Я тоже это обработал.

В моем location_layout.xml я использую:

В моей деятельности я делаю:

И в моем классе пользовательских представлений:

null возвращает null . Выполняя это, моя деятельность работает нормально. Возможно, это View.findViewById различиями Activity.findViewById и View.findViewById . Поэтому я сохранил контекст, переданный конструктору вида таможни локально, и попытался:

Который также возвратил null .

Затем я изменил свой пользовательский вид, чтобы расширить ViewGroup вместо этого View и изменил location_layout.xml чтобы TextView был прямым дочерним элементом моего пользовательского представления, так что View.findViewById должен работать так, как предполагалось. Suprise: он ничего не решал.

Так что, черт возьми, я поступаю неправильно?

Буду признателен за любые комментарии.

Возможно потому, что вы называете это слишком рано. Подождите, пока onFinishInflate() . Вот пример проекта, демонстрирующий пользовательский View доступ к его содержимому.

Возможно, вы вызываете findViewById перед вызовом setContentView ? Если это так, попробуйте вызвать findViewById ПОСЛЕ вызова setContentView

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

В моем случае у меня было 2 активности в моем проекте, main.xml и main2.xml . С самого начала main2 был копией main , и все работало хорошо, пока я не добавил новый TextView к main2 , поэтому R.id.textview1 стал доступен для остальных приложений. Затем я попытался получить его по стандартным вызовам:

И это всегда было нулевым. Оказалось, что в конструкторе onCreate я main2 экземпляр не main2 , а другой. Я имел:

Я заметил это после того, как приехал сюда, на сайт.

Наряду с классическими причинами, упомянутыми в другом месте:

  • Убедитесь, что вы вызвали setContentView() перед findViewById()
  • Убедитесь, что id вы хотите, находится в представлении или макете, который вы setContentView() для setContentView()
  • Убедитесь, что id не случайно дублируется в разных макетах

Есть один, который я нашел для пользовательских представлений в стандартных макетах, что противоречит документации:

Теоретически вы можете создать собственное представление и добавить его в макет ( см. Здесь ). Однако я обнаружил, что в таких ситуациях атрибут id работает для всех представлений в макете, кроме пользовательских. Решение, которое я использую:

    Замените каждое настраиваемое представление на FrameLayout с теми же свойствами макета, что и пользовательский вид. Дайте ему соответствующий id , скажем frame_for_custom_view .

Который помещает пользовательский вид в фрейм.

FindViewById может быть нулевым, если вы вызываете неправильный суперконструктор в пользовательском представлении. Тег ID является частью attrs, поэтому, если вы игнорируете attrs, вы удаляете ID.

Это было бы неправильно

Ответ для тех, кто использует ExpandableListView, и запускать этот вопрос на основе его названия.

У меня была ошибка при попытке работать с TextViews в моих дочерних и групповых представлениях как часть реализации ExpandableListView.

В реализациях методов getChildView () и getGroupView () вы можете использовать что-то вроде следующего.

Я нашел это здесь .

Я довольно новичок в Android / Eclipse, по ошибке я добавил материал пользовательского интерфейса в activity_main.xml вместо fragment_main.xml . Мне потребовалось несколько часов, чтобы понять это …

В моем конкретном случае я пытался добавить нижний колонтитул в ListView. Следующий вызов onCreate () возвращал значение null.

Читайте также:  Настройка i2p для андроид

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

FWIW, я не вижу, чтобы кто-то решил это так же, как мне было нужно. Никаких жалоб во время компиляции, но я получал нулевое представление во время выполнения и вызывал вещи в правильном порядке. То есть findViewById () после setContentView (). Проблема в том, что мое представление определено в content_main.xml, но в моем activity_main.xml мне не хватало этого одного утверждения:

Когда я добавил это к activity_main.xml, больше нет NullPointer.

В моем случае я использовал ExpandableListView, и я установил android:transcriptMode=»normal» . Это привело к тому, что несколько детей в расширяемой группе исчезли, и я использовал исключение NULL, когда я использовал прокрутку списка.

Для меня у меня было два xml-макета для одной и той же активности – один в портретном режиме и один в ландшафте. Конечно, я изменил идентификатор объекта в ландшафте xml, но забыл сделать то же изменение в портретной версии. Убедитесь, что если вы изменили одно, вы сделаете то же самое с другим xml или вы не получите сообщение об ошибке, пока не запустите / отлаживаете его, и он не сможет найти идентификатор, который вы не изменили. О, глупые ошибки, почему ты так меня наказываешь?

Задайте содержимое активности из ресурса макета. Т.е. setContentView(R.layout.basicXml) ;

У меня была такая же проблема. Я использовал стороннюю библиотеку, которая позволяет переопределить их адаптер для GridView и указать собственный макет для каждой ячейки GridView.

Наконец я понял, что происходит. Eclipse все еще использовал XML-файл раскладки библиотеки для каждой ячейки в GridView, хотя он не дал никаких указаний на это. В моем пользовательском адаптере он указал, что он использует ресурс xml из моего собственного проекта, хотя во время выполнения он не был.

Так что я сделал, чтобы убедиться, что мои собственные макеты xml и идентификаторы отличаются от тех, которые все еще сидят в библиотеке, очистили проект, а затем начали читать правильные пользовательские макеты, которые были в моем проекте.

Короче говоря, будьте осторожны, если вы переопределяете адаптер сторонней библиотеки и указываете свой собственный макет xml для использования адаптером. Если ваш макет внутри вашего проекта имеет то же имя файла, что и в библиотеке, вы можете столкнуться с действительно сложной ошибкой!

У меня такая же проблема, но я думаю, что ее стоит поделиться с вами, ребята. Если вам нужно findViewById в пользовательском макете, например:

Вы не можете получить представление в конструкторе. Вы должны вызвать findViewById после того, как просмотр завышен. Их метод, который вы можете переопределить onFinishInflate

В моем случае я раздул макет, но взгляды на ребенка возвращали нуль. Первоначально у меня было это:

Однако, когда я изменил его на следующее, он работал:

Ключ должен был специально ссылаться на уже завышенный макет, чтобы получить вид ребенка. То есть, чтобы добавить footerView :

  • FooterView .findViewById …

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

В дополнение к вышеуказанным решениям вы убедитесь, что
tools:context=».TakeMultipleImages» в макете такое же значение в файле mainfest.xml:
android:name=».TakeMultipleImages» для одного и того же элемента активности. Это происходит при использовании копирования и вставки для создания новой активности

ОГРАНИЧИВАЙТЕ СРОК! (Который содержит идентификатор)

В моем случае findViewById () возвратил null, потому что макет, в котором был написан элемент, не был завышен …

FindViewById (R.id.listview) возвратил null, потому что я не делал inflater.inflate (R.layout.fragment_layout, …, …); перед этим.

Надеюсь, этот ответ поможет некоторым вам.

Мое решение состояло в том, чтобы просто очистить проект.

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

Я использовал эту директиву в своем Android-интерфейсе Android следующим образом:

Детский вид (retry_button):

.findViewById (R.id.retry) всегда возвращает null. Но, если я переместил идентификатор из дочернего представления в тег include, он начал работать.

FindViewById также может возвращать значение null, если вы находитесь внутри фрагмента. Как описано здесь: findViewById in Fragment

Вы должны вызвать getView () для возврата верхнего уровня в фрагмент. Затем вы можете найти элементы макета (кнопки, текстовые изображения и т. Д.),

Источник

Оцените статью