上一篇实现多叶子飘动旋转,今天完成最后的功能。
1、添加右侧旋转枫叶
2、添加滑动条效果,显示百分比
3、修复叶子飘出边框问题
1、添加右侧旋转叶子
Bitmap turnBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.fengshan, null)).getBitmap(); int turnLeafAngle = 0; private void setTurnLeaf(Canvas canvas) { Matrix matrix = new Matrix(); turnLeafAngle = turnLeafAngle + 3; matrix.postTranslate((width - rightCircleWidth/2 - turnBitmap.getWidth()/2), (height - rightCircleWidth/2 - turnBitmap.getHeight()/2)); matrix.postRotate(turnLeafAngle, width - rightCircleWidth/2 - turnBitmap.getWidth()/2 + turnBitmap.getWidth()/2, height - rightCircleWidth/2 - turnBitmap.getHeight()/2 + turnBitmap.getHeight()/2); canvas.drawBitmap(turnBitmap, matrix, new Paint()); }
代码很明确,首先通过Matrix.postTranslate(float dx, float dy)把turnBitMap定位到最右侧圆圈
再通过Matrix.postRotate(float degress, float dx, float dy);设置旋转角度,每次角度+3°
其中degress为旋转角度,(dx,dy)为旋转中心点坐标
2、添加滑动效果
原理就是覆盖一层不同颜色的图层。根据当前百分比,分别画一个半圆,画一个正方形
a、定义一个圆形Rectf(为什么不是半圆?因为画圆弧的其实角度从水平线右侧开始)
progressArcRectf = new RectF(0, 0, height, height);
b、定义一个长方形Rectf,长方形x坐标起点即时圆形半径
progressRectf = new RectF(height/2, 0, width, height);
c、画出圆弧Canvas.drawArc(Rectf rectf, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
startAngle:起始角度,默认从右侧水平线开始
sweepAngle:为旋转的角度,顺时针旋转
useCenter:true只画出弧线,false则画出圆心到弧线的区域
//画滑动后的背景条 int currentProgressWidht = currentProgress * (width - borderWidth)/100; if(currentProgressWidht
给LeafView.java添加一个
public void setCurrentProgress(int currentProgress) { this.currentProgress = currentProgress; }
3、修复叶子飘动范围
这个简单,就是设置叶子的rect坐标起点+边框距离
赋上所有代码
1、activity_leaf.xml
<&#63;xml version="1.0" encoding="utf-8"&#63;>
2、LeafView.java
import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.jar.Attributes; /** * Created by jiemiao.zhang on 2017-3-15. */ public class LeafView extends View { private String TAG = "--------LeafView"; private Resources mResources; //背景图、叶子 private Bitmap mLeafBitmap, bgBitmap, turnBitmap; //整个控件的宽度和高度 private int width, height; //最外层边框宽度 private int borderWidth; //右侧圆形直径 private int rightCircleWidth; //左侧圆形直径 private int leftCircleWidth; private Paint bgPaint; private RectF bgRect; private Rect bgDestRect; //进度条实时背景 private Paint progressBgPaint; //进度条左侧半圆,进度条中间长方形部分Rect private RectF progressArcRectf, progressRectf; //当前百分比0~100 private int currentProgress = 0; //存放叶子lsit private ListleafList; //叶子的宽和高 private int mLeafWidth, mLeafHeight; //叶子滑动一周的时间5秒 private final static long cycleTime = 5000; //叶子数量 private final static int leafNumber = 6; public LeafView(Context context, AttributeSet attrs) { super(context, attrs); mResources = getResources(); mLeafBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf, null)).getBitmap(); mLeafWidth = mLeafBitmap.getWidth(); mLeafHeight = mLeafBitmap.getHeight(); turnBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.fengshan, null)).getBitmap(); bgBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf_kuang, null)).getBitmap(); bgPaint = new Paint(); bgPaint.setColor(mResources.getColor(R.color.bg_color)); //进度条实时背景 progressBgPaint = new Paint(); progressBgPaint.setColor(mResources.getColor(R.color.progress_bg_color)); //获取所有叶子的信息,放入list leafList = getLeafs(leafNumber); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = w; height = h; borderWidth = height * 10/64; rightCircleWidth = width * 62/303; leftCircleWidth = height - 2 * borderWidth; bgDestRect = new Rect(0, 0 , width, height); bgRect = new RectF(0, 0 , width, height); progressArcRectf = new RectF(borderWidth, borderWidth, height - borderWidth, height - borderWidth); progressRectf = new RectF(borderWidth+(height-2*borderWidth)/2, borderWidth, width-rightCircleWidth/2, height-borderWidth); Log.i("leftMarginWidth", (borderWidth + leftCircleWidth/2) + ""); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画背景颜色到画布 canvas.drawRect(bgRect, bgPaint); if(currentProgress <= 100) { //画叶子 int size = leafList.size(); for (int i=0; i 3) { canvas.drawText(currentProgress + "%", textX, height/2 + 10,paintText); } } //获取每片叶子在XY轴上的滑动值 private void getLocation(Leaf leaf) { float betweenTime = leaf.startTime - System.currentTimeMillis(); //周期结束再加一个cycleTime if(betweenTime <0) { leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime)); betweenTime = cycleTime; } //通过时间差计算出叶子的坐标 float fraction = (float) betweenTime / cycleTime; float x = (int)(width * fraction); //防止叶子飘出边框 leaf.x = x (height - borderWidth) &#63; (height - borderWidth) : y; y = y getLeafs(int leafSize) { List list = new LinkedList (); for (int i=0; i
最后再看下效果
总结
看过前5篇的很好理解,用到的技术点之前都讲到了。这篇主要就是几个百分比函数的计算。
比如设置半圆时弧度如何计算,圆弧对应的百分比,滑动区域长方形的起点坐标计算,去掉边框后的坐标计算
画半圆必须要有一个完整圆形Rect,因为drawArc()从右侧半径水平起始角度,顺时针。然功能要求我们从左侧圆形开始画,所以要通过一个算法,假如当前百分比为4%,需要画30°的圆弧,那么起始角度为165°=180°-15°,画出角度30%
通过matrix.postRotate()实现旋转功能时,必须加上当前view的坐标及二分之一长宽
需要图片等信息的可以从下面的Github地址下载,不过原文比较复杂
参考 https://github.com/Ajian-studio/GALeafLoading
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。