I make a progress bar. It is not monochromatic, but gradient, so adding a layout to a layout does not roll, it is necessary that the gradient does not expand on the progress, but opens. Rummaged through the open spaces and made such a decision

public class LineProgressBar extends FrameLayout { Bitmap maskBitmap; Paint p; Paint q; PorterDuffXfermode porterDuffXfermode; private int height; private int width; private int progressMaskWidth; public LineProgressBar(Context context) { super(context); init(); } public LineProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { height = getResources().getDimensionPixelSize(R.dimen.line_progress_bar_height); width = Decorator.screenWidthPix; progressMaskWidth = width; if (getLayoutParams() == null) { setLayoutParams(new ViewGroup.LayoutParams(width, height)); } else { getLayoutParams().height = height; getLayoutParams().width = width; } p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setStyle(Paint.Style.FILL_AND_STROKE); p.setColor(Color.TRANSPARENT); q = new Paint(Paint.ANTI_ALIAS_FLAG); porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN); invalidateBitmap(); setLayerType(LAYER_TYPE_SOFTWARE, null); setBackground(new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, new int[]{0xff3bffb7, 0xff1ce9ff, 0xffcc9dfc})); } private void invalidateBitmap() { maskBitmap = Bitmap.createBitmap(progressMaskWidth, this.height, Bitmap.Config.ARGB_8888); invalidate(); } // public void setAlignedView(View view){ // if (view.getLayoutParams() != null && view.getLayoutParams().width > 0) { // width = view.getLayoutParams().width; // progressMaskWidth = width; // invalidate(); // } // } @Override protected void onDraw(Canvas canvas) { q.setXfermode(porterDuffXfermode); canvas.drawBitmap(maskBitmap, width - progressMaskWidth, 0, q); q.setXfermode(null); } public void setProgress(int percent) { if (percent < 100) { progressMaskWidth = (int) ((100 - percent) * ((double) width / 100)); } else { progressMaskWidth = 1; } invalidateBitmap(); } } 

When setting progress, we calculate the width of the mask, and in ondraw we place it at the end of the view. On pre-lollipop, everything works perfectly, but on the 21+ version of the android mask it turns out not transparent, but black. How can I handle such a case? I support the API until the 16th, inclusive, and I would not like to get away from it.

    1 answer 1

    And what is the standard progress bar you are not satisfied with? You assign him such a pgogressDrawable and you don’t need to write any of your widgets ...

     <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/progress"> <clip> <shape> <gradient android:startColor="#ff3bffb7" android:centerColor="#ff1ce9ff" android:endColor="#ffcc9dfc" /> </shape> </clip> </item> </layer-list> 
    • How to write on en-so - best answer ever. Thanks a lot - iamthevoid