您的位置:首页 > 移动开发 > Android开发

android仿ios菊花LoadingView

2017-07-12 14:12 411 查看
最近抽空仿着ios上的菊花加载效果,自己实现了个,效果感觉还行,于是写篇博客贴出来,供大家参考



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

废话少讲,直接上代码:

ChrysanthemumLoadingView.java

private int mWidth;
private int mHeight;
private int mCenterX;
private int mCenterY;
private Paint mPaint;
private final int mDefaultColor = 0xff999999;
private final int mDefaultSegmentWidth = 10;
private final int mDefaultSegmentLength = 20;
private int mSegmentWidth = mDefaultSegmentWidth;
private int mSegmentColor = mDefaultColor;
private int mSegmentLength = mDefaultSegmentLength;

private int control = 1;

public ChrysanthemumLoadingView(Context context) {
this(context, null);
}

public ChrysanthemumLoadingView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}

public ChrysanthemumLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ChrysanthemumLoadingView);
int indexCount = typedArray.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int attr = typedArray.getIndex(i);
switch (attr){
case R.styleable.ChrysanthemumLoadingView_pathColor:
mSegmentColor = typedArray.getColor(attr,mDefaultColor);
break;
case R.styleable.ChrysanthemumLoadingView_segmentLength:
mSegmentLength = typedArray.getDimensionPixelSize(attr,mDefaultSegmentLength);
break;
case R.styleable.ChrysanthemumLoadingView_segmentWidth:
mSegmentWidth = typedArray.getDimensionPixelSize(attr,mDefaultSegmentWidth);
break;
}
}
typedArray.recycle();

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mSegmentColor);
mPaint.setStrokeWidth(mSegmentWidth);

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = MeasureSpec.getSize(widthMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec);
mCenterX = mWidth / 2;
mCenterY = mHeight / 2;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < 12; i++) {
mPaint.setAlpha(((i + 1 + control) % 12 * 255) / 12);
canvas.drawLine(mCenterX, mCenterY - mSegmentLength, mCenterX, mCenterY - mSegmentLength*2, mPaint);
canvas.rotate(30, mCenterX, mCenterY);
}
}

@Override
protected void onFinishInflate() {
super.onFinishInflate();
ValueAnimator valueAnimator = ValueAnimator.ofInt(12, 1);
valueAnimator.setDuration(1000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
control = (int) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.start();
}


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

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

在布局中使用:

<com.xxx.ChrysanthemumLoadingView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
app:pathColor="#000000"
app:segmentLength="7sp"
app:segmentWidth="3sp" />
由于是自定义view, 已经用到了自定义属性,需要声明:

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


这个声明不要忘记添加.

然后就是看到的效果:



最后, 奉上自己正在更新完善的Github项目,https://github.com/MrDeclanCoder/KotlinMVPRxJava2Dagger2GreenDaoRetrofitDemo  
我平常练手的项目使用了一些框架以及自己写的自定义View,点进去看一下,可能有你能用到的,欢迎star!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: