turing-tech / MaterialScrollBar

An Android library that brings the Material Design 5.1 sidebar to pre-5.1 devices.
Apache License 2.0
781 stars 126 forks source link

Updating the RecyclerView content while the Indicator is visible leads to crash #66

Closed awenger closed 8 years ago

awenger commented 8 years ago
materialScrollBar = new TouchScrollBar(this, list, false);
materialScrollBar.setHandleColour(ContextCompat.getColor(this, R.color.test));
materialScrollBar.addIndicator(new CustomIndicator(this), true);

If the content of the RecyclerView changes while the Indicator is visible this happens:

  java.lang.ArrayIndexOutOfBoundsException: length=546; index=-1
      at java.util.ArrayList.get(ArrayList.java:310)
      at my.Adapter.getCustomStringForElement(Adapter.java:26)
      at abu.a(CustomIndicator.java:38)
      at aby.setText(Indicator.java:102)
      at acg.a(ScrollingUtilities.java:68)
      at aca.a(MaterialScrollBar.java:657)
      at ack.onTouch(TouchScrollBar.java:72)
      at android.view.View.dispatchTouchEvent(View.java:9296)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2547)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2240)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
      at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403)
      at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
      at android.app.Activity.dispatchTouchEvent(Activity.java:2771)
      at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:63)
      at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:63)
      at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364)
      at android.view.View.dispatchPointerEvent(View.java:9520)
      at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4230)
      at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4096)
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
      at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
      at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922)
      at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896)
      at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5857)
      at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6025)
      at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
      at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
      at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
      at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5996)
      at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6048)

In this case previously available items in the RecyclerView were removed during the content change. The Adapter was notified of the changes via adapter.notifyItemRangeRemoved

awenger commented 8 years ago

Thanks for the fast fix. However I think just catching the ArrayIndexOutOfBoundsException is not the proper way to handle such cases. Did you test if it's possible to observe the RecyclerView.Adapter for data changes and act accordingly?

Ashok-Varma commented 7 years ago

I think you should give a method to call when ever data changes. Like notifydataSetChanged.