使用 java 创建的 Ripple Drawable 在 pre lollipop 上崩溃
Ripple Drawable created using java crashes on pre lollipop
我没有使用 XML 文件来设置波纹可绘制对象的状态,而是使用 java new RippleDrawable(color, backgroundDrawable, null)
constructor在每个项目都有自己的颜色的适配器中使用它。该代码在 post 棒棒糖设备上按预期工作,但它在棒棒糖之前的设备上崩溃并出现以下错误,即使我添加了 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});
}
错误堆栈跟踪
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
#getBackgroundDrawable
的原因是 returning a RippleDrawable
。因为它只有 21+ 可用,所以验证错误,因为它是一个独立的方法,并且 android 找不到方法签名中的 return 类型。
要验证这一点,当您 运行 下面的代码时,您不会得到相同的错误,因为对整个代码块进行了版本检查。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable rippleDrawable= new RippleDrawable(getPressedState(Color.GREEN), null, null);
textView.setBackground(rippleDrawable);
}
解决您问题的最简单方法是将 #getBackgroundDrawable
的 return 类型更改为 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
表示您的代码引用了 android 无法找到的内容。将返回类型更改为 Drawable
方法签名将对 API-19 有效。
如果你 运行 这个代码没有版本检查那么你会得到 ClassNotFoundException
因为现在实际的方法体正在执行。看看 This thread.
我们知道RippleDrawable()
不支持android版本以下的棒棒糖(21版本以下)。
所以对于之前的棒棒糖版本,
对于连锁反应,你可以试试这个。
这个图书馆Material
dependencies {
implementation 'com.github.rey5137:material:1.3.1'
}
这是您的按钮代码,
<com.rey.material.widget.Button
style="@style/YourOwnStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON"
app:rd_style="@style/YourRippleDrawableStyle"/>
自定义视图也支持,
有关更多详细信息,请查看此 link、
我没有使用 XML 文件来设置波纹可绘制对象的状态,而是使用 java new RippleDrawable(color, backgroundDrawable, null)
constructor在每个项目都有自己的颜色的适配器中使用它。该代码在 post 棒棒糖设备上按预期工作,但它在棒棒糖之前的设备上崩溃并出现以下错误,即使我添加了 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});
}
错误堆栈跟踪
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
#getBackgroundDrawable
的原因是 returning a RippleDrawable
。因为它只有 21+ 可用,所以验证错误,因为它是一个独立的方法,并且 android 找不到方法签名中的 return 类型。
要验证这一点,当您 运行 下面的代码时,您不会得到相同的错误,因为对整个代码块进行了版本检查。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable rippleDrawable= new RippleDrawable(getPressedState(Color.GREEN), null, null);
textView.setBackground(rippleDrawable);
}
解决您问题的最简单方法是将 #getBackgroundDrawable
的 return 类型更改为 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
表示您的代码引用了 android 无法找到的内容。将返回类型更改为 Drawable
方法签名将对 API-19 有效。
如果你 运行 这个代码没有版本检查那么你会得到 ClassNotFoundException
因为现在实际的方法体正在执行。看看 This thread.
我们知道RippleDrawable()
不支持android版本以下的棒棒糖(21版本以下)。
所以对于之前的棒棒糖版本, 对于连锁反应,你可以试试这个。
这个图书馆Material
dependencies {
implementation 'com.github.rey5137:material:1.3.1'
}
这是您的按钮代码,
<com.rey.material.widget.Button
style="@style/YourOwnStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON"
app:rd_style="@style/YourRippleDrawableStyle"/>
自定义视图也支持,
有关更多详细信息,请查看此 link、