IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Android的下拉刷新带进度条效果

    cuiran发表于 2015-01-16 22:33:12
    love 0

    首先看一下运行效果图,程序的下拉刷新参考了视频,在视频页面也提供了源码下载,

    http://www.imooc.com/learn/135


    本篇主要说在此基础上增加了进度条的快速旋转和递增递减处理,在文章最后也会给出源码,这里主要描述一下所用的一个类

    RoundProgressBar

    package com.cayden.listview;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.view.View;
    
    
    /**
     * 带进度的进度条,线程安全的View,可直接在线程中更新进度
     * @author cuiran
     *
     */
    public class RoundProgressBar extends View {
    	/**
    	 * 画笔对象的引用
    	 */
    	private Paint paint;
    	
    	/**
    	 * 圆环的颜色
    	 */
    	private int roundColor;
    	
    	/**
    	 * 圆环进度的颜色
    	 */
    	private int roundProgressColor;
    	
    	/**
    	 * 中间进度百分比的字符串的颜色
    	 */
    	private int textColor;
    	
    	/**
    	 * 中间进度百分比的字符串的字体
    	 */
    	private float textSize;
    	
    	/**
    	 * 圆环的宽度
    	 */
    	private float roundWidth;
    	
    	/**
    	 * 最大进度
    	 */
    	private int max;
    	
    	/**
    	 * 当前进度
    	 */
    	private int progress;
    	/**
    	 * 是否显示中间的进度
    	 */
    	private boolean textIsDisplayable;
    	
    	/**
    	 * 进度的风格,实心或者空心
    	 */
    	private int style;
    	
    	public static final int STROKE = 0;
    	public static final int FILL = 1;
    	/**是否循环**/
    	public  boolean isSpinning = false;
    	
    	public RoundProgressBar(Context context) {
    		this(context, null);
    	}
    
    	public RoundProgressBar(Context context, AttributeSet attrs) {
    		this(context, attrs, 0);
    	}
    	
    	public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    		
    		paint = new Paint();
    
    		TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
    				R.styleable.RoundProgressBar);
    		
    		//获取自定义属性和默认值
    		roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
    		roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
    		textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
    		textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
    		roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);
    		max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 360);
    		textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
    		style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
    		
    		mTypedArray.recycle();//必须Recycle
    	}
    	
    
    	@Override
    	protected void onDraw(Canvas canvas) {
    		super.onDraw(canvas);
    		
    		/**
    		 * 画最外层的大圆环
    		 */
    		int centre = getWidth()/2; //获取圆心的x坐标
    		int radius = (int) (centre - roundWidth/2); //圆环的半径
    		paint.setColor(roundColor); //设置圆环的颜色
    		paint.setStyle(Paint.Style.STROKE); //设置空心
    		paint.setStrokeWidth(roundWidth); //设置圆环的宽度
    		paint.setAntiAlias(true);  //消除锯齿 
    		canvas.drawCircle(centre, centre, radius, paint); //画出圆环
    		
    		/**
    		 * 画进度百分比 现已去掉改成画图片
    		 */
    //		paint.setStrokeWidth(0); 
    //		paint.setColor(textColor);
    //		paint.setTextSize(textSize);
    //		paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
    //		int percent = (int)(((float)progress / (float)max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
    //		float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
    //		
    //		if(textIsDisplayable && percent != 0 && style == STROKE){
    //			canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint); //画出进度百分比
    //		}
    
    			if(isSpinning){
    				/**
    				 * 画图片
    				 */
    				Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading02);
    				int width=bitmap.getWidth();
    				int height=bitmap.getHeight();
    				canvas.drawBitmap(bitmap, centre-width/2, centre-height/2 , paint);
    				
    				bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading06);
    				width=bitmap.getWidth();
    				height=bitmap.getHeight();
    				canvas.drawBitmap(bitmap, centre-width/2, centre-height/2 , paint);
    				/**
    				 * 画圆弧 ,画圆环的进度
    				 */
    				//设置进度是实心还是空心
    				paint.setStrokeWidth(roundWidth); //设置圆环的宽度
    				paint.setColor(roundProgressColor);  //设置进度的颜色
    				RectF oval = new RectF(centre - radius, centre - radius, centre
    						+ radius, centre + radius);  //用于定义的圆弧的形状和大小的界限
    				paint.setStyle(Paint.Style.STROKE);
    				canvas.drawArc(oval, progress-90, 320 , false, paint);  //根据进度画圆弧
    			}else{
    				/**
    				 * 画图片
    				 */
    				Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading02);
    				int width=bitmap.getWidth();
    				int height=bitmap.getHeight();
    				canvas.drawBitmap(bitmap, centre-width/2, centre-height/2 , paint);
    				 bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading05);
    				 width=bitmap.getWidth();
    				 height=bitmap.getHeight();
    				 canvas.drawBitmap(bitmap, centre-width/2, centre-height/2 , paint);
    				/**
    				 * 画圆弧 ,画圆环的进度
    				 */
    				//设置进度是实心还是空心
    				paint.setStrokeWidth(roundWidth); //设置圆环的宽度
    				paint.setColor(roundProgressColor);  //设置进度的颜色
    				RectF oval = new RectF(centre - radius, centre - radius, centre
    						+ radius, centre + radius);  //用于定义的圆弧的形状和大小的界限
    				paint.setStyle(Paint.Style.STROKE);
    				canvas.drawArc(oval, -90, progress , false, paint);  //根据进度画圆弧
    			}
    				
    			
    	
    		
    	}
    	
    	
    	public synchronized int getMax() {
    		return max;
    	}
    
    	/**
    	 * 设置进度的最大值
    	 * @param max
    	 */
    	public synchronized void setMax(int max) {
    		if(max < 0){
    			throw new IllegalArgumentException("max not less than 0");
    		}
    		this.max = max;
    	}
    
    	/**
    	 * 获取进度.需要同步
    	 * @return
    	 */
    	public synchronized int getProgress() {
    		return progress;
    	}
    	  /**
         * Reset the count (in increment mode)
         */
        public void resetCount() {
            progress = 0;
            invalidate();
        }
        /**
         * Turn off spin mode
         */
        public void stopSpinning() {
            isSpinning = false;
            progress = 0;
            spinHandler.removeMessages(0);
        }
        /**
         * Puts the view on spin mode
         */
        public void spin() {
            isSpinning = true;
            spinHandler.sendEmptyMessage(0);
        }
        /**
         * Increment the progress by 1 (of 360)
         */
        public void incrementProgress() {
            isSpinning = false;
            if (progress > 360)
                progress = 0;
            spinHandler.sendEmptyMessage(0);
        }
    	 private Handler spinHandler = new Handler() {
    	        /**
    	         * This is the code that will increment the progress variable
    	         * and so spin the wheel
    	         */
    	        @Override
    	        public void handleMessage(Message msg) {
    	        		invalidate();
    	        		if(isSpinning){
    	        			  progress += 10;
    	  	                if (progress > 360) {
    	  	                    progress = 0;
    	  	                }
    	  	                spinHandler.sendEmptyMessageDelayed(0, 0);
    	        		}
    	            //super.handleMessage(msg);
    	        }
    	    };
    	/**
    	 * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
    	 * 刷新界面调用postInvalidate()能在非UI线程刷新
    	 * @param progress
    	 */
    	public synchronized void setProgress(int progress) {
    		if(progress < 0){
    			throw new IllegalArgumentException("progress not less than 0");
    		}
    		if(progress > max){
    			progress = max;
    		}
    		if(progress <= max){
    			this.progress = progress;
    			postInvalidate();
    		}
    		
    	}
    	
    	
    	public int getCricleColor() {
    		return roundColor;
    	}
    
    	public void setCricleColor(int cricleColor) {
    		this.roundColor = cricleColor;
    	}
    
    	public int getCricleProgressColor() {
    		return roundProgressColor;
    	}
    
    	public void setCricleProgressColor(int cricleProgressColor) {
    		this.roundProgressColor = cricleProgressColor;
    	}
    
    	public int getTextColor() {
    		return textColor;
    	}
    
    	public void setTextColor(int textColor) {
    		this.textColor = textColor;
    	}
    
    	public float getTextSize() {
    		return textSize;
    	}
    
    	public void setTextSize(float textSize) {
    		this.textSize = textSize;
    	}
    
    	public float getRoundWidth() {
    		return roundWidth;
    	}
    
    	public void setRoundWidth(float roundWidth) {
    		this.roundWidth = roundWidth;
    	}
    
    
    
    }
    

    类中的主要绘图部分在

    canvas.drawArc(oval, progress-90, 320 , false, paint); //根据进度画圆弧

    canvas.drawArc(oval, -90, progress , false, paint); //根据进度画圆弧

    可以看一下canvas.drawArc方法

    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

    • oval :指定圆弧的外轮廓矩形区域。
    • startAngle: 圆弧起始角度,单位为度。
    • sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。
    • useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。
    • paint: 绘制圆弧的画板属性,如颜色,是否填充等
    可以参考以下对此介绍的网站

    http://blog.sina.com.cn/s/blog_783ede0301012im3.html



    最后给出项目的源码:

    https://github.com/cayden/ListViewDemo




沪ICP备19023445号-2号
友情链接