I'm not using the XML file to set the state of the ripple drawable instead I'm using the java new RippleDrawable(color, backgroundDrawable, null)
constructor as I'm using it in adapter where each item has there own color. The code works as expected on post lollipop devices but it crashes with the following error on pre lollipop ones even though I have added an SDK_INT check
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.rootView.setBackground(getBackgroundDrawable(ColorConverter.lightenColor(Color.parseColor(item.getTextColor()), 0.6f), background));
}
getBackgroundDrawable()
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static RippleDrawable getBackgroundDrawable(int pressedColor, Drawable backgroundDrawable) {
return new RippleDrawable(getPressedState(pressedColor), backgroundDrawable, null);
}
getPressedState()
private static ColorStateList getPressedState(int pressedColor) {
return new ColorStateList(new int[][]{new int[]{}}, new int[]{pressedColor});
}
Error Stacktrace
E/dalvikvm: Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method com.test.app.adapter.util.DashboardButtonsAdapter.getBackgroundDrawable
12-11 18:40:07.745 14717-14717/com.test.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.app, PID: 14717
java.lang.VerifyError: com/test/app/adapter/util/DashboardButtonsAdapter
at com.test.app.fragment.dashboard.DashboardPageFragment.onCreateView(DashboardPageFragment.java:71)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:733)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:805)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1052)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:590)
at android.view.View.measure(View.java:16504)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:847)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16504)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
at android.view.View.measure(View.java:16504)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1912)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1109)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1291)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRo
The reason for is #getBackgroundDrawable
is returning a RippleDrawable
. Because its available only 21+ hence the Verify error because its an independent method and return type in method signature is not found by android.
To verify this when you run the code below you won't get the same error because there is a version check for whole code block .
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable rippleDrawable= new RippleDrawable(getPressedState(Color.GREEN), null, null);
textView.setBackground(rippleDrawable);
}
The easiest solution for your problem is to change the return type of #getBackgroundDrawable
to Drawable
.
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static Drawable getBackgroundDrawable(int pressedColor, Drawable backgroundDrawable) {
return new RippleDrawable(getPressedState(pressedColor), backgroundDrawable, null);
}
java.lang.VerifyError
means your code is referring to something that android cannot find. Changing the returt type to Drawable
method signature will be valid for API-19.
If you run this code without version check then u will get ClassNotFoundException
because now actual method body is getting executed. Have a look at This thread.