自定义环形加载进度条和原生ProgressBar使用

1.自定义


/**
 * 旋转加载动画控件
 */
public class RotateLoadingView extends View {

    /**
     * 默认圆弧的宽度
     */
    private static final int DEFAULT_ARC_WIDTH = 6;
    /**
     * 默认旋转度数的速度
     */
    private static final int DEFAULT_SPEED_OF_DEGREE = 5;
    /**
     * 是否需要画图
     */
    private boolean mIsDraw;
    /**
     * 是否是自动模式,无需人工干预
     */
    private boolean mIsAutoMode = true;

    /**
     * 圆弧画笔
     */
    private Paint mArcPaint;
    /**
     * 圆弧画笔的粗细
     */
    private int mArcWidth;
    /**
     * 圆弧的颜色
     */
    private int mArcColor;

    /**
     * 背景圆弧颜色
     */
    private int mbgArcColor;

    private boolean mIsSingleArc;
    /**
     * 圆弧所在的椭圆对象
     */
    private RectF mLoadingRectF;
    /**
     * 上弧的度数
     */
    private int mTopDegree = 10;
    /**
     * 下弧的度数
     */
    private int mBottomDegree = 190;
    /**
     * 圆弧的角度
     */
    private float mArcDegree;
    /**
     * 圆弧的最大角度
     */
    private int mMaxArcDegree;
    /**
     * 上下弧度数的变化速度
     */
    private int mSpeedOfDegree;
    /**
     * 圆弧角度的变化速度
     */
    private float mSpeedOfArc;
    /**
     * 圆弧是否开始变大
     */
    private boolean mChangeBigger = true;

    /**
     * 图标
     */
    private Bitmap mIconBitmap;
    /**
     * 图标缩放比例
     */
    private float mIconScale;
    /**
     * 绘制图标的画笔
     */
    private Paint mIconPaint;
    /**
     * 背景画笔
     */
    private Paint mBackPaint;

    private int mWidth;
    private int mHeight;
    private float mStrokeWidth = 50;
    private float mRadius = 50;

    public RotateLoadingView(Context context) {
        super(context);
        initAttrs(context, null);
    }

    public RotateLoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
    }

    public RotateLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadingView);
        mArcColor = typedArray.getColor(R.styleable.LoadingView_lv_color, ThemeUtils.getMainThemeColor(context));
        mbgArcColor=typedArray.getColor(R.styleable.LoadingView_lv_bg_color, ThemeUtils.getMainThemeColor(context));
        mArcWidth = typedArray.getDimensionPixelSize(R.styleable.LoadingView_lv_width, DensityUtils.dp2px(getContext(), DEFAULT_ARC_WIDTH));
        mSpeedOfDegree = typedArray.getInt(R.styleable.LoadingView_lv_speed, DEFAULT_SPEED_OF_DEGREE);
        mSpeedOfArc = mSpeedOfDegree >> 2;
        mIsDraw = mIsAutoMode = typedArray.getBoolean(R.styleable.LoadingView_lv_auto, true);
        mIsSingleArc = typedArray.getBoolean(R.styleable.LoadingView_lv_arc_single, false);
        mMaxArcDegree = mIsSingleArc ? 280 : 160;
        boolean hasIcon = typedArray.getBoolean(R.styleable.LoadingView_lv_has_icon, true);
        if (hasIcon) {
            Drawable icon = ResUtils.getDrawableAttrRes(getContext(), typedArray, R.styleable.LoadingView_lv_icon);
            if (icon != null) {
                mIconBitmap = Utils.getBitmapFromDrawable(icon);
            } else {
                Drawable appIcon = Utils.getAppIcon(getContext());
                if (appIcon != null) {
                    mIconBitmap = Utils.getBitmapFromDrawable(appIcon);
                }
            }
            mIconScale = typedArray.getFloat(R.styleable.LoadingView_lv_icon_scale, 0.5F);
        }
        typedArray.recycle();

        initPaint();
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        mBackPaint = new Paint();
        mBackPaint.setColor(mbgArcColor);
        mBackPaint.setAntiAlias(true);
        mBackPaint.setStyle(Paint.Style.STROKE);
        mBackPaint.setStrokeWidth(mArcWidth);
        mBackPaint.setStrokeCap(Paint.Cap.ROUND);

        mArcPaint = new Paint();
        mArcPaint.setColor(mArcColor);
        mArcPaint.setAntiAlias(true);
        mArcPaint.setStyle(Paint.Style.STROKE);
        mArcPaint.setStrokeWidth(mArcWidth);
        mArcPaint.setStrokeCap(Paint.Cap.ROUND);

        mIconPaint = new Paint();
        mIconPaint.setColor(mArcColor);
        mIconPaint.setAntiAlias(true);
        mIconPaint.setStyle(Paint.Style.STROKE);
        mIconPaint.setStrokeCap(Paint.Cap.ROUND);
    }
    //重写测量大小的onMeasure方法和绘制View的核心方法onDraw()
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getRealSize(widthMeasureSpec);
        mHeight = getRealSize(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);

    }
    public int getRealSize(int measureSpec) {
        int result = 1;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) {
            //自己计算
            result = (int) (mRadius * 2 + mStrokeWidth);
        } else {
            result = size;
        }

        return result;
    }
    @Override
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
        super.onSizeChanged(width, height, oldWidth, oldHeight);
        mArcDegree = 10;
        mLoadingRectF = new RectF(mArcWidth, mArcWidth, width - mArcWidth, height - mArcWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!mIsDraw) {
            return;
        }
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mBackPaint);
        drawArc(canvas);

        changeArcDegree();

        invalidate();
    }

    /**
     * 画圆弧
     *
     * @param canvas
     */
    private void drawArc(Canvas canvas) {
        if (mIconBitmap != null) {
            canvas.drawBitmap(mIconBitmap, null, getIconBitmapRectF(mIconBitmap), mIconPaint);
        }

        drawTopArc(canvas);

        if (!mIsSingleArc) {
            drawBottomArc(canvas);
        }
    }

    /**
     * 画上弧
     *
     * @param canvas
     */
    private void drawTopArc(Canvas canvas) {
        canvas.drawArc(mLoadingRectF, mTopDegree, mArcDegree, false, mArcPaint);
        mTopDegree += mSpeedOfDegree;
        if (mTopDegree > 360) {
            mTopDegree = mTopDegree - 360;
        }
    }

    /**
     * 画下弧
     *
     * @param canvas
     */
    private void drawBottomArc(Canvas canvas) {
        canvas.drawArc(mLoadingRectF, mBottomDegree, mArcDegree, false, mArcPaint);
        mBottomDegree += mSpeedOfDegree;

        if (mBottomDegree > 360) {
            mBottomDegree = mBottomDegree - 360;
        }
    }

    /**
     * 改变圆弧的角度
     */
    private void changeArcDegree() {
        if (mChangeBigger) {
            if (mArcDegree < mMaxArcDegree) {
                mArcDegree += mSpeedOfArc;
            }
        } else {
            if (mArcDegree > mSpeedOfDegree) {
                mArcDegree -= 2 * mSpeedOfArc;
            }
        }
        if (mArcDegree >= mMaxArcDegree || mArcDegree <= mSpeedOfDegree) {
            mChangeBigger = !mChangeBigger;
        }
    }

    /**
     * 获取中心图标所在的区域
     *
     * @return
     */
    public RectF getIconBitmapRectF(Bitmap bitmap) {
        float width = bitmap.getWidth(), height = bitmap.getHeight();
        if (width >= height) {
            height = getWidth() / width * height;
            width = getWidth();
        } else {
            width = getHeight() / height * width;
            height = getHeight();
        }
        float left = (getWidth() - width * mIconScale) / 2;
        float top = (getHeight() - height * mIconScale) / 2;
        float right = getWidth() - left;
        float bottom = getHeight() - top;
        return new RectF(left, top, right, bottom);
    }

    /**
     * 设置loading的图标
     *
     * @param icon
     * @return
     */
    public RotateLoadingView setLoadingIcon(Drawable icon) {
        if (icon != null) {
            mIconBitmap = Utils.getBitmapFromDrawable(icon);
        }
        return this;
    }

    /**
     * 设置loading的图标
     *
     * @param iconBitmap
     * @return
     */
    public RotateLoadingView setLoadingIcon(Bitmap iconBitmap) {
        mIconBitmap = iconBitmap;
        return this;
    }

    public RotateLoadingView setLoadingColor(int color) {
        mArcColor = color;
        return this;
    }

    public int getLoadingColor() {
        return mArcColor;
    }

    /**
     * 开始旋转
     */
    public void start() {
        if (!mIsAutoMode) {
            mIsDraw = true;
            invalidate();
        }
    }

    /**
     * 停止旋转
     */
    public void stop() {
        if (!mIsAutoMode) {
            pause();
        }
    }

    /**
     * 暂停旋转并消失
     */
    private void pause() {
        mIsDraw = false;
        invalidate();
    }

    public boolean isStart() {
        return mIsDraw;
    }

    /**
     * 资源释放
     */
    public void recycle() {
        pause();

        if (mIconBitmap != null) {
            mIconBitmap.recycle();
            mIconBitmap = null;
        }
        mBackPaint=null;
        mArcPaint = null;
        mIconPaint = null;
        mLoadingRectF = null;
    }

}
public class Utils {
    /**
     * 将Drawable转化为Bitmap
     *
     * @param drawable Drawable
     * @return Bitmap
     */
    public static Bitmap getBitmapFromDrawable(Drawable drawable) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
                .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }
    /**
     * 获取应用的图标
     *
     * @param context
     * @return
     */
    public static Drawable getAppIcon(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo info = pm.getApplicationInfo(context.getPackageName(), 0);
            return info.loadIcon(pm);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}
   themeUtils.java
 /**
     * 获取主题色
     *
     * @param context 上下文
     * @return 主题色
     */
    @ColorInt
    public static int getMainThemeColor(Context context) {
        return resolveColor(context, R.attr.colorAccent, getColor(context, R.color.xui_config_color_main_theme));
    }
  @ColorInt
    public static int resolveColor(Context context, @AttrRes int attr) {
        return resolveColor(context, attr, 0);
    }

    @ColorInt
    public static int resolveColor(Context context, @AttrRes int attr, int fallback) {
        TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr});
        try {
            return a.getColor(0, fallback);
        } finally {
            a.recycle();
        }
    }

使用:

-        <RotateLoadingView
            android:id="@+id/loading"
            android:layout_width="26dp"
            android:layout_height="26dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:lv_arc_single="true"
            app:lv_speed="8"
            app:lv_width="2dp"
            app:lv_color="#FFFFFF"
            app:lv_bg_color="#33FFFFFF"
            app:lv_auto="true"
            app:lv_has_icon="false" />

attr.xml

 <!--LoadingView-->
    <declare-styleable name="LoadingView">
        <!--loading加载画笔的粗细-->
        <attr name="lv_width" format="dimension" />
        <!--loading加载画笔的颜色-->
        <attr name="lv_color" format="color" />
        <!--loading背景颜色-->
        <attr name="lv_bg_color" format="color" />
        <!--loading加载旋转的速度-->
        <attr name="lv_speed" format="integer" />
        <!--是否有loading中心的图标, 默认是true-->
        <attr name="lv_has_icon" format="boolean" />
        <!--loading中心的图标-->
        <attr name="lv_icon" format="reference" />
        <!--loading中心图标缩放的比例, 默认是0.5-->
        <attr name="lv_icon_scale" format="float" />
        <!--圆弧的角度-->
        <attr name="lv_arc_degree" format="integer" />
        <!--是否自动旋转,无需人工控制,默认是true-->
        <attr name="lv_auto" format="boolean" />
        <!--是否单弧旋转,默认false-->
        <attr name="lv_arc_single" format="boolean" />
    </declare-styleable>

2.ProgressBar

 <ProgressBar
            android:id="@+id/arc_loading"
            android:layout_width="26dp"
            android:layout_height="26dp"
            android:layout_marginLeft="15dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:indeterminateDrawable="@drawable/bar" />

1.bar.xml 自己填充颜色

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="10"
        android:useLevel="false">
        <gradient
            android:centerY="0.5"
            android:endColor="#FFFFFF" //结束的颜色
            android:startColor="#10FFFFFF" //开始的颜色
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</animated-rotate>

2、设置图片 

一 首相在drawable文件夹中建立如下旋转动画文件

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"    
    android:drawable="@drawable/loading1"    
    android:pivotX="50%"    
    android:pivotY="50%" />

其中loading1即为您想用的图片

二 在布局文件中设置progressbar

<ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         android:indeterminateDrawable="@drawable/progressbg"
         android:indeterminateOnly="true"
         android:indeterminateBehavior="repeat"
    
       />

参考:android画笔,Android自定义View系列之画笔(一)_Gaosaroma的博客-CSDN博客

           Android编程之ProgressBar圆形进度条颜色设置方法 / 张生荣

          XUI

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值