androidandroid-drawableshimmer

Rounded shimmerDrawable (facebook android-shimmer)


So, i have drawable from https://github.com/facebook/shimmer-android

val shimmer = ColorHighlightBuilder()
            .setBaseColor(ContextCompat.getColor(context, R.color.skeleton_mask))
            .setBaseAlpha(SHIMMERING_BASE_ALPHA)
            .setHighlightAlpha(SHIMMERING_HIGHLIGHT_ALPHA)
            .setHighlightColor(ContextCompat.getColor(context, R.color.skeleton_shimmer))
            .setDuration(SHIMMERING_DURATION)
            .setDirection(Shimmer.Direction.LEFT_TO_RIGHT)
            .setAutoStart(true)
            .build()

val shimmerDrawable = ShimmerDrawable()
shimmerDrawable.setShimmer(shimmer)

Problem: this drawable has Rect shape, which is being shimmered.

But i want it to be Rect with rounded corners. Is there any solutions, except contributing to library and modifying ShimmerDrawable ? Maybe some wrapping into another drawable, idk

This library has issue about rounded corners https://github.com/facebook/shimmer-android/issues/84 but only solution available is wrapping view holding this drawable with CardView, i do not want this


Solution

  • Well looking at the source code of ShimmerDrawable.java, it's not that hard to implement what you want. There are several things that needs to be changed slightly.

    // private final Rect mDrawRect = new Rect();
    private final RectF mDrawRect = new RectF();
    
    ...
    
    // canvas.drawRect(mDrawRect, mShimmerPaint);
    canvas.drawRoundRect(mDrawRect, 50f, 50f, mShimmerPaint);
    

    And that is it. But you probably want to modify it a little bit more for your own convenience. If so, ignore the above code and follow the following code.

    // private final Rect mDrawRect = new Rect();
    private final RectF mDrawRect = new RectF();
    
    private final float xRadius;
    private final float yRadius;
    
    public ShimmerDrawable(final float xRadius, final float yRadius) {
        mShimmerPaint.setAntiAlias(true);
        this.xRadius = xRadius;
        this.yRadius = yRadius;
    }
    
    ...
    
    // canvas.drawRect(mDrawRect, mShimmerPaint);
    canvas.drawRoundRect(mDrawRect, xRadius, yRadius, mShimmerPaint);
    

    Later, you can create a ShimmerDrawable with:

    val shimmerDrawable = ShimmerDrawable(50f, 50f)
    
    ShimmerDrawable shimmerDrawable = new ShimmerDrawable(50f, 50f);
    

    And to be portable across different screen densities, you might also want to convert the values of xRadius and yRadius before creating the ShimmerDrawable.

    private final int dpToPx(final Context context,final float dp)
    {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
    }