继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

android开发仿ios菊花LoadingView特效

一只斗牛犬
关注TA
已关注
手记 338
粉丝 49
获赞 300

最近抽空仿着iOS上的菊花加载效果,自己实现了个,效果感觉还行,于是写篇博客贴出来,供大家参考


5b9608470001d05c00540355.jpg


自定义view无非就是那几步,首先分析要实现的效果,采用那些方式实现比较好,然后是否需要自定义属性, 测量布局是否需要重写这样, 最重要还是onDraw中画出来.

废话少讲,直接上代码:

ChrysanthemumLoadingView.Java


  1. private int mWidth;  

  2.     private int mHeight;  

  3.     private int mCenterX;  

  4.     private int mCenterY;  

  5.     private Paint mPaint;  

  6.     private final int mDefaultColor = 0xff999999;  

  7.     private final int mDefaultSegmentWidth = 10;  

  8.     private final int mDefaultSegmentLength = 20;  

  9.     private int mSegmentWidth = mDefaultSegmentWidth;  

  10.     private int mSegmentColor = mDefaultColor;  

  11.     private int mSegmentLength = mDefaultSegmentLength;  

  12.   

  13.     private int control = 1;  

  14.   

  15.     public ChrysanthemumLoadingView(Context context) {  

  16.         this(context, null);  

  17.     }  

  18.   

  19.     public ChrysanthemumLoadingView(Context context, @Nullable AttributeSet attrs) {  

  20.         this(context, attrs, 0);  

  21.     }  

  22.   

  23.     public ChrysanthemumLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  

  24.         super(context, attrs, defStyleAttr);  

  25.         init(context, attrs);  

  26.     }  

  27.   

  28.     private void init(Context context, AttributeSet attrs) {  

  29.         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ChrysanthemumLoadingView);  

  30.         int indexCount = typedArray.getIndexCount();  

  31.         for (int i = 0; i < indexCount; i++) {  

  32.             int attr = typedArray.getIndex(i);  

  33.             switch (attr){  

  34.                 case R.styleable.ChrysanthemumLoadingView_pathColor:  

  35.                     mSegmentColor = typedArray.getColor(attr,mDefaultColor);  

  36.                     break;  

  37.                 case R.styleable.ChrysanthemumLoadingView_segmentLength:  

  38.                     mSegmentLength = typedArray.getDimensionPixelSize(attr,mDefaultSegmentLength);  

  39.                     break;  

  40.                 case R.styleable.ChrysanthemumLoadingView_segmentWidth:  

  41.                     mSegmentWidth = typedArray.getDimensionPixelSize(attr,mDefaultSegmentWidth);  

  42.                     break;  

  43.             }  

  44.         }  

  45.         typedArray.recycle();  

  46.   

  47.         mPaint = new Paint();  

  48.         mPaint.setAntiAlias(true);  

  49.         mPaint.setStrokeCap(Paint.Cap.ROUND);  

  50.         mPaint.setStyle(Paint.Style.STROKE);  

  51.         mPaint.setColor(mSegmentColor);  

  52.         mPaint.setStrokeWidth(mSegmentWidth);  

  53.   

  54.     }  

  55.   

  56.     @Override  

  57.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  

  58.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  

  59.         mWidth = MeasureSpec.getSize(widthMeasureSpec);  

  60.         mHeight = MeasureSpec.getSize(heightMeasureSpec);  

  61.         mCenterX = mWidth / 2;  

  62.         mCenterY = mHeight / 2;  

  63.     }  

  64.   

  65.     @Override  

  66.     protected void onDraw(Canvas canvas) {  

  67.         super.onDraw(canvas);  

  68.         for (int i = 0; i < 12; i++) {  

  69.             mPaint.setAlpha(((i + 1 + control) % 12 * 255) / 12);  

  70.             canvas.drawLine(mCenterX, mCenterY - mSegmentLength, mCenterX, mCenterY - mSegmentLength*2, mPaint);  

  71.             canvas.rotate(30, mCenterX, mCenterY);  

  72.         }  

  73.     }  

  74.   

  75.     @Override  

  76.     protected void onFinishInflate() {  

  77.         super.onFinishInflate();  

  78.         ValueAnimator valueAnimator = ValueAnimator.ofInt(12, 1);  

  79.         valueAnimator.setDuration(1000);  

  80.         valueAnimator.setInterpolator(new LinearInterpolator());  

  81.         valueAnimator.setRepeatCount(ValueAnimator.INFINITE);  

  82.         valueAnimator.setRepeatMode(ValueAnimator.RESTART);  

  83.         valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  

  84.             @Override  

  85.             public void onAnimationUpdate(ValueAnimator animation) {  

  86.                 control = (int) animation.getAnimatedValue();  

  87.                 invalidate();  

  88.             }  

  89.         });  

  90.         valueAnimator.start();  

  91.     }</span>  


onFinishInflate()就是在activity中布局加载完毕后调用的方法, 在里边真正开启的loadingview交替运行的效果.


绘制的原理就是先画出一段line, 然后将canvas旋转,此例是旋转30度,我们都知道圆的一周是360度,这样正好需要绘制12个线段,然后每次画布旋转30度即可.

在布局中使用:


  1. <com.xxx.ChrysanthemumLoadingView  

  2.                 android:layout_width="100dp"  

  3.                 android:layout_height="100dp"  

  4.                 android:layout_centerHorizontal="true"  

  5.                 app:pathColor="#000000"  

  6.                 app:segmentLength="7sp"  

  7.                 app:segmentWidth="3sp" />

由于是自定义view, 已经用到了自定义属性,需要声明:


  1. xmlns:app="http://schemas.android.com/apk/res-auto"


这个声明不要忘记添加.


然后就是看到的效果:


5b9608470001d05c00540355.jpg

原文链接:http://www.apkbus.com/blog-914653-68483.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP

热门评论

你这自定义view会存在明显的内存泄漏问题

查看全部评论