您的位置:首页 > 移动开发 > Android开发

Android MaterialProgressDrawable类

2016-07-25 21:20 543 查看

一:常用方法

返回值方法和描述
voidupdateSizes(int size)
设置大小,可以选LARGE、DEFAULT
voidshowArrow(boolean show)
设置是否显示箭头
voidsetArrowScale(float scale)
设置箭头缩放大小,0f~1f
voidsetStartEndTrim(float startAngle, float endAngle)
设置进度条的开始和结尾,也就是长度,范围0f~1f,比如
setStartEndTrim(0f,0.8f)
voidsetProgressRotation(float rotation)
设置旋转角度,0f~1f
voidsetBackgroundColor(int color)
设置背景颜色
voidsetColorSchemeColors(int… colors)
设置进度条的颜色,可以是多种颜色,转一圈换一个
voidsetAlpha(int alpha)
设置透明度,0-255,
注意:默认一开始透明度是0
voidstart()
开始转圈动画
voidstop()
终止进行中的动画,并且将进度条长度归零
intgetAlpha()
获取当前透明度
intgetIntrinsicHeight()
获取Drawable高度
intgetIntrinsicWidth()
获取Drawable宽度

二:使用

从v4包复制MaterialProgressDrawable类,改为public class

初始化

private final int CIRCLE_BG_LIGHT = 0xFFFAFAFA;//背景颜色十六进制值
public void init() {
//parent是mImageView的父布局,用于启动动画,不能为null
mProgress = new MaterialProgressDrawable(this, parent);
mProgress.setBackgroundColor(CIRCLE_BG_LIGHT);
mProgress.setColorSchemeColors(colors);
mImageView.setImageDrawable(mProgress);
}


注意: setBackgroundColor和setColorSchemeColors设置的颜色值不能之间使用R.color.xx,可以使用颜色的十六进制,如0xFFFAFAFA,或者 getResources().getColor(R.color.xx)转换成十六进制

启动:

mProgress.setAlpha(255);
mProgress.setStartEndTrim(0f, 0.8f);
mProgress.setArrowScale(1f); //0~1之间
mProgress.setProgressRotation(1);
mProgress.showArrow(true);
mProgress.start();


停止

mProgress.stop();


三:源码

设置ring的基本参数,根据Density转换成px,适配各种分辨率

//设置各个参数,使用updateSizes()方法修改样式DEFAULT和LARGE
private void setSizeParameters(double progressCircleWidth, double progressCircleHeight,
double centerRadius, double strokeWidth, float arrowWidth, float arrowHeight) {
final Ring ring = mRing;
final DisplayMetrics metrics = mResources.getDisplayMetrics();
final float screenDensity = metrics.density;//获取屏幕密度
//设置各个参数,乘以screenDensity为了从dp转为px
mWidth = progressCircleWidth * screenDensity;
mHeight = progressCircleHeight * screenDensity;
ring.setStrokeWidth((float) strokeWidth * screenDensity);
ring.setCenterRadius(centerRadius * screenDensity);
ring.setColorIndex(0);
ring.setArrowDimensions(arrowWidth * screenDensity, arrowHeight * screenDensity);
ring.setInsets((int) mWidth, (int) mHeight);
}


主要的绘制工作都在ring中

/**
* Draw the progress spinner
*/
public void draw(Canvas c, Rect bounds) {
final RectF arcBounds = mTempBounds;
arcBounds.set(bounds);
arcBounds.inset(mStrokeInset, mStrokeInset);

final float startAngle = (mStartTrim + mRotation) * 360;
final float endAngle = (mEndTrim + mRotation) * 360;
float sweepAngle = endAngle - startAngle;

mPaint.setColor(mCurrentColor);
//绘制弧线
c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
//绘制三角形
drawTriangle(c, startAngle, sweepAngle, bounds);
//当透明度小于255,透明度值和弧线三角形正好相反
if (mAlpha < 255) {
mCirclePaint.setColor(mBackgroundColor);
mCirclePaint.setAlpha(255 - mAlpha);
c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
mCirclePaint);
}
}


动画:

//设置动画
private void setupAnimators() {
final Ring ring = mRing;
final Animation animation = new Animation() {
//第一个参数为动画的进度时间值,取值范围为[0.0f,1.0f],第二个参数Transformation记录着动画某一帧中变形的原始数据。该方法在动画的每一帧显示过程中都会被调用。
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
//只在start方法中,起始角度和终止角度不一样时设置为true,当第一次动画结束后设置为false
if (mFinishing) {
applyFinishTranslation(interpolatedTime, ring);//设置ring的值和颜色
} else {
// The minProgressArc is calculated from 0 to create an
// angle that matches the stroke width.
final float minProgressArc = getMinProgressArc(ring);
final float startingEndTrim = ring.getStartingEndTrim();
final float startingTrim = ring.getStartingStartTrim();
final float startingRotation = ring.getStartingRotation();

updateRingColor(interpolatedTime, ring);

// Moving the start trim only occurs in the first 50% of a
// single ring animation
//前面半部分只设置起点的值
if (interpolatedTime <= START_TRIM_DURATION_OFFSET) {
// scale the interpolatedTime so that the full
// transformation from 0 - 1 takes place in the
// remaining time
final float scaledTime = (interpolatedTime)
/ (1.0f - START_TRIM_DURATION_OFFSET);
final float startTrim = startingTrim
+ ((MAX_PROGRESS_ARC - minProgressArc) * MATERIAL_INTERPOLATOR
.getInterpolation(scaledTime));
ring.setStartTrim(startTrim);
}

// Moving the end trim starts after 50% of a single ring
// animation completes
// 后半部分只设置终点的值
if (interpolatedTime > END_TRIM_START_DELAY_OFFSET) {
// scale the interpolatedTime so that the full
// transformation from 0 - 1 takes place in the
// remaining time
final float minArc = MAX_PROGRESS_ARC - minProgressArc;
float scaledTime = (interpolatedTime - START_TRIM_DURATION_OFFSET)
/ (1.0f - START_TRIM_DURATION_OFFSET);
final float endTrim = startingEndTrim
+ (minArc * MATERIAL_INTERPOLATOR.getInterpolation(scaledTime));
ring.setEndTrim(endTrim);
}

//没看出来有什么作用。。
final float rotation = startingRotation + (0.25f * interpolatedTime);
ring.setRotation(rotation);
//总角度为1080,分5圈转完
// ((FULL_ROTATION / NUM_POINTS) * interpolatedTime) 当前动画需要转的角度
//(FULL_ROTATION * (mRotationCount / NUM_POINTS)) 承接上一圈转的角度
//如第一圈,角度从0~216,第二圈216~432...第五圈864~1080。在draw(canvas)中设置canvas角度旋转
float groupRotation = ((FULL_ROTATION / NUM_POINTS) * interpolatedTime)
+ (FULL_ROTATION * (mRotationCount / NUM_POINTS));
setRotation(groupRotation);//设置旋转的角度并更新,调用draw()
}
}
};
animation.setRepeatCount(Animation.INFINITE);
animation.setRepeatMode(Animation.RESTART);
animation.setInterpolator(LINEAR_INTERPOLATOR);
animation.setAnimationListener(new Animation.AnimationListener() {

@Override
public void onAnimationStart(Animation animation) {
mRotationCount = 0;
}

@Override
public void onAnimationEnd(Animation animation) {
// do nothing
}

@Override
public void onAnimationRepeat(Animation animation) {
//记录完成动画时的角度信息
ring.storeOriginals();
//下一个颜色
ring.goToNextColor();
ring.setStartTrim(ring.getEndTrim());
if (mFinishing) {
//完成第一个动画,关闭箭头,SwipeRefreshLayout中向下拉完成后
mFinishing = false;
animation.setDuration(ANIMATION_DURATION);
ring.setShowArrow(false);
} else {
mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
}
}
});
mAnimation = animation;
}


第一遍动画调用applyFinishTranslation完成,之后关闭箭头,开始新的动画,每次的动画是前50%只更改起点位置,后50%只更改终点位置,通过一系列的计算,旋转canvas

参考资料:http://blog.csdn.net/tyzlmjj/article/details/50557397
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android