2015-07-24 2 views
9

Ich habe eine RecyclerView in meiner App funktioniert alles gut Ich bin beim Scrollen, wenn das letzte Element sichtbar ist Ich füge etwas mehr Element auf der Unterseite und es funktioniert gut. Nun, was das Problem ist, dass ich eine Handler habe, die alle 5 Sekunden läuft und überprüfen, ob es irgendwelche Updates im Web-Service gibt und wenn es irgendwelche Updates gibt, lade ich einfach die Daten an die Spitze der RecyclerView es funktioniert gut, wenn ich habe nicht gescrollt die RecyclerView, aber wenn ich es scrollen und die Handler heißt (wie es nach jeweils 5 Sekunden aufgerufen wird) dann während der Aktualisierung der RecyclerView auf der Oberseite stürzt die App.RecyclerView stürzt beim Aktualisieren auf

Updating-Funktion an der Spitze:

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 Protokoll Fehler:

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 

PS: com.android.support:recyclerview-v7:22.2.1

verwendet wird
+1

Entfernen Sie einfach 'notifyItemRangeInserted (0, topItemList.size());' da die 'notifyDataSetChanged();' deckt die Meldungen und sehen, ob das das Problem behebt. – kha

Antwort

0

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

3

Es ist ein Bug von RV, siehe discussion here.
In den meisten Fällen wird notifyDataSetChanged() diesen Absturz zu vermeiden, aber es wird Animation und Leistung zu töten.

1

Code wie folgt ändern:

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

es seltsam, aber auf diese Weise behoben ich mein Problem!

6

Dieser Absturz könnte durch die Tatsache verursacht werden, dass die setViewHolder und onBind Methoden aufgerufen werden, während die Liste (vom Adapter verwendet wird) aktualisiert wird, aber notifyDataSetChanged() genannt worden ist. Dies passiert normalerweise, wenn Sie während der Aktualisierung der Liste durch die Liste blättern.

Lösung: Pflegen Sie eine separate Liste (tempList) von ItemPOJOs und die topData in dieser Liste anhängen. Löschen Sie dann die für den Adapter verwendete Liste, legen Sie die Liste des Adapters mit tempList fest und rufen Sie notifyDataSetChanged() an.

2

Versuchen deaktivieren recyclerview während erfrischend:

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