Збій програми при спробі використовувати RecyclerView на Android 5.0


91

Я намагаюся возитися з новим RecyclerView, і всякий раз, коли я намагаюся його запустити, мій додаток відразу ж аварійно завершує роботу. Це дає мені NullPointerException для спроби отримати доступ до методів з android.support.v7.widget.RecyclerView. Я переглянув інші публікації і побачив, що у більшості людей цього не було, compile 'com.android.support:recyclerview-v7:+'але я спробував це, і це зовсім не допомогло. Не дуже впевнений, що робити в цей момент, будь-яка допомога буде вдячна. Ось журнал помилок: (я б опублікував зображення, але ще не маю 10 повторень)

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView$LayoutManager.onMeasure(android.support.v7.widget.RecyclerView$Recycler, android.support.v7.widget.RecyclerView$State, int, int)' on a null object reference
        at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:1764)
        at android.view.View.measure(View.java:17430)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17430)
        at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:851)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5786)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        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:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

для тих, хто має цю помилку, спричинену вкладками Viewpager, дивіться це рішення
— Хасан Гілак,

Ви вирішили це?. Будь ласка, допоможіть, у мене така ж проблема
— Сагар

Не забудьте встановити / створити / зареєструвати onCreateViewте, що ви видаляєте / знищуєте / реєструєте в onDestroyView... Потрібно слідувати цим життєвим циклам!
— Сакібой

Відповіді:


211

Ця проблема зазвичай виникає, коли LayoutManagerдля RecyclerView. Ви можете зробити це так:

final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);

14
Я не думаю, що це повинно бути остаточним, тому я не думаю, що в цьому була проблема. У моєму випадку я реалізовував фрагмент за допомогою recyclerView, і я намагався просто зберегти посилання на нього з onCreateView і встановити layoutManager пізніше, коли дані завантажуються. У мене виникла ця проблема, і вона зникла, коли я встановив layoutManager раніше в методі gamein onCreateView.
— Неманя Ковачевич

3
@ NemanjaKovačević ну, я припускаю, що кожна змінна, яку не потрібно змінювати пізніше, повинна бути оголошена як final, тому я оголосив її finalтут.
— aga

2
Оскільки LinearLayoutManager за замовчуванням вертикальний, ви можете використовувати: reciclerView.setLayoutManager (новий LinearLayoutManager (контекст));
— ll

1
Слава Богу, що ми можемо погуглити ті самі повідомлення про помилки, що й Google, щоб зрозуміти їх.
— jhegedus

1
@wesleyfranks важко сказати, чому ви отримуєте посилання на нульовий об'єкт, не дивлячись на 1. код, який встановлює RecyclerView і 2. стек стека, який ви отримуєте після аварії. :)
— aga,

26

У моєму випадку це було пов’язано не з „остаточним”, а з проблемою, згаданою у коментарі @ NemanjaKovačević до відповіді @aga. Я встановлював layoutManager при завантаженні даних, і це було причиною того ж збою. Після переміщення налаштування layoutManager до onCreateView мого фрагмента проблема була виправлена.

Щось на зразок цього:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
{
...
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler);

mLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);

1
Ще раз: я не кажу, що ця проблема якось пов’язана з тим, що змінна не є остаточною. Питання в тому, що LayoutManager не було надано , ось і все. Ви можете зробити змінну, що вказує на LayoutManagerфінал, чи не остаточний - це нічого не змінює.
— aga

@Yurik я використовую reciclerview в Activity, не на фрагменті. що для мене справа?
— Youri

@Youri, ви просто повинні помістити налаштування layoutManager у onCreate своєї діяльності, я думаю.
— YuriK

10

Для мене у мене була та сама проблема, проблема полягала в тому, що в xml залишився невикористаний RecyclerView з переглядом, але я не прив'язую його до будь-якого адаптера в Activity, отже, проблема. Це було вирішено, як тільки я видалив такі невикористані подання утилізатора в xml

тобто - Я видалив це представлення, оскільки воно не було викликане в коді або не встановлено будь-який адаптер

<android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rv_profileview_allactivities"
        android:visibility="gone" />

Те саме тут все було ідеально, але це не працювало. Тож я видалив невикористані огляди утилізаторів, і він працював без жодних проблем. Thanks man @Maurice ^^
— Bhupinder

1
витративши день, я спробував ваше рішення, і воно спрацювало: D [:( мій час втратив даремно]
— mfaisalhyder

8

Я відчув цей збій, хоча мав RecyclerView.LayoutManagerналежний набір. Мені довелося перенести RecyclerView код ініціалізації у onViewCreated(...)зворотний виклик, щоб вирішити цю проблему.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_listing, container, false);
    rootView.setTag(TAG);
    return inflater.inflate(R.layout.fragment_listing, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mLayoutManager = new LinearLayoutManager(getActivity());
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mRecyclerView.setLayoutManager(mLayoutManager);

    mAdapter = new ListingAdapter(mListing);
    mRecyclerView.setAdapter(mAdapter);
}

2
Тим не менше, моя проблема не вирішена: / я спробував майже кожне рішення і все ще отримую ту саму помилку під час використання RecyclerView всередині фрагмента, який буде показано в PagerView :(
— mfaisalhyder

Чудово! Переміщення RecyclerViewкоду ініціалізації в onViewCreated(...) спрацьований
— Марсело Грасьєтті

Я зробив це рішення, і воно все ще було для мене нульовим. Все ще намагаючись зрозуміти, де, хоча.
— Wesley Franks

5

Вам потрібно використовувати setLayoutManagerв RecyclerView#onCreate()методі. Перед додаванням recyclerViewдо подання він повинен мати LayoutManagerнабір.

 private RecyclerView menuAsList;

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

    menuAsList = (RecyclerView) findViewById(R.id.recyclerView_mainMenu);
    menuAsList.setLayoutManager(new LinearLayoutManager(Home.this));

}

3

Я отримав цю проблему через неправильне посилання на RecyclerViewідентифікатор.

recyclerView = (RecyclerView) findViewById(R.id.rv_followers_list);

до

recyclerView = (RecyclerView) findViewById(R.id.rv_search_list);

2
recyclerView =
            (RecyclerView) findViewById(R.id.recycler_view2);

Зверніться до свого ідентифікатора виду переробника, вказуючи на фактичний вигляд переробника, який вирішив мою проблему


1

Моя проблема полягала в моєму XML-мові, у мене для android: animateLayoutChanges встановлено значення true, і я зателефонував notifyDataSetChanged () на адаптері RecyclerView в коді Java.

Отже, я щойно видалив android: animateLayoutChanges зі свого макета, і це вирішило мою проблему.


1

У мене була ця проблема під час використання бібліотеки Butterknife. Я мав:

View rootView = inflater.inflate
                (R.layout.fragment_recipe_detail_view, container, false);
ButterKnife.bind(rootView);

Але правильна версія:

View rootView = inflater.inflate
                (R.layout.fragment_recipe_detail_view, container, false);
ButterKnife.bind(this, rootView);

1

У Gradle реалізуйте цю бібліотеку:

implementation 'com.android.support:appcompat-v7:SDK_VER'
implementation 'com.android.support:design:SDK_VER'
implementation 'com.android.support:support-v4:SDK_VER'
implementation 'com.android.support:support-v13:SDK_VER'
implementation 'com.android.support:recyclerview-v7:SDK_VER'

У XML згадуємо так:

<android.support.v7.widget.RecyclerView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:id="@+id/recyclerView"/>

У фрагменті ми використовуємо recyclerViewтак:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
       View rootView = inflater.inflate(R.layout.YOUR_LAYOUT_NAME, container, false);

       RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        APICallMethod();
        YOURADAPTER = new YOURADAPTER(getActivity(), YOUR_LIST); // you can use that adapter after for loop in response(APICALLMETHOD)
        recyclerView.setAdapter(YOURADAPTER);
        return rootView;
    }

В Activity ми використовуємо RecyclerViewтак:

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

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        APICallMethod();
        YOURADAPTER = new YOURADAPTER(ACTIVITY_NAME.this, YOUR_LIST); // you can use that adapter after for loop in response(APICALLMETHOD)
        recyclerView.setAdapter(YOURADAPTER);
   }

якщо вам потрібна горизонтальна, RecyclerView зробіть це:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(layoutManager);
        APICallMethod();
        YOURADAPTER = new YOURADAPTER(ACTIVITY_NAME.this, YOUR_LIST); // you can use that adapter after for loop in response(APICALLMETHOD)
        recyclerView.setAdapter(YOURADAPTER);

якщо ви хочете використовувати GridLayoutManager, використовуючи RecyclerViewвикористання такого:

        RecyclerView recyclerView = findViewById(R.id.rvNumbers);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); // 3 is number of columns.
        adapter = new MyRecyclerViewAdapter(this, data);
        recyclerView.setAdapter(adapter);

1

Я використовував ін’єкцію залежності - ButterKnife, і ця проблема виникла через те, що я не пов’язав погляд.

Тож усередині onCreate () я щойно вставив цей рядок:

ButterKnife.bind(this);

Моя декларація RecyclerView з ін’єкцією залежності:

@BindView(R.id.recyclerview)
RecyclerView recyclerView;

1

Для тих, хто використовує: реалізацію 'androidx.recyclerview: recyclerview: 1.1.0-beta05'

переконайтеся, що ви використовуєте це у своєму макеті xml

Я також зазнав аварії під час запуску мого додатка нижче API 27. Ось посилання на повідомлення

Спочатку я створив стиль для зміни розміру шрифту мого текстового подання всередині виду перегляду, тому і створив цей код нижче: (я міг просто зателефонувати @dimen при зміні розміру шрифту на основі розмірів екрану)

Всередині style.xml

і додав це в мою тему

themes.xml

Дослідивши, я з’ясував, що саме цей призводить до помилки, і після видалення стилю я більше не стикався.

Я спробував усі можливі рішення, які я знайшов тут у переповненні стека, і майже відмовився від цього, на щастя, в своїй цікавості я подумав, чому не видалити стиль, можливо, це спричиняє збій, а потім бум збою зникає.


1
Будь ласка, включайте приклади коду безпосередньо, а не посилання на зображення. Погляньте на розділ "Допоможіть іншим відтворити проблему": stackoverflow.com/help/how-to-ask
— Chris B

1
Я справді за це @ChrisB. Я вперше коментую тут, оскільки моя репутація занадто низька, як бачите. Я зіткнувся з аварією сьогодні, і я думав розмістити тут, можливо, є люди, які також стикаються з цим, особливо вони використовують 'androidx.recyclerview: reciclerview: 1.1.0-beta05'.
— Jeanne vie

0

Оскільки LinearLayoutManager за замовчуванням вертикальний, простіший спосіб зробити це:

recyclerView.setLayoutManager(new LinearLayoutManager(context));

Якщо ви хочете змінити орієнтацію, ви можете використовувати цей конструктор:

public LinearLayoutManager(Context context, int orientation, boolean reverseLayout);

маючи дивного менеджера issulinearlayout зараз. я його інстанцирую, але все ще ge ця помилка. свята корова.
— filthy_wizard

0

Я думаю, проблема у вашому Adapter. Переконайтеся , що ви повернулися ViewHolderв onCreateViewHolder(). Як нижче:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;
    v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_leaderboard, parent, false);
    ViewHolder view_holder = new ViewHolder(v);
    return view_holder;
}

0

Для мене проблема полягала в моєму Activity_main.xml (21), в якому recycleView не мав ідентифікатора.

activity_main.xml (21)

 <android.support.v7.widget.RecyclerView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/button3"
    tools:listitem="@layout/transaction_list_row" />

Activity_main.xml

<android.support.v7.widget.RecyclerView

    android:id="@+id/transac_recycler_view"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/button3"
    />

Це спрацювало, коли я додав android: id = "@ + id / transac_recycler_view" до Activity_main.xml (21) recycleView


0

У моєму випадку я додав лише бібліотеку масляного ножа і забув додати annotationProcessor. Додавши нижчий рядок до build.gradle (модуль програми), вирішив мою проблему.

    annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'

0

Recyclerview recylerview = findbyid (R.id.recyclerview) Можливо, ви пропустили це


Привіт, ласкаво просимо до SO! Будь ласка, поясніть ще, чому це актуально для цього питання. Як зараз написано, важко сказати, на що ви посилаєтесь.
— Piotr Kamoda

0

У мене була подібна проблема, коли я тестував свою програму на GenyMotion. Після перезапуску пристрою в GenyMotion проблема була вирішена


0

Я зіткнувся з тією ж проблемою, тому що RecyclerView містився в іншому макеті, а не в Activity_main.xml.

Шукаючи на деяких сайтах, я щось отримав і відчув, що хочу поділитися тут

  1. Додайте ідентифікатор для включення тегу до Activity_main.xml

    <include id="includedRecyclerLayout" .... </include>

  2. викличте цей макет перед пошуком подання за ідентифікатором у MainActivity.java

    `ConstraintLayout includedLayout = findViewById (R.id.inckudedRecyclerLayout);

    RecyclerViewrecyclerview = includedLayout.findViewById (R.id.RECYCLER_VIEW_ID) `;


-1

Якщо я там, де ти, я це зроблю. onView (withId (android.R.id.list)). виконувати (RecyclerViewActions.scrollToPosition (3)); android.R.id.list змініть його на ідентифікатор списку, і позиція буде вашою позицією всередині вашого масиву.


-1

за допомогою фрагмента

написання коду в onCreateView ()

RecyclerView recyVideo = view.findViewById (R.id.recyVideoFag);

використання діяльності

написання коду в onCreate () RecyclerView recyVideo = findViewById (R.id.recyVideoFag);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.