实现一个Material效果的ProgressBar
来源:互联网 发布:淘宝号出售批发 编辑:程序博客网 时间:2024/05/20 04:09
先来看看效果:
分析下难点:
1. 动画的实现;
2. 边界的控制;
3. 状态保存与恢复;
4. 两种状态的实现,loading状态(不停旋转)、progress状态。
分别来看下。
1. 动画如何实现:
将动画进行拆解,可以发现它其实是一个弧不断变长变短的一个过程+弧本身在绕圆形转动两部分组成。
所以可以分开来处理,弧度变长变短可以通过canvas.drawArc的参数startAngle/SweeepAngle控制,只要改变这两个值即可实现效果。怎么改变?有几种方案,1是通过hander+thread;2是通过View.post();3是通过PropertyAnimation.
弧本身绕圆心运动可以通过Canvas.rotate实现。
private static final float delta = 6f; private float temp = 0; class AnimRunnable implements Runnable{ @Override public void run() { if (mStartAngle == temp) { mSweepAngle += delta; } if (mSweepAngle >= 280 || mStartAngle > temp) { mStartAngle += delta; if(mSweepAngle > 20) { mSweepAngle -= delta; } } if (mStartAngle > temp + 280) { temp = mStartAngle; mStartAngle = temp; mSweepAngle = 20; } postInvalidate(); postDelayed(this,mSpinSpeed); } }
2.边界的控制:
需要在onMeasure中控制。在onSizeChanged方法中可以拿到最终的width、height,通过width/height就可以控制progressbar的边界了。
需要注意的是,边界需要是正方形的,所以得考虑宽高不相等的情况以及四个方向padding的大小。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //计算自己需要的宽度和高度 int width = mCircleRadius*2; int height = mCircleRadius*2; //考虑父容器的测量规则 setMeasuredDimension(getResolvedSize(width, widthMeasureSpec), getResolvedSize(height, heightMeasureSpec)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); //简化处理,以最大的padding作为padding int padding = Math.max(Math.max(paddingLeft, paddingRight), Math.max(paddingTop, paddingBottom)); int diameter; //保证bounds是一个正方形 if(w >= h){ diameter = h; mBounds = new RectF(padding+mBarWidth+(w-h)/2,padding+mBarWidth,diameter-padding-mBarWidth+(w-h)/2,diameter-padding-mBarWidth); }else if(w < h){ diameter = w; mBounds = new RectF(padding+mBarWidth,padding+mBarWidth+(h-w)/2,diameter-padding-mBarWidth,diameter-padding-mBarWidth+(h-w)/2); } }
3.状态的保存与恢复:
progressbar的状态不能因为横竖屏切换等问题丢失,所以需要通过重写onSaveInstanceState/onRestoreInstanceState来保存/恢复状态.
@Override protected void onRestoreInstanceState(Parcelable state) { if(! (state instanceof SavedState)){ super.onRestoreInstanceState(state); return; } //先恢复父类的状态 SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); //在恢复自己的状态 this.mCurMode = savedState.mCurMode == 0 ? Mode.INDETERMINATE : Mode.DETERMINATE; this.mRimWidth = savedState.mRimWidth; this.mRimColor = savedState.mRimColor; this.mBarColor = savedState.mBarColor; this.mBarWidth = savedState.mBarWidth; this.showRim = savedState.showRim; this.isAnimStart = savedState.isAnimStart; this.mProgress = savedState.mProgress; } @Override protected Parcelable onSaveInstanceState() { //相当于是做了一层包装 //先保存父类的状态,然后包装,再保存自己的状态 Parcelable parcelable = super.onSaveInstanceState(); SavedState savedState = new SavedState(parcelable); savedState.mCurMode = (this.mCurMode == Mode.INDETERMINATE) ? 0 : 1; savedState.mRimWidth = this.mRimWidth; savedState.mRimColor = this.mRimColor; savedState.mBarColor = this.mBarColor; savedState.mBarWidth = this.mBarWidth; savedState.showRim = this.showRim; savedState.isAnimStart = this.isAnimStart; savedState.mProgress = this.mProgress; return savedState; }
4.两种状态的实现:
自然是通过一个变量记录当前模式,在onDraw中通过判断模式进行不同的绘制操作。
地址:https://github.com/Rowandjj/MaterialProgressBar/
3 0
- 实现一个Material效果的ProgressBar
- android自定义view实现progressbar的效果
- 实现Material Design水波效果的Button
- Material Design效果实现
- 简单实现一个自定义view的ProgressBar
- 自定义progressBar的效果
- 兼容低版本的 Material Design ProgressBar
- 5.0的Material ProgressBar颜色修改方案
- C# 多线程实现ProgressBar效果
- progressBar图片旋转效果实现
- C# 重写 Listview 的 OnDrawSubItem 函数实现 ProgressBar 进度条效果
- 用shape实现progressbar的转圈效果控制转速
- Android高级UI ProgressBar实现各种效果的圆形进度
- Material Design一些效果实现
- android Material Design之 ToolBar+TabLayout+recycleView的效果实现
- Material Design实现之 CoordinatorLayout的滚动效果
- Material Design recyclerview+floatingactionbutto实现联动的效果
- 实现Material Design风格的点击水波荡漾效果
- string与char*和char[]的互相转换
- 关于我的机房收费系统
- HDU 1150
- 转:Qt运行cmd命令
- 个推Android SDK实现透传消息的最小Manifest.xml配置
- 实现一个Material效果的ProgressBar
- 黑马程序员---Foundation - NSString
- 二叉搜索树(Binary Search Tree)
- (C/C++学习笔记)多继承的二义性
- ubuntu(English)下安装搜狗拼音
- 再看设计模式之策略模式
- 数据结构 第一遍导图
- eoj 1848 你是ACM吗?
- ModifyMenu的用法