Android MaterialProgressDrawable类
来源:互联网 发布:数据分析是什么工作 编辑:程序博客网 时间:2024/06/08 14:37
一:常用方法
设置大小,可以选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
0 0
- Android MaterialProgressDrawable类
- Android 圆形进度条MaterialProgressDrawable
- MaterialProgressDrawable
- MaterialProgressDrawable v4包下圆形进度条
- MaterialProgressDrawable , 实现SwipeRefreshLayout的下拉效果的旋转动画效果
- UI组件——SwipeRefreshLayout源码解析——MaterialProgressDrawable的绘制
- android类
- [Android工具类]Android File工具类
- Android中的android.app.Application类
- [android] android源码中的 PduParser 类详解。
- [android] android framework中的 PhoneNumberUtils 类详解
- Android Log架构/Android Log工具类
- (Android design)新闻资讯类android客户端开源拉
- (Android design)新闻资讯类android客户端开源拉
- [Android UI开发] Android常用工具类
- [Android教程] android的 Http工具类
- 【Android】 Android之API类库整理
- Android类库介绍
- Linux启动tomcat报错Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000007aaa80000
- 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
- Linux MySql学习记录
- 03-树3 Tree Traversals Again
- 2016 cocoapods的安装和使用以及版本升级遇到的问题
- Android MaterialProgressDrawable类
- 解决<textarea>标签中的文字莫名其妙的居中的问题
- 修改源码自定义SwipeRefreshLayout样式——高仿微信朋友圈下拉刷新
- 自定义类加载器
- retrofit与响应式编程一:rxjava简介
- android中jni,内存优化,设计模式总结
- tinyint(1)和tinyint(4)的区别和用法
- fisher vector
- js闭包