I have a code like this:
@Override
public void onDrawOver(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
drawGradient(canvas, parent);
drawStages(canvas, parent);
}
private void drawStages(final Canvas canvas, RecyclerView parent) {
final int parentLeft = parent.getPaddingLeft();
final int parentRight = parentLeft + mLeftPadding + mIconSize + mRightPadding;
int childCount = parent.getChildCount();
for (int i = 0; i < childCount - 1; i++) {
View child = parent.getChildAt(i);
LineupLayoutManager.LayoutParams params =
(LineupLayoutManager.LayoutParams) child.getLayoutParams();
final int parentTop = child.getTop() + params.topMargin;
final int parentBottom = child.getBottom() + params.bottomMargin;
int height = parentBottom - parentTop;
final int paddingVertical = Math.round((height - mIconSize) / 2);
try {
String link = findPlaceById(params.getPlaceId(),mStageList).getImg();
Picasso.with(context).load(link).resize(150,150).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
final Drawable drawable = new BitmapDrawable();
drawable.setBounds(parentLeft + mLeftPadding, parentTop + paddingVertical,
parentRight - mRightPadding, parentBottom - paddingVertical);
Canvas canvas1 = new Canvas(bitmap);
drawable.draw(canvas1);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
} catch (IndexOutOfBoundsException e) {
Log.e(LOG_TAG, Log.getStackTraceString(e));
}
}
}
Whole code is inside the Class extended from RecyclerView.ItemDecoration The problem is that when I execute it, app crashes with this error:
Fatal signal 11 (SIGSEGV), code 1, fault addr 0x58 in tid 17542
I also tried to put bitmap.draw into runOnUIThread() but no success.
After a bit of research, I discovered that Picasso is somehow interfering with the canvas. That means if I put the stuff outside picasso methods, everything works fine.
I'm only assuming right now, but it seems like you stored a reference to canvas
sometime earlier. When you then receive the Bitmap
, this Canvas
might have been invalidated somehow already.
Instead of your implementation, store a reference to the Drawable
and request a redraw on your View
. Then within onDraw()
draw the Drawable
to the Canvas
provided as a parameter.
Try to adapt the following implementation to you liking.
BitmapDrawable drawable = null;
private void drawStages(Canvas canvas, RecyclerView parent) {
if (drawable != null) {
int parentLeft = parent.getPaddingLeft();
int parentRight = parentLeft + mLeftPadding + mIconSize + mRightPadding;
int childCount = parent.getChildCount();
for (int i = 0; i < childCount - 1; i++) {
View child = parent.getChildAt(i);
LineupLayoutManager.LayoutParams params =
(LineupLayoutManager.LayoutParams) child.getLayoutParams();
int parentTop = child.getTop() + params.topMargin;
int parentBottom = child.getBottom() + params.bottomMargin;
int height = parentBottom - parentTop;
int paddingVertical = Math.round((height - mIconSize) / 2);
drawable.setBounds(parentLeft + mLeftPadding, parentTop + paddingVertical,
parentRight - mRightPadding, parentBottom - paddingVertical);
drawable.draw(canvas);
} else try {
String link = findPlaceById(params.getPlaceId(),mStageList).getImg();
Picasso.with(context).load(link).resize(150,150).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
drawable = new BitmapDrawable();
parent.invalidate()
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
} catch (IndexOutOfBoundsException e) {
Log.e(LOG_TAG, Log.getStackTraceString(e));
}
}
Edit: Added the working code.
private void drawStages(Canvas canvas, final RecyclerView parent) {
final int parentLeft = parent.getPaddingLeft();
final int parentRight = parentLeft + mLeftPadding + mIconSize + mRightPadding;
int childCount = parent.getChildCount();
for (int i = 0; i < childCount - 1; i++) {
View child = parent.getChildAt(i);
LineupLayoutManager.LayoutParams params =
(LineupLayoutManager.LayoutParams) child.getLayoutParams();
final int parentTop = child.getTop() + params.topMargin;
final int parentBottom = child.getBottom() + params.bottomMargin;
int height = parentBottom - parentTop;
final int paddingVertical = Math.round((height - mIconSize) / 2);
BitmapDrawable drawable;
if(drawables.size()!=0)drawable = drawables.get(i);
else drawable = null;
if(drawable!=null){
drawable.setBounds(parentLeft + mLeftPadding, parentTop + paddingVertical,
parentRight - mRightPadding, parentBottom - paddingVertical);
drawable.draw(canvas);
} else {
String link = findPlaceById(params.getPlaceId(),mStageList).getImg();
Picasso.with(context).load(link).resize(150,150).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapDrawable d = new BitmapDrawable(context.getResources(),bitmap);
drawables.add(d);
parent.invalidateItemDecorations();
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
}
}