webentwicklung-frage-antwort-db.com.de

RecyclerView stürzt beim Update ab

Ich habe eine RecyclerView in meiner App. Alles funktioniert gut. Ich bin beim Scrollen, wenn das letzte Element sichtbar ist. Ich füge ein paar weitere Elemente an der Unterseite hinzu und es funktioniert einwandfrei. Nun, das Problem ist, dass ich eine Handler habe, die alle 5 Sekunden ausgeführt wird, und überprüfen, ob es ein Update im Web-Service gibt. Wenn es ein Update gibt, lade ich einfach die Daten oben in die RecyclerView ollte nicht die RecyclerView rollen, aber wenn ich sie scrolle und die Handler aufgerufen wird (wie sie alle 5 Sekunden aufgerufen wird), stürzt die App beim Aktualisieren der RecyclerView oben ab.

Aktualisierungsfunktion oben:

public void addOnTop(ArrayList<ItemPOJO> topItemList) {
    for (int i = topItemList.size() - 1; i >= 0; i--) {
        itemList.add(0, topItemList.get(i));
    }
    notifyItemRangeInserted(0, topItemList.size());
    notifyDataSetChanged();
}

Dies ist das Fehlerprotokoll:

Java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{419b8760 position=5 id=-1, oldPos=-1, pLpos:-1 no parent}
        at Android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.Java:4214)
        at Android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.Java:4345)
        at Android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.Java:4326)
        at Android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.Java:1955)
        at Android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.Java:1364)
        at Android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.Java:1327)
        at Android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.Java:1155)
        at Android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.Java:1012)
        at Android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.Java:1363)
        at Android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.Java:2227)
        at Android.view.View.dispatchTouchEvent(View.Java:7190)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2274)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2009)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2280)
        at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2023)
        at com.Android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.Java:1931)
        at com.Android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.Java:1385)
        at Android.app.Activity.dispatchTouchEvent(Activity.Java:2396)
        at Android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.Java:59)
        at Android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.Java:59)
        at com.Android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.Java:1879)
        at Android.view.View.dispatchPointerEvent(View.Java:7370)
        at Android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.Java:3182)
        at Android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.Java:3127)
        at Android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.Java:4164)
        at Android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.Java:4143)
        at Android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.Java:4235)
        at Android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.Java:171)
        at Android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
        at Android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.Java:163)
        at Android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.Java:4214)
        at Android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.Java:4254)
        at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:725)
        at Android.view.Choreographer.doCallbacks(Choreographer.Java:555)
        at Android.view.Choreographer.doFrame(Choreographer.Java:523)
        at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreog

P.S .: com.Android.support:recyclerview-v7:22.2.1 wird verwendet

10

Dieser Absturz kann durch die Tatsache verursacht werden, dass die Methoden setViewHolder und onBind aufgerufen werden, während Ihre vom Adapter verwendete Liste aktualisiert wird, notifyDataSetChanged() jedoch nicht aufgerufen wurde. Dies geschieht normalerweise, wenn Sie durch die Liste blättern oder fliehen, während die Liste aktualisiert wird.

Lösung: Eine separate Liste (tempList) von ItemPOJOs pflegen und die topData in dieser Liste anhängen. Anschließend die Liste für den Adapter löschen, die Liste des Adapters mit der tempList setzen und aufrufen notifyDataSetChanged().

6
Sid

Es ist ein Fehler im Wohnmobil, siehe die Diskussion hier .
In den meisten Fällen kann mit notifyDataSetChanged() dieser Absturz vermieden werden, Animation und Performance werden jedoch abgebrochen.

3
Piasy

Deaktivieren Sie die Recycler-Funktion während der Aktualisierung:

recyclerView.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          return true;
      }
  });
1

Ändern Sie Ihren Code folgendermaßen:

public void addOnTop(ArrayList<ItemPOJO> topItemList) {
    Collections.reverse(topItemList);
    itemList.addAll(0, topItemList);
    notifyItemRangeInserted(0, topItemList.size());
}

es ist komisch, aber auf diese Weise habe ich mein Problem gelöst!

1
MaryPeak

Versuche dies:

 notifyItemRangeInserted(0, topItemList.size()-1);
0
damn