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

Android——自定义View loading效果

2016-07-28 09:26 543 查看
一些android应用,都需要loading效果,比如登录,注册,加载一个网页等操作,都需要用到loading,网上也有很多很不错效果的例子,但是还是自己手动写一个比较实际。

就一个类,我贴出来:

package com.lai.loadingpoppoint;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
* 自定义loading效果
*/
public class LoadingPopPoint extends View {

private static final String TAG = "LoadingPopPoint";
private static final float MAX = 30;
private static final int STEP = 1;//第几步画

private static final int RADIUS = 80;
private static final float MOVING_RADIUS = 10f;
private static final float INCREASE = MOVING_RADIUS * 0.4f;

private double x;
private double y;

private float radius;
private static final int DEFAULT_NUMBER = 3;
private int pointNumber = DEFAULT_NUMBER;
//default colors
private int paintColor[] = {Color.parseColor("#3B8EFF"), Color.parseColor("#FFD81D"), Color.parseColor("#FF4A4B")};//三点颜色
private float progress[] = {0, MAX / 3, MAX / 3 * 2};
private List<Paint> paints;

/**
* 构造方法
* @param context
*/
public LoadingPopPoint(Context context) {
super(context);
init();
}

public LoadingPopPoint(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public LoadingPopPoint(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

/**
* 为三点设置颜色
*/
private void init() {
paints = new ArrayList<>();
for (int i = 0; i < pointNumber; i++) {
Paint paint = new Paint();
paint.setColor(paintColor[i]);
paints.add(paint);
}
}

/**
* 画视图
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < pointNumber; i++) {
progress[i] = progress[i] + STEP;
radius = getRadiusByProgress(progress[i]);//画出三个点之间的距离
canvas.drawCircle((float) (getWidth() / 2 + x), getHeight() / 2, radius, paints.get(i));
}
//每40毫秒重画视图,并显示动画
postInvalidateDelayed(40);
}

/**
* 计算当前X和Y,并返回这一点的半径
*
* @param progress
* @return
*/
private float getRadiusByProgress(float progress) {
//x y是全局的
x = RADIUS * Math.cos(Math.toRadians(((double) progress % MAX) / MAX * 360));
y = RADIUS * Math.sin(Math.toRadians(((double) progress % MAX) / MAX * 360));

if (y < 0) {
return (float) (MOVING_RADIUS + (1 - Math.abs(x) / RADIUS) * INCREASE);
} else {
return (float) (MOVING_RADIUS - (1 - Math.abs(x) / RADIUS) * INCREASE);
}
}

/**
*  自定义view 的大小
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));//决定view的大小
}

/**
* 获取view在屏幕中的位置
* @param measureSpec
* @param isWidth
* @return
*/
private int measure(int measureSpec, boolean isWidth) {
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();//计算padding
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight();
result += padding;
if (mode == MeasureSpec.AT_MOST) {
if (isWidth) {
result = Math.max(result, size);
} else {
result = Math.min(result, size);
}
}
}
return result;
}
}


上面的注释写的很清楚了, 效果如下:



最后我把源码的 下载地址 附上
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android