попытка вызвать виртуальный метод «void android.widget.spinner.setadapter (адаптер)» в ссылке на нулевой объект [дубликат]

Решение Bootstrap v4 - основанное на jQuery, но лучше, чем чистое решение css

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

Это было сделано с учетом настольных компьютеров и мобильных устройств. Попал в оболочку jQuery с условием, который проверяет, превышает ли ширина окна 768px.

jQuery

/** Dropdown on hover */
$(".nav-link.dropdown-toggle").hover( function () {
    // Open up the dropdown
    $(this).removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link
    $(this).parent().addClass('show'); // add the class show to the li parent
    $(this).next().addClass('show'); // add the class show to the dropdown div sibling
}, function () {
    // on mouseout check to see if hovering over the dropdown or the link still
    var isDropdownHovered = $(this).next().filter(":hover").length; // check the dropdown for hover - returns true of false
    var isThisHovered = $(this).filter(":hover").length;  // check the top level item for hover
    if(isDropdownHovered || isThisHovered) {
        // still hovering over the link or the dropdown
    } else {
        // no longer hovering over either - lets remove the 'show' classes
        $(this).attr('data-toggle', 'dropdown'); // put back the data-toggle attr
        $(this).parent().removeClass('show');
        $(this).next().removeClass('show');
    }
});
// Check the dropdown on hover
$(".dropdown-menu").hover( function () {
}, function() {
    var isDropdownHovered = $(this).prev().filter(":hover").length; // check the dropdown for hover - returns true of false
    var isThisHovered= $(this).filter(":hover").length;  // check the top level item for hover
    if(isDropdownHovered || isThisHovered) {
        // do nothing - hovering over the dropdown of the top level link
    } else {
        // get rid of the classes showing it
        $(this).parent().removeClass('show');
        $(this).removeClass('show');
    }
});

CSS

@media(min-width:  768px) {
  .dropdown-menu {
    margin-top: 0; // fixes closing on slow mouse transition
  }
}
206
задан Ry- 21 June 2012 в 20:57
поделиться

26 ответов

, который возвращает null

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

234
ответ дан CommonsWare 20 August 2018 в 19:59
поделиться
  • 1
    О, МОЙ БОГ! Не могу поверить, что я трачу дни на что-то такое тривиальное. Я переместил setContentView () над вызовом findViewById (), и это трюк. благодаря! – agentcurry 26 January 2012 в 22:35
  • 2
    @CommonsWare это, что правильный проект? Я не вижу onFinishInflate нигде в github.com/commonsguy/cw-advandroid/tree/master/Animation/… – likejiujitsu 12 October 2015 в 16:43
  • 3
    @likejiujitsu: Возможно, это было в 2010 году. Я обновил ссылку на новый проект с onFinishInflate(). – CommonsWare 12 October 2015 в 16:58
  • 4
    У меня есть setContentView, вызываемый до findViewById, и он по-прежнему равен нулю. Я ссылаюсь на EditText – Neon Warge 13 February 2016 в 10:58
  • 5
    Всегда ссылайтесь на фиксированные обязательства GitHub (например, github.com/commonsguy/cw-omnibus/tree/… ) и никогда не удаляйте репозитории или rebase ;-) – Ciro Santilli 新疆改造中心 六四事件 法轮功 14 February 2016 в 17:22

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

2
ответ дан Ajay Takur 20 August 2018 в 19:59
поделиться

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

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

Например. fragment_layout.xml

<ListView
android:id="@+id/listview">

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

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

0
ответ дан Akshayraj Kore 20 August 2018 в 19:59
поделиться

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

2
ответ дан ColossalChris 20 August 2018 в 19:59
поделиться

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

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

0
ответ дан Community 20 August 2018 в 19:59
поделиться

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

3
ответ дан Deividas Strioga 20 August 2018 в 19:59
поделиться
  • 1
    У меня та же проблема, один уровень выше также можно найти .. это довольно раздражает, и я хотел бы знать, почему это происходит, поскольку я не могу сделать свое меню, как я хочу, чтобы он – NaturalBornCamper 23 December 2017 в 18:17
  • 2
    Иерархии глубокой иерархии являются анти-шаблонами, почти всегда есть более чистое решение. Вы говорите о переполнении меню на панели инструментов или в навигационном ящике? – Deividas Strioga 25 December 2017 в 13:03
  • 3
    Навигационный ящик, я уже опубликовал другой вопрос, за исключением того, что добавление элемента меню внутри группы не работает, просто добавляет его в конец всех элементов: stackoverflow.com/questions/47955376/… – NaturalBornCamper 25 December 2017 в 21:27

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

124
ответ дан eeerahul 20 August 2018 в 19:59
поделиться
  • 1
    Такая простая ошибка, но, к сожалению, это то, что я сделал. Отладчик бесполезен, так как он сказал, что ошибка была в моей новой линии намерения не в действительной новой активности, которую я вызывал. Благодаря! – edude05 13 April 2012 в 02:23
  • 2
    На самом деле у меня была эта ошибка, потому что я вызывал setContentView, указывающий на неправильный вид ... к сожалению, компилятор не поймает этот тип ошибки. – HeatfanJohn 12 February 2013 в 18:23
  • 3
    Да, я удалил setContentView по ошибке и не понял, почему моя программа начала раздавить. – Ronen Festinger 15 July 2016 в 18:23

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

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

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

4
ответ дан ferris 20 August 2018 в 19:59
поделиться
  • 1
    Проблема с копированием, вставляющим фрагмент, заключается в том, что вы иногда забываете что-то менять, являясь правильным макетом, чтобы раздуть один из них. Благодаря! – Pablo Quemé 6 January 2018 в 00:31

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

TextView tv = (TextView) findViewById( R.id.textview1 );

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

setContentView(R.layout.main);

вместо

setContentView(R.layout.main2);

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

14
ответ дан infografnet 20 August 2018 в 19:59
поделиться

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

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

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

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

2
ответ дан JDJ 20 August 2018 в 19:59
поделиться

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

2
ответ дан JeeZ 20 August 2018 в 19:59
поделиться

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

85
ответ дан Joe 20 August 2018 в 19:59
поделиться
  • 1
    БЛАГОДАРЯ! Вот и все. (В моем случае у меня есть несколько версий для разных версий Android). Я все время забываю об этом, хотя я поставил гигантский комментарий сверху и снизу каждого файла макета. Я хочу, чтобы компилятор допустил ошибку или большое предупреждение, если это произойдет. – tiktak 20 January 2013 в 14:28

Просто хотел бросить здесь свой конкретный случай.

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

Родительский взгляд:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:visibility="gone" />

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

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/retry"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">

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

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

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:id="@+id/retry"
        android:visibility="gone" />

Исправлено:

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">
1
ответ дан John D. 20 August 2018 в 19:59
поделиться
8
ответ дан Jonathan 20 August 2018 в 19:59
поделиться

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

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

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

        if (convertView == null) {
            LayoutInflater inflater =  (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.child_layout, null);
        }

Я нашел здесь здесь .

6
ответ дан Josh Metcalfe 20 August 2018 в 19:59
поделиться

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

5
ответ дан lama12345 20 August 2018 в 19:59
поделиться

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

 Spinner hdSpinner = (Spinner)view.findViewById(R.id.accountsSpinner);

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

  mTransactionAdapter = new TransactionAdapter(getActivity(),
        R.layout.transactions_list_item, null, from, to, 0, hdSpinner);
0
ответ дан Lexo 20 August 2018 в 19:59
поделиться

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

0
ответ дан Liangjun 20 August 2018 в 19:59
поделиться

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

TextView footerView = (TextView) placesListView.findViewById(R.id.footer);

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

View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);
3
ответ дан Matt 20 August 2018 в 19:59
поделиться

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

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

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

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

  1. Замените каждое пользовательское представление на FrameLayout теми же свойствами макета, что и пользовательское представление. Дайте ему соответствующий id, скажем frame_for_custom_view.
  2. В onCreate:
    setContentView(R.layout.my_layout);
    FrameView fv = findViewById(R.id.frame_for_custom_layout);
    MyCustomView cv = new MyCustomView(context);
    fv.addView(cv);
    
    , который помещает пользовательский вид в фрейм.
12
ответ дан Neil Townsend 20 August 2018 в 19:59
поделиться
  • 1
    Это помогло мне: & quot; Убедитесь, что идентификатор, который вы хотите, находится в представлении или макете, который вы указали для setContentView () & quot ;. Что делать, если это подкласс? Попробовал получить родительский вид, а затем родительский.findById (), но он все еще возвращает null – NaturalBornCamper 23 December 2017 в 19:26
  • 2
    @naturalborncamper, если вы разместите отдельный вопрос с примером кода, я посмотрю на него. – Neil Townsend 24 December 2017 в 10:18
  • 3
    Спасибо Neil, я уже опубликовал его, и кто-то указал лучший способ сделать это, хотя он не работает точно так, как должно быть, поэтому мне пришлось использовать другую стратегию: stackoverflow.com/questions/47955376/… – NaturalBornCamper 25 December 2017 в 21:25

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

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

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context);
}

Правильно

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context,attrs);
}
11
ответ дан repkap11 20 August 2018 в 19:59
поделиться
  • 1
    Большое спасибо, сэр! Так небрежно, я просто сомневаюсь, что с моей IDE что-то не так. Как вам повезло с ответом. – EffectiveMatrix 20 July 2015 в 10:52
  • 2
    – Andrew F. 9 August 2016 в 17:47

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

public class MiniPlayerControllBar extends LinearLayout {
    //code
}

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

2
ответ дан Shaw 20 August 2018 в 19:59
поделиться

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

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);

    footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
    pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter);
    tvText = (TextView) findViewById(R.id.tvListviewFooter);
    ...
}

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

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);

    footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
    pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter);
    tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter);
    ...
}

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

  • footerView.findViewById ...
1
ответ дан Suragch 20 August 2018 в 19:59
поделиться

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

1
ответ дан Tabish 20 August 2018 в 19:59
поделиться
  • 1
    извините, я думаю, статический взгляд - плохая идея – vuhung3990 25 June 2018 в 09:29

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

0
ответ дан Tad 20 August 2018 в 19:59
поделиться

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

2
ответ дан user2982286 20 August 2018 в 19:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: