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(); }