0

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.

Lukas Anda
  • 716
  • 1
  • 9
  • 30

1 Answers1

0

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) {
                }
            });
        }
    }
}
tynn
  • 38,113
  • 8
  • 108
  • 143