Android Implements IOS11 Control Center Schedule Bar

IOS 11 has released beta, and I believe some of the partners with the iphone are eager to upgrade.
So in this article, we use a simple custom View to implement a very novel progress bar in the control center similar to iOS 11.

Let's first look at the target effect map and the final result.


Target rendering

Achieving results

Custom Property Analysis

Name Interpretation
progressMax Maximum
progressValue Speed of progress
iconSrc Icon
bgColor background color
progressColor Progress color
progressOrientation direction
rectRadius Rounded arc
iconPadding icon Interior Spacing

In summary, the relevant attribute definition code is as follows:

    <declare-styleable name="RectProgress">
        <attr name="progressValue" format="integer" />
        <attr name="progressMax" format="integer" />
        <attr name="bgColor" format="color" />
        <attr name="rectRadius" format="dimension" />
        <attr name="iconPadding" format="dimension" />
        <attr name="progressColor" format="color" />
        <attr name="iconSrc" format="reference" />
        <attr name="progressOrientation">
            <enum name="vertical" value="1" />
            <enum name="horizontal" value="2" />
        </attr>
    </declare-styleable>

Progress Bar Drawing

Firstly, the composition of the next progress bar is analyzed.

  • background
  • Speed of progress
  • Icon

It seems very simple. Use canvas.drawRoundRect() to draw background and progress respectively, and finally add a bitmap.
However, in practice, we will find that it is not feasible to operate according to the idea of covering Background with Progress. The problem is that when drawing Progress, we deal with the upper corner.
The solution is to use Paint.setXfermode(); (For details of each Mode, see here . ) Here we use PorterDuff.Mode.SRC_ATOP.
This idea is described in vernacular: first draw a rounded background, and then draw a rectangular Progress on the basis of the rounded background. At this time, because Paint.setXfermode(); so the rectangular Progresses will only be shown on the intersection of the background.
(Note: Paint.setXfermode(); hardware acceleration needs to be turned off, otherwise it may not take effect: setLayerType(View.LAYER_TYPE_SOFTWARE, null);

So drawing progress code in ondraw() is actually very simple:

        //bgPaint is the background brush and progressPaint is the progress brush.
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();
        int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);
        {
            bgPaint.setColor(bgColor);
            // draw the background of progress
            canvas.drawRoundRect(bgRect, rectRadius, rectRadius, bgPaint);
            // draw progress
            canvas.drawRect(progressRect, progressPaint);
            bgPaint.setXfermode(null);
        }
        canvas.restoreToCount(layerId);

Handling of gestures

Here we only analyze the vertical direction of gesture processing, the horizontal direction is the same: gesture processing this logic is very simple. Logically, ACTION_DOWN is the same as ACTION_MOVE. Only one point needs to be addressed:

  • Considering the padding of View, it is necessary to determine whether ACTION_DOWN is processed in the progress bar or not.
    Main code:
              //bgRect background rectangle, progressRect progress rectangle
              if (event.getY() < bgRect.top) {
                  //Contacts beyond the top of Progress
                  progressRect.top = bgRect.top;
              } else if (event.getY() > bgRect.bottom) {
                  //Contacts over the bottom of Progress
                  progressRect.top = bgRect.bottom;
              } else {
                  progressRect.top = getPaddingTop() + event.getY();
              }

Icon Drawing

icon draws only one line of code:
canvas.drawBitmap(bitmap, srcRect, dstRect, bgPaint);
What needs to be explained is the parameters of this method.

  • Bitmap region to be drawn by srcRect
  • The area to be drawn by dstRect Bitmp

Callback

It is important to note that a callback is made only once per percentage change.

Project hosting address

https://github.com/CuiZhaoHui/IOS11RectProgress

The author's level is limited. If there are any mistakes, please correct them.~

Keywords: iOS Attribute github

Added by CtrlAltDel on Tue, 18 Jun 2019 21:26:43 +0300