[英]java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
I am trying to implement swipe to delete in RecyclerView.我正在尝试在 RecyclerView 中实现滑动删除。 Everything seems to be working fine except drawing a delete icon below the item that's being swiped.
除了在正在滑动的项目下方绘制一个删除图标外,一切似乎都运行良好。
This is how I am doing it:这就是我的做法:
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
// Do my stuff
// }
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
Bitmap icon;
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
View itemView = viewHolder.itemView;
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
if(dX > 0){
p.setColor(Color.parseColor("#388E3C"));
RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_delete);
RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
} else {
p.setColor(Color.parseColor("#D32F2F"));
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_delete);
RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
It is throwing它在扔
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean android.graphics.Bitmap.isRecycled()”
Full StackTrace完整堆栈跟踪
09-12 01:28:58.386 26575-26575/com.ozuf.booker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ozuf.booker, PID: 26575
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference
at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1281)
at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:620)
at com.ozuf.booker.fragments.BookFragment$1.onChildDraw(BookFragment.java:149)
at android.support.v7.widget.helper.ItemTouchHelper$Callback.onDraw(ItemTouchHelper.java:1956)
at android.support.v7.widget.helper.ItemTouchHelper$Callback.access$1400(ItemTouchHelper.java:1356)
at android.support.v7.widget.helper.ItemTouchHelper.onDraw(ItemTouchHelper.java:542)
at android.support.v7.widget.RecyclerView.onDraw(RecyclerView.java:3373)
at android.view.View.draw(View.java:15635)
at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3308)
at android.view.View.updateDisplayListIfDirty(View.java:14568)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3588)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3567)
at android.view.View.updateDisplayListIfDirty(View.java:14528)
at android.view.View.getDisplayList(View.java:14590)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2575)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2385)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2012)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1073)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5988)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Chor
Line 149 is c.drawBitmap(icon,null,icon_dest,p);
第 149 行是
c.drawBitmap(icon,null,icon_dest,p);
I have debugged and I saw that icon
is null but I don't understand why it;s null since I've already assigned it a value.我已经调试过,我看到那个
icon
是空的,但我不明白为什么它是空的,因为我已经为它分配了一个值。
I don't understand why it;s null since I've already assigned it a value.
我不明白为什么它是空的,因为我已经给它赋值了。
Yes.是的。 You did =>
null
.你做了 =>
null
。 The problem is elsewhere.问题出在别处。 See docs for decodeResource() :
请参阅decodeResource() 的文档:
Returns: The decoded bitmap, or null if the image could not be decoded .
返回: 解码后的位图,如果图像无法解码,则返回null 。
so you need to a) always check for that condition, b) check why exactly it happens with the data you try to decode.所以您需要 a) 始终检查该条件,b) 检查为什么您尝试解码的数据会发生这种情况。
The error is because of the drawable might be a Vector.错误是因为 drawable 可能是 Vector。
Drawable drawable = ContextCompat.getDrawable(StreamActivity.this,R.drawable.ic_close)
Bitmap icon = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(icon);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
Trying to decode a vector drawable into Bitmap, gives such error.尝试将可绘制矢量解码为 Bitmap,会出现此类错误。 So try to use any image with format .png, .jpeg etc in case of decoding resource to Bitmap.
因此,如果将资源解码为 Bitmap,请尝试使用任何格式为 .png、.jpeg 等的图像。
Answer is check if bitmap is null or reycled() before passing it to ImageView.答案是在将位图传递给 ImageView 之前检查位图是否为空或reycled() 。
if(resource!==null && !resource.isRecycled)
imageView.setImageBitmap(resource)
My problem was that android added a vector drawable anydpi
along with the multiple created image assets for the icon.我的问题是 android 添加了一个矢量可绘制
anydpi
以及为图标创建的多个图像资产。 I deleted the anydpi
variant and it all works fine now.我删除了
anydpi
变体,现在一切正常。
I switched from:我从:
android:layout_width="1095dp"
android:layout_height="1200dp"
To:至:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Then the error went away.然后错误消失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.