Android仿Win8进度条

本文介绍了一个实现自定义动画效果的圆形进度条组件,通过调整帧率和参数,用户可以创建出不同速度和视觉效果的进度条动画。

原文:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=318786&extra=page%3D1&page=1

/**
 * 圆形进度条
 * @author planet
 *
 */
public class IndeterminateProgressBar  extends View{
        static final String TAG = "ProgressBar";
        /**
         * 帧率=1000/delayMillis
         * 帧率越快,旋转速度也就越快
         */
        private int delayMillis = 30;
        private Handler mHandler;
        private ArrayList<Entity> entities;
        private int width = 0;
//        private int height = 0;
        private int r = 15;
        private int shift = 20;
        private int radius = 3;
        private int color = Color.WHITE;
        private long time = 0;
        private boolean started = false;
 
        public IndeterminateProgressBar(Context context) {
                super(context);
                init(null);
        }
 
        public IndeterminateProgressBar(Context context, AttributeSet attrs) {
                super(context, attrs);
                init(attrs);
        }
        public IndeterminateProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                init(attrs);
        }
 
        @Override
        protected void onLayout(boolean changed, int left, int top, int right,
                        int bottom) {
                super.onLayout(changed, left, top, right, bottom);
                width = getLayoutParams().width;
//                height = getLayoutParams().height;
                if(width>0){
                        //根据view宽度定义小球的半径
                        if(width<50){
                                radius = 2;
                        }else if(width<80){
                                radius = 3;
                        }else{
                                radius = 4;
                        }
                        //radius = width<80?2:4;
                        r = width/2-radius*2;
                        if(r<=0) r = 15;
                        shift = width/2;
                }
        }
 
        private void init(AttributeSet attrs){
                //获取设置的background作为小球颜色,然后将view自身背景设置成透明色
                if(attrs != null){
                        String v = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "background");
                        if(v.startsWith("#")){
                                color = v!=null?Color.parseColor(v):color;
                        }else{
                                color = getResources().getColor(Integer.parseInt(v.replaceAll("@", "")));
                        }
                        setBackgroundResource(android.R.color.transparent);
                }
 
                mHandler = new Handler(new Handler.Callback() {
                        @Override
                        public boolean handleMessage(Message msg) {
                                for(Entity e : entities){
                                        e.update();
                                }
                                invalidate();
                                mHandler.sendEmptyMessageDelayed(0, delayMillis);
                                time += delayMillis;
                                return false;
                        }
                });
        }
         
        public void setColor(int color){
                this.color = color;
        }
        /**
         * 结束动画
         */
        public void stop(){
                mHandler.removeMessages(0);
                started = false;
                invalidate();
        }
         
        public boolean isStart(){
                return started;
        }
        /**
         * 重新开始动画
         */
        public void start(){
                if(started) return;
                started = true;
                time = 0;
                entities = new ArrayList<IndeterminateProgressBar.Entity>();
                float s = .25f;
                entities.add(new Entity(0, color, 0));
                entities.add(new Entity(1*s, color, delayMillis*4));
                entities.add(new Entity(2*s, color, delayMillis*8));
                entities.add(new Entity(3*s, color, delayMillis*12));
                entities.add(new Entity(4*s, color, delayMillis*16));
                mHandler.sendEmptyMessage(0);
        }
 
        @Override
        protected void onDraw(Canvas canvas) {
                for(Entity e : entities){
                        e.draw(canvas);
                }
                super.onDraw(canvas);
        }
 
        class Entity{
                private float x;
                private float y;
                private int color;
                private Paint paint;
                private double sp = 0;
                private long delay;
                //动画一共三个阶段0~2
                private int sec = 0;
                //每个阶段pec从0~1
                private float pec = 0;
                boolean visiable = true;
 
                public float getInterpolation(float input) {
                        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
                }
 
                public Entity(float sp, int color, int delay) {
                        paint = new Paint();
                        paint.setAntiAlias(true);
                        paint.setStyle(Paint.Style.FILL);
                        this.color = color;
                        this.sp = sp;
                        this.delay = delay;
                        paint.setColor(this.color);
                }
 
                public void update(){
                        if(time<delay) return;
                        visiable = true;
                        //pec这个变量是步进值,值越大,旋转速度也越快,可以跟delayMillis配合使用
                        pec+= 0.03;
                        if(pec>1){
                                pec = 0;
                                sec=++sec==3?0:sec;
                                delay = sec==0?time+delayMillis*22:time+delayMillis*3;
                                visiable = sec==0?false:true;
                        }
                        //sec=0从0.5pi开始,sec=1从1.5pi开始,sec=2从1pi开始
                        double θ = Math.PI*.5+(sec==0?0:sec*Math.PI/sec) - (sec==0?0:sp)
                                        //sec=0,sec=2移动1pi, sec=1移动2pi
                                        + (Math.PI*(sec==1?2:1)- (sec==0?sp:0) + (sec==2?sp:0))*getInterpolation(pec);
                        x = (float) (r/2*Math.cos(θ))+shift/2;
                        y = (float) (r/2*Math.sin(θ))+shift/2;
                }
 
                public void draw(Canvas canvas){
                        if(!visiable || x==0 || y==0) return;
                        canvas.save();
                        canvas.translate(x, y);
                        canvas.drawCircle(x, y, radius, paint);
                        canvas.restore();
                }
        }
 
        @Override
        protected void onAttachedToWindow() {
                super.onAttachedToWindow();
                if(getVisibility() == View.VISIBLE){
                        start();
                }
        }
 
        @Override
        protected void onDetachedFromWindow() {
                super.onDetachedFromWindow();
                stop();
        }
}


在数字化环境中,线上票务获取已成为参与各类活动的主要途径。随着公众对热门演出需求的增长,票源往往在开放销售后迅速告罄,导致普通消费者难以顺利购得所需票券。为应对这一挑战,部分技术开发者借助编程手段构建了自动化购票辅助程序,旨在提升用户成功获取门票的概率。本文将以一个针对特定票务平台设计的自动化工具为例,系统阐述其设计理念、技术组成及具体实施流程。 秀动网作为国内知名的演出及体育赛事票务销售平台,因活动热度较高,常出现访问拥堵、瞬时抢购压力大等现象,使得常规购票过程面临困难。因此,开发一款能够协助用户更有效完成票务申购的辅助工具具有实际意义。 该工具主要具备以下几项关键功能:持续监控目标平台的票务信息更新;在票务释放时自动执行选座、添加至购物车及提交订单等系列操作;集成一定的异常处理机制,以应对网络延迟或服务器响应异常等情况。 在技术实现层面,选用Python作为开发语言,主要基于其语法简洁、标准库与第三方资源丰富,适合快速构建功能原型。同时,Python在网络通信与浏览器自动化方面拥有如requests、selenium等成熟支持库,为程序实现网页交互与数据抓取提供了便利。 开发过程主要包括以下环节:首先解析目标网站的页面结构,明确可通过程序操控的网页元素路径;随后编写监控模块,实时检测新票务信息的上线并及时触发后续操作;接着模拟用户操作流程,包括自动填写个人信息、选择座位偏好、完成购物车添加等步骤,并通过行为模拟降低被平台反爬虫机制识别的可能;最终实现订单自动提交,并在成功购票后向用户发送通知。 此外,该工具提供了可配置的操作界面,允许用户根据个人需求设定抢票时间、目标活动类型及座位选择等参数,从而在提升使用体验的同时,减少对票务平台服务器资源的非必要占用。 需指出的是,尽管此类工具能提高购票效率,但其使用可能涉及违反平台服务协议或相关法规的风险。各票务销售方通常对自动化抢票行为设有明确约束,因此开发与使用者均应遵守相应规定,确保技术应用的合法性。 综上所述,该基于Python的票务辅助工具是针对特定场景设计的自动化解决方案,通过技术手段改善用户购票体验,但同时也强调必须在法律与平台规则框架内合理使用此类技术。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值