Android MaterialProgressDrawable类
2016-07-25 21:20
543 查看
一:常用方法
返回值 | 方法和描述 |
---|---|
void | updateSizes(int size) 设置大小,可以选LARGE、DEFAULT |
void | showArrow(boolean show) 设置是否显示箭头 |
void | setArrowScale(float scale) 设置箭头缩放大小,0f~1f |
void | setStartEndTrim(float startAngle, float endAngle) 设置进度条的开始和结尾,也就是长度,范围0f~1f,比如 setStartEndTrim(0f,0.8f) |
void | setProgressRotation(float rotation) 设置旋转角度,0f~1f |
void | setBackgroundColor(int color) 设置背景颜色 |
void | setColorSchemeColors(int… colors) 设置进度条的颜色,可以是多种颜色,转一圈换一个 |
void | setAlpha(int alpha) 设置透明度,0-255, 注意:默认一开始透明度是0 |
void | start() 开始转圈动画 |
void | stop() 终止进行中的动画,并且将进度条长度归零 |
int | getAlpha() 获取当前透明度 |
int | getIntrinsicHeight() 获取Drawable高度 |
int | getIntrinsicWidth() 获取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
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories