Android——自定义View loading效果

一些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;
    }
}

上面的注释写的很清楚了, 效果如下:
这里写图片描述

最后我把源码的 下载地址 附上

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值