ProgressBar 源码

/**
* @FileName CircleProgressBar.java
* @Package com.read.view
* @Description TODO
* @Author Alpha
* @Date 2015-7-30 下午4:52:24
* @Version V1.0

*/
package com.read.view;
import com.read.cnblogs.R;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Cap;
import android.util.AttributeSet;
import android.util.Property;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

public class CircleProgressBar extends View {

     private static final Interpolator ANGLE_INTERPOLATOR = new LinearInterpolator();
        private static final Interpolator SWEEP_INTERPOLATOR = new AccelerateDecelerateInterpolator();
        private static final int ANGLE_ANIMATOR_DURATION = 2000;
        private static final int SWEEP_ANIMATOR_DURATION = 900;
        private static final int MIN_SWEEP_ANGLE = 30;
        private static final int DEFAULT_BORDER_WIDTH = 3;
        private final RectF fBounds = new RectF();

        private ObjectAnimator mObjectAnimatorSweep;
        private ObjectAnimator mObjectAnimatorAngle;
        private boolean mModeAppearing = true;
        private Paint mPaint;
        private float mCurrentGlobalAngleOffset;
        private float mCurrentGlobalAngle;
        private float mCurrentSweepAngle;
        private float mBorderWidth;
        private boolean mRunning;
        private int[] mColors;

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

        public CircleProgressBar(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }

        public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);

            float density = context.getResources().getDisplayMetrics().density;
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularProgress, defStyleAttr, 0);
            mBorderWidth = a.getDimension(R.styleable.CircularProgress_borderWidth,
                    DEFAULT_BORDER_WIDTH * density);
            a.recycle();
            mColors = new int[2];
            mColors[0] = context.getResources().getColor(R.color.pink);
            //mColors[1]=context.getResources().getColor(R.color.pink);

//            mCurrentColorIndex = 0;
//            mNextColorIndex = 1;

            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeCap(Cap.ROUND);
            mPaint.setStrokeWidth(mBorderWidth);
            mPaint.setColor(mColors[0]);

            setupAnimations();
        }

        private void start() {
            if (mRunning) {
                return;
            }
            mRunning = true;
            mObjectAnimatorAngle.start();
            mObjectAnimatorSweep.start();
            invalidate();
        }

        private void stop() {
            if (!mRunning) {
                return;
            }
            mRunning = false;
            mObjectAnimatorAngle.cancel();
            mObjectAnimatorSweep.cancel();
            invalidate();
        }

        @Override
        protected void onVisibilityChanged(View changedView, int visibility) {
            super.onVisibilityChanged(changedView, visibility);
            if (visibility == VISIBLE) {
                start();
            } else {
                stop();
            }
        }

        @Override
        protected void onAttachedToWindow() {
            start();
            super.onAttachedToWindow();
        }

        @Override
        protected void onDetachedFromWindow() {
            stop();
            super.onDetachedFromWindow();
        }
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            fBounds.left = mBorderWidth / 2f + .5f;
            fBounds.right = w - mBorderWidth / 2f - .5f;
            fBounds.top = mBorderWidth / 2f + .5f;
            fBounds.bottom = h - mBorderWidth / 2f - .5f;
        }

        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            float startAngle = mCurrentGlobalAngle - mCurrentGlobalAngleOffset;
            float sweepAngle = mCurrentSweepAngle;
            if (mModeAppearing) {
                mPaint.setColor(mColors[0]);
                sweepAngle += MIN_SWEEP_ANGLE;
            } else {
                startAngle = startAngle + sweepAngle;
                sweepAngle = 360 - sweepAngle - MIN_SWEEP_ANGLE;
            }
            canvas.drawArc(fBounds, startAngle, sweepAngle, false, mPaint);//画弧线
        }

//        private static int gradient(int color1, int color2, float p) {
//            int r1 = (color1 & 0xff0000) >> 16;
//            int g1 = (color1 & 0xff00) >> 8;
//            int b1 = color1 & 0xff;
//            int r2 = (color2 & 0xff0000) >> 16;
//            int g2 = (color2 & 0xff00) >> 8;
//            int b2 = color2 & 0xff;
//            int newr = (int) (r2 * p + r1 * (1 - p));
//            int newg = (int) (g2 * p + g1 * (1 - p));
//            int newb = (int) (b2 * p + b1 * (1 - p));
//            return Color.argb(200, newr, newg, newb);
//        }

        private void toggleAppearingMode() {
            mModeAppearing = !mModeAppearing;
            if (mModeAppearing) {
//                mCurrentColorIndex = ++mCurrentColorIndex % 4;
//                mNextColorIndex = ++mNextColorIndex % 4;
                mCurrentGlobalAngleOffset = (mCurrentGlobalAngleOffset + MIN_SWEEP_ANGLE * 2) % 360;
            }
        }
        // ////////////////////////////////////////////////////////////////////////////
        // ////////////// Animation

        private Property<CircleProgressBar, Float> mAngleProperty = new Property<CircleProgressBar, Float>(Float.class, "angle") {
            @Override
            public Float get(CircleProgressBar object) {
                return object.getCurrentGlobalAngle();
            }

            @Override
            public void set(CircleProgressBar object, Float value) {
                object.setCurrentGlobalAngle(value);
            }
        };

        private Property<CircleProgressBar, Float> mSweepProperty = new Property<CircleProgressBar, Float>(Float.class, "arc") {
            @Override
            public Float get(CircleProgressBar object) {
                return object.getCurrentSweepAngle();
            }

            @Override
            public void set(CircleProgressBar object, Float value) {
                object.setCurrentSweepAngle(value);
            }
        };

        private void setupAnimations() {
            mObjectAnimatorAngle = ObjectAnimator.ofFloat(this, mAngleProperty, 360f);
            mObjectAnimatorAngle.setInterpolator(ANGLE_INTERPOLATOR);
            mObjectAnimatorAngle.setDuration(ANGLE_ANIMATOR_DURATION);
            mObjectAnimatorAngle.setRepeatMode(ValueAnimator.RESTART);
            mObjectAnimatorAngle.setRepeatCount(ValueAnimator.INFINITE);

            mObjectAnimatorSweep = ObjectAnimator.ofFloat(this, mSweepProperty, 360f - MIN_SWEEP_ANGLE * 2);
            mObjectAnimatorSweep.setInterpolator(SWEEP_INTERPOLATOR);
            mObjectAnimatorSweep.setDuration(SWEEP_ANIMATOR_DURATION);
            mObjectAnimatorSweep.setRepeatMode(ValueAnimator.INFINITE);
            mObjectAnimatorSweep.setRepeatCount(ValueAnimator.INFINITE);
            mObjectAnimatorSweep.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {
                    toggleAppearingMode();
                }
            });

        }

        public void setCurrentGlobalAngle(float currentGlobalAngle) {
            mCurrentGlobalAngle = currentGlobalAngle;
            invalidate();
        }

        public float getCurrentGlobalAngle() {
            return mCurrentGlobalAngle;
        }

        public void setCurrentSweepAngle(float currentSweepAngle) {
            mCurrentSweepAngle = currentSweepAngle;
            invalidate();
        }

        public float getCurrentSweepAngle() {
            return mCurrentSweepAngle;
        }
}
时间: 2024-08-09 11:41:51

ProgressBar 源码的相关文章

Android网络:HTTP之利用HttpURLConnection访问网页、获取网络图片实例 (附源码)

http://blog.csdn.net/yanzi1225627/article/details/22222735 如前文所示的TCP局域网传送东西,除了对传输层的TCP/UDP支持良好外,Android对HTTP(超文本传输协议)也提供了很好的支持,这里包括两种接口: 1.标准Java接口(java.net) ----HttpURLConnection,可以实现简单的基于URL请求.响应功能: 2.Apache接口(org.appache.http)----HttpClient,使用起来更方

2016年最牛逼的分类Android项目源码免费一次性打包下载!

之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年开始不断整理源码区和其他网站上的安卓例子源码,目前总共有810套左右,根据实现的功能被我分成了100多个类,总共接近2.5G,还在不断更新.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是我一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不要一分钱!最看不起那些挂羊头卖狗的)你可以在本帖里面按Ctrl+F查找你需要的关键字,

非常出色的一款WinForm窗体重绘GUI类库源码

基本控件的演示 ScrollBar滚动条 各种圆形进度条 ProgressBar进度条 Mdi演示,仿谷歌浏览器 多种皮肤可供选择 一套专业级别的GUI控件,目前包含了窗体.进度条.滚动条以及MDI多窗口皮肤的实现,其他基本控件还没有,但是整个界面非常流畅. 源码内包含4个项目: HelloCsharp.WinFormUI,GUI核心实现类,封装了多种窗体控件的方法. HelloCsharp.ControlDemo,包含基本控件,进度条,滚动条以及TrackBar的调用demo. HelloCs

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签

android源码解析(十七)--&gt;Activity布局加载流程

好吧,终于要开始讲讲Activity的布局加载流程了,大家都知道在Android体系中Activity扮演了一个界面展示的角色,这也是它与android中另外一个很重要的组件Service最大的不同,但是这个展示的界面的功能是Activity直接控制的么?界面的布局文件是如何加载到内存并被Activity管理的?android中的View是一个怎样的概念?加载到内存中的布局文件是如何绘制出来的? 要想回答这些问题,我们就需要对android的界面加载与绘制流程有所了解,这里我们先来学习一下Act

转--2014年最新810多套android源码2.46GB免费一次性打包下载

转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源码,目前总共有810套左右,根据实现的功能被博主分成了100多个类,总共接近2.5G,还在不断更新.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是博主一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不

管窥Android中的滑动条SeekBar的父类AbsSeekBar的源码

Android中的控件中有一类是ProgressBar,其子类中有一个是AbsSeekBar.相信有不少童鞋对这个拖动条的父类比较感兴趣吧!尤其是看到网易云音乐的进度条上面是可以处理播放与暂停事件,是不是很羡慕的哈~  俺在这里告诉大家,不用羡慕,看了我下面的代码分析,你也是可以做出那样的效果的哦.Let's go. 下面先给大家列表一下AbsSeekBar的成员变量有哪些. //当前的矩形 private final Rect mTempRect = new Rect(); //可以拖动的滑块

C#源码大汇总

C#高仿QQ2013可在广域网部署聊天系统GG叽叽 动态显示硬盘分区容量饼图 自定义ProgressBar控件高仿Win8进度条 多皮肤精美在线QQ悬浮客服插件 jQuery仿天猫首页多格焦点图片轮播 jQuery时间轴特效 自动完成菜单.代码提示.输入纠错控件 仿Google浏览器进度条 仿苹果Safari浏览器选项卡自定义TabControl控件 蜂窝大战游戏 C#开源内容管理系统DTcms v3.0正式版源码 ScreenToGif录制屏幕到gif动画 CSS3仿Google Play的垂

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr