自定义Drawable Demo(圆角/圆形图片,Material动画)
2016-05-16 11:37
645 查看
自定义Drawable Demo(圆角/圆形图片,Material动画)
参考:https://github.com/dinuscxj/LoadingDrawable本项目地址:https://github.com/Blankeer/DrawableDemo
效果图:
蓝色的load是自定义的,红色的是系统的ProgressBar
RoundImageDrawable(圆角图片)
bitmap图片的设置
mPaint = new Paint(); BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setAntiAlias(true); mPaint.setShader(bs);
绘制圆角
canvas.drawRoundRect(mRectF, radius, radius, mPaint);
CircleImageDrawable (圆形图片)
绘制圆形canvas.drawCircle(radius, radius, radius, mPaint);
MaterialLoadDrawable
模仿material design progerss动画.将动画分为两个阶段
s代表当前弧度开始绘制角度,e代表当前弧度结束绘制角度,max表示角度的最大值,比如360*0.8,min则相反,比如5度,
cs表示每圈开始绘制的角度
第一个阶段:s=cs,e从cs->max+min+cs
第二个阶段:e=max+min+cs,s从cs->max+cs
上面是第0圈的主要流程,需要记录的是每次开始的起始角度cs,
每圈结束后的s值即为下一圈的cs值。
第0圈,cs=0;
第1圈,cs=max;
第2圈,cs=(2*max)%360;
…
主要代码:
private void setup() { mColor = DEFAULT_COLOR; mWidth = mHeight = DEFAULT_SIZE; mInsetValue = DEFAULT_INSET; mMindFraction = DEFAULT_MINDFRACTION; mStrokeWidth = DEFAULT_STROKE_WIDTH; rectf = new RectF(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(mColor); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeCap(Paint.Cap.ROUND); mDuration = DEFAULT_DURATION; mAnimator = ValueAnimator.ofFloat(0F, 1F);//属性动画初始化 mAnimator.setDuration(mDuration); mAnimator.setRepeatMode(ValueAnimator.RESTART);//设置反复动画 mAnimator.setRepeatCount(ValueAnimator.INFINITE); mAnimator.setInterpolator(new FastOutSlowInInterpolator());//插值器 mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { animUpdate(animation.getAnimatedFraction()); invalidateSelf(); } }); mAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationRepeat(Animator animation) { super.onAnimationRepeat(animation); count++; mCurrentStartAngle = mStartAngle;//保存开始角度 } @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); count = 0; } }); mCurrentStartAngle = 0; } public void start() { mAnimator.start(); } public void stop() { mAnimator.cancel(); } private void animUpdate(float fraction) { mCanvasRotate += 2;//画布旋转每次增加量,可自己调节 if (fraction <= mMindFraction) {//第一阶段 //最小角度是值,fraction为0时,还有一小段弧。思路是每次绘制多绘制minAngle的角度 mEndAngle = (DEFAULT_MAX_ANGLE + DEFAULT_MIN_ANGLE) * (fraction / mMindFraction);//end只是相对start的位移 // 绘制总长度:(maxAngle+minAngle)/2,当前进度fraction/当前阶段百分比 if (mEndAngle < DEFAULT_MIN_ANGLE && count > 0) {//当绘制角度小于最小角度时,绘制最小角度 mEndAngle = DEFAULT_MIN_ANGLE;//第一圈不执行 } } else {//第二阶段 //绘制总角度是maxAngle,后面是所占百分比 mStartAngle = (DEFAULT_MAX_ANGLE) * ((fraction - mMindFraction) / (1 - mMindFraction)); //endAngle是总角度减startAngle mEndAngle = DEFAULT_MAX_ANGLE + DEFAULT_MIN_ANGLE - mStartAngle; mStartAngle = (mStartAngle + mCurrentStartAngle) % 360; } // System.out.println(fraction + "\t\t" + mStartAngle + "\t\t" + (mEndAngle + mStartAngle)); } @Override public void draw(Canvas canvas) { int canvasCopy = canvas.save();//保存画布 rectf.set(getBounds()); canvas.rotate(mCanvasRotate, getCenterX(), getCenterY());//旋转画布 rectf.inset(mInsetValue, mInsetValue); canvas.drawArc(rectf, mStartAngle, mEndAngle, false, mPaint); canvas.restoreToCount(canvasCopy);//恢复画布 }
相关文章推荐
- 使用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