Custom pull-down refresh rotation loading animation LoadingView

Keywords: Attribute github

brief introduction

When customizing a pull-down refresh, the progress is a LoadingView displayed according to the pull-down distance. An App Icon can be placed in the middle. Seeing is better than hearing. See the following figure for the specific effect:

Analysis of implementation ideas

The first step is to draw the outermost gray circle. It's very easy to draw the circle directly with canvas.
Step 2 draw the icon in the middle
The third step is to draw a blue progress circle, which starts with drawing an arc. Use canvas.drawArc to draw an arc (calculate a percentage according to the distance between the pull-down refresh and pull-down, and then 360 * percentage, which is the angle of the current blue progress circle arc, so that you can move forward with the pull-down distance and the progress continuously)
The fourth step supports rotation animation, which can be realized by attribute animation. The principle is that the starting angle of the drawn arc is from - 90 to 360

The first step is to draw the outermost circle

It's just canvas.drawCircle.

    @Override
    protected void onDraw(Canvas canvas) {
        //Draw the outermost gray circle
        //Calculating center of circle
        float cx = getWidth() / 2;
        float cy = getHeight() / 2;
        //radius
        float radius = (getWidth() / 2.0f - borderWidth);
        canvas.drawCircle(cx, cy, radius, mPaintGrey);

        super.onDraw(canvas);
    }

Step 2 draw the icon in the middle

The size of this icon may be uncertain. You need to scale the bitmap image according to the width and height of the current view to ensure that the icon is placed in the middle of the view circle.

//Calculate picture scaling
float scale = Math.min(getWidth() * 1.0f / (centerImg.getWidth()), (getHeight()) * 1.0f / centerImg.getHeight());

//Zoom picture
private Bitmap scaleBitmap(Bitmap bitmap, float scale) {
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        scaleImg = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        return scaleImg;
    }
    
//Draw middle Icon
canvas.drawBitmap(scaleImg, left, top, paint);

Step 3 draw a blue progress circle

//Draw a blue progress arc
canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaint);

Step 4: support circle animation

Use attribute animation to do this

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this,"startAngle",-90f, 270);//Animation values vary from - 90 to 270
objectAnimator.setDuration(1000);//Animation time
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);//Infinite repetition of animation

//Let our view support the property startAngle. Add a get set method to trigger the view redraw in the set method. Draw the blue progress circle in the onDraw method. Use the newly set starting angle.
public float getStartAngle() {
        return startAngle;
}
public void setStartAngle(float startAngle) {
        this.startAngle = startAngle;
        postInvalidate();
}

github source code

Posted by viv on Tue, 29 Oct 2019 07:53:27 -0700