Збій програми при спробі використовувати 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.