java.lang.IllegalStateException: Underflow in restore - more restores than saves
Asked Answered
W

4

8

I am using rippleeffect library for my project. But in Android Nougat and Marshmallow, App crashes due to this library:

compile 'com.github.traex.rippleeffect:library:1.3'

The error message is:

FATAL EXCEPTION: main Process: com.test.testapp, PID: 17713 java.lang.IllegalStateException: Underflow in restore - more restores than saves at android.graphics.Canvas.native_restore(Native Method) at android.graphics.Canvas.restore(Canvas.java:522) at com.andexert.library.RippleView.draw(RippleView.java:170) ........................ ........................

As far as the below link this is a known issue. https://github.com/traex/RippleEffect/issues/76 and I also tried so many solutions from stackoverflow but luck did favor so far!!!

What can be done to solve this problem?

Willemstad answered 30/12, 2016 at 3:51 Comment(2)
I think you can fix this error by downgrading your - targetSdkVersion to 22 but i do not recommend to use that ! You don't need libraries to use ripple effectFleecy
This issue came in Android API Level 23 (Marshmallow). I updated the Library version to newest. They have solved the bug.Pengelly
F
14

I faced the same issue and did not found a good solution for that.But If you

  • Downgrade targetSdkVersion to 22 you can run it: meaning it does not crash! but I really don't recommend that.
  • Try to compile it with compile this dependency ->'com.github.emanzanoaxa:RippleEffect:52ea2a0ab6'
  • Call canvas.save(); before every restore() is another suggestion from your link given that you can try
  • You can also try to add that library inside your project and use it

https://codeload.github.com/traex/RippleEffect/zip/master (from the link you provided there are solutions that people have tried use them)


Or i suggest you to create them by yourself no libraries needed at all!

Ripple touch effect was introduced in Android 5.0 (API level 21) and the animation is implemented by the new RippleDrawable class.

General, ripple effect for regular buttons works by default in API 21 and for other touchable views, it can be achieved by specifying:

android:background="?attr/selectItemBackground"

for ripples contained within the view or:

android:background="?attr/selectItemBackgroundBorderless"

for ripples that extend beyond the view's bounds.

You can achieve the same in code using:

int[] attrs = new int[]{R.attr.selectItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);

If you want to customize the ripple effect into a view, you need to create a new XML file, inside the drawable directory.

Examples:

Example 1: An unbounded ripple

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#ffff0000" />

Example 2: Ripple with mask and background color

<ripple android:color="#7777666"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/mask"
        android:drawable="#ffff00" />
    <item android:drawable="@android:color/white"/>
</ripple>

Example 3: Ripple on top a drawable resource

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#ff0000ff">
    <item android:drawable="@drawable/my_drawable" />
</ripple>

How to Use: To attach your ripple xml file to any view, set it as background as following: assuming your ripple file is named my_ripple.xml. in exmple 1, 2 or 3

<View 
    android:id="@+id/myViewId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_ripple" />
Fleecy answered 30/12, 2016 at 5:37 Comment(2)
'com.github.emanzanoaxa:RippleEffect:52ea2a0ab6' dependency worked for me.Willemstad
I had 2 restore() for 1 save(). Adding a 2nd save did it. Thanks a lot for the hint.Reiff
A
14

they fixed the bug :P RippleEffect

Autopsy answered 3/8, 2017 at 13:21 Comment(2)
very nice @AutopsyFleecy
It is still coming.Phenomenal
B
1

Check your code again. You probably have an extra .restore() method somewhere.

Bihari answered 6/10, 2019 at 6:36 Comment(0)
T
1

In my case I blur image inside OnScroll (I scroll a view and blur in a loop). I initialized canvas so:

val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
// OnScroll:
    scroll.draw(canvas)
    blurImage(bitmap)

It lead to the exception. So, I moved val canvas = Canvas(bitmap) inside a loop:

val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
// OnScroll:
    val canvas = Canvas(bitmap)
    scroll.draw(canvas)
    blurImage(bitmap)

Later I removed blurring outside of the loop, so that canvas wasn't created in the loop anymore.

Tympan answered 19/10, 2021 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.