NullPointerException-попытка вызвать виртуальный метод RecyclerView$ViewHolder.shouldIgnore ()' для ссылки на нулевой объект

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

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
    at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2913)
    at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1445)
    at android.support.v7.widget.RecyclerView.access0(RecyclerView.java:144)
    at android.support.v7.widget.RecyclerView.run(RecyclerView.java:282)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:821)
    at android.view.Choreographer.doCallbacks(Choreographer.java:606)
    at android.view.Choreographer.doFrame(Choreographer.java:575)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:807)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:6895)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

это происходит, когда включена анимация изменений RecyclerView и соответствующий RecyclerView.Методы адаптера notifyItemInserted (), notifyItemRemoved () и т. д., вызываются, чтобы указать, что изолированное изменение было внесено в список, управляемый адаптером (в отличие от оптового изменения, как указано notifyDataSetChanged ()).

это из-за ошибки в RecyclerView, или мы разработчики делаем что-то не так?

4 ответов


в моем случае ошибка вследствие я ставил новый RecyclerView.LayoutParams в rootview элемента.

затем я понял, что RecyclerView вид товара хранит их ViewHolders в пользовательской ни класса. Поэтому, когда я сбросить ни ViewHolder ссылка навсегда. Что вызывает сбой NullPointerException позже.

проблема исчезла после того, как я перестал устанавливать RecyclerView.Ни в в rootView пункт. :)

Так. Прекратите делать это в своем представлении:

RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
itemRoot.setLayoutParams(params);

Это, по-видимому, связано с ошибкой в RecyclerView, которая была введена в 23.2.0. Ошибка была сообщена здесь, и я объяснил, что я думаю, вызывает ошибку в комментарий #5 на эту ошибку.

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

Я нашел источник этой проблемы. В течение RecyclerView.dispatchLayoutStep3 (), есть цикл for, " for (int i = 0; i

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

dispatchLayoutStep3 () - > animateChange () - > addAnimatingView () - > hide () - > hideViewInternal ()

когда ChildHelper добавляет дочерний параметр в свою коллекцию mHiddenViews, это нарушает целостность цикла for В dispatchLayoutStep3 ().

Я вижу два обходных пути для этого:

1) отключить анимацию изменений в RecyclerView

2) Перейти к 23.1.1, где это не было проблемой


Я встретил это исключение только сейчас, и я исправил его, изменив framgent до FragmentLayout.

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

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


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

    ViewGroup.LayoutParams params = itemView.getLayoutParams();
    params.height=xx;
    params.width= xx;
    params.yyyy = xxx;
    itemView.setLayoutParams(params);