首页 > 移动平台 > 详细

Android多种样式的进度条

时间:2016-04-29 17:19:33      阅读:249      评论:0      收藏:0      [点我收藏+]


---- The mark of the immature man is that he wants to die nobly for a causer while the mark of the mature man is that he wants to live humbly for one 



1. 水平向右的进度条

技术分享



1-1 定义显示进度指示的图形 

drawable目录下progress_v_01.xml

关于shape使用详情可 查阅 点击打开链接

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!--默认图形大小-->
    <size
        android:width="500dp"
        android:height="50dp" />
    <!--填充颜色 -->
    <solid android:color="#6633CC" />
    <!--边框角度?-->
    <corners android:radius="20dp" />
</shape>

效果图 1-1-1

技术分享


1-2. 在drawable目录下新建一个clip标签的文件 
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/progress_v_01"
    android:gravity="left">

</clip>

clipOrientation设置方向为水平方向

gravity设置过程中对齐方式为左

drawable 中引用要显示设置的图形 


1-3.在页面布局文件中使用 

在src属性下引入我们1-2中创建的clip标签的文件 

<ImageView
        android:layout_margin="10dp"
        android:background="#e6e6e6"

        android:id="@+id/iv_image_clip_left"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"     
        android:src="@drawable/clip_left_01"/>
   


1.4 在java代码中动态设置进度 


 private ImageView mClipLeftImageView;
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mClipLeftImageView = (ImageView) findViewById(R.id.iv_image_clip_left);
        mClipLeftImageView.setImageLevel(10000);

        handler.postDelayed(runnable,2000);
    }
    private int mUnmber = 0;
    private Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            if (mUnmber<=10000){
                mClipLeftImageView.getDrawable().setLevel(mUnmber);
                handler.postDelayed(runnable,20);
                mUnmber+=100;
            }
        }
    };


2. 水平向左的进度条

技术分享


2-1 定义显示进度的图片,这里使用的是1-1中定义的图形 

2-2 创建clip标签文件 

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/progress_v_01"
    android:gravity="right"
    >
</clip>

clipOrientation设置方向为水平方向

gravity设置过程中对齐方式为右(从而达到进度从右向左的实现效果)

drawable 中引用要显示设置的图形 

2-3 在布局文件中的使用 同1-3;

2-4  java代码中的设置同 1-4;



3.水平向左向右的进度条

技术分享


3-1 定义显示进度的图片,这里使用的是1-1中定义的图形 

3-2 创建clip标签文件 

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/progress_v_01"
    android:gravity="center_horizontal"
    >
</clip>

clipOrientation设置方向为水平方向

gravity设置过程中对齐方式 为垂直中心对齐(从而达到进度从中间向两边扩展的实现效果)

drawable 中引用要显示设置的图形 


3-3 在布局文件中的使用 同 1-3;

3-4 在java代码中的设置同 1-4;





4.水平向右的圆形进度条

技术分享


4-1 定义使用到的显示进度的图形 drawbale目录下progress_oval_01.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <!--设置黑夜显示大小-->
    <size
        android:width="100dp"
        android:height="100dp" />
    <!--设置图形颜色-->
    <gradient
        android:centerColor="#CC9933"
        android:centerX="0.5"
        android:centerY="0.5"
        android:endColor="#33FF33"
        android:gradientRadius="45"
        android:startColor="#FFFF33"
        android:type="radial" />
    <!--设置图形边框-->
    <stroke
        android:width="2dp"
        android:color="#0000CC" />
    
</shape>


4-2 创建使用到的clip文件 

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/progress_oval_01"
    android:gravity="left"
    >

</clip>

clipOrientation设置方向为水平方向

gravity设置过程中对齐方式 为左边对齐(从而达到进度从左边向右的扩展的实现效果)

drawable 中引用要显示设置的图形 


3-3 在布局文件中的使用 同 1-3;

3-4 在java代码中的设置同 1-4;




5. 中心向外扩展的圆形进度条

技术分享

5-1 创建显示进度的图形 这里引用的是4-1中创建的图形

5-2 创建对应显示的clip标签文件 

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal|vertical"
    android:drawable="@drawable/progress_oval_01"
    android:gravity="center"
    >

</clip>


clipOrientation设置方向为水平方向

gravity设置过程中对齐方式 为中心对齐(从而达到进度从中间向两边的扩展的实现效果)

drawable 中引用要显示设置的图形 


5-3 在布局文件中的使用 同 1-3;

创建ImageView标签,在src属性下进行引用

5-4 在java代码中的设置同 1-4;



6.垂直向上的直线进度条

技术分享

6-1 创建显示进度的图形 

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <size android:width="5dp"
        android:height="100dp"/>

    <gradient
        android:angle="45"
        android:startColor="#FF9900"
        android:centerColor="#FFFF00"
        android:endColor="#66FF00"
        />
    <corners android:radius="5dp"/>

</shape>


效果图: 6-1-1


技术分享

6-2 创建对应的clip标签文件 

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/progress_oval_01"
    android:gravity="bottom"
    >

</clip>

clipOrientation设置方向为竖直方向

gravity设置过程中对齐方式 底部(从而达到进度从底部向上增加的实现效果)

如果设置为top,那么进度将成为从上到下 

drawable 中引用要显示设置的图形 

6-3 在布局文件中的使用 同 1-3;

创建ImageView标签,在src属性下进行引用

6-4 在java代码中的设置同 1-4;






7.垂直向上的圆形进度条

技术分享



8 Clip方式实现综述  

ClipDrawable代表从其它位图上截取一个“图片片段”。在XML文件中使用<clip.../>元素定义ClipDrawable对象,
可指定如下三个属性:

android:drawable:指定截取的源Drawable对象,也可以指定drawable类的子标签

android:clipOrientation:指定截取的方向,可设置为 horizontal  vertical 

android:gravity:指定截取时的对齐方式,可设置为top bottom right center_vertical fill_vertical center_horizontal center  fill  clip_vertaical  start end 等等


使用ClipDrawable对象时可以调用setLevel(int level)方法来设置截取的区域大小,当level为0时,截取的图片片段为空;当level为10000时,截取整张图片。


可以使用ClipDrawable的这种性质控制截取图片的区域大小,让程序不断调用setLevel方法并改变level的值,达到让图片慢慢展开的效果



9 通过自定义View的方式来实现进度条 -水平进度条


效果图 8-1 

技术分享

看这样的进度条确实有点风骚,不过效果还行

9-1 定义一个类,继承ProgressBar

public class HorizontalProgressBarWithNumber extends ProgressBar {


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

    public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs,
                                           int defStyle) {
        super(context, attrs, defStyle);

        
    }

    @Over

官方推荐的使用方式为

public class HorizontalProgressBarWithNumber extends ProgressBar {


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

    public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs,
                                           int defStyle) {
        super(context, attrs, defStyle);

        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
    }

    @Over

也就是说g..官方推荐的使用两个构造参数去调用三个构造参数的写法,我个人不建议这样写,两个构造去调用三个构造的方法,那么有时我们在构造中进行初时化操作的时候只需要在三个构造参数的方法进行一次初始化操作就好,但是当我们开发的应用遇到低版本的手机时,会遇到崩溃的问题(无法加载初始化xml布局文件),因为三个构造的方法是在高版本中才有的,所以我这里将初始化的操作全部封装到另一个方法中去,分别在两个构造中和三个构造方法中调用。

9-2 复写父控件的onDraw方法,来进行重新绘制 

 @Override
    protected synchronized void onDraw(Canvas canvas) {

        canvas.save();
        /**
         * 定义画笔的初始位置
         */
        canvas.translate(getPaddingLeft(), getHeight() / 2);

        /**
         * 计算加载进度的比例
         */
        float radio = getProgress() * 1.0f / getMax();
        /**
         * 计算已加载的进度
         */
        float progressPosX = (int) (mRealWidth * radio);
        /**
         * 定义进度上显示的文字信息
         */
        String text = getProgress() + "%";


        /**
         * 获取绘制文字的宽与高
         */
        float textWidth = mPaint.measureText(text);
        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;

        /**
         * 判断绘制
         */
        if (progressPosX + textWidth > mRealWidth) {
            progressPosX = mRealWidth - textWidth;
        }


        /**
         * 绘制已加载的进度
         */

        mPaint.setColor(mBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight);
        canvas.drawLine(0, 0, progressPosX, 0, mPaint);


        /**
         * 绘制加载显示的文字
         */
        mPaint.setColor(mTextColor);
        canvas.drawText(text, progressPosX, -textHeight, mPaint);


        /**
         * 绘制未加载的进度
         */
        float start = progressPosX + textWidth;
        mPaint.setColor(mUnBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight);
        canvas.drawLine(start, 0, mRealWidth, 0, mPaint);


        canvas.restore();

    }

这里进行绘制的过程是 先绘制已加载的进度,然后再绘制显示进度的文字,最后再绘制滑加载的进度,

9-3 设置并初始化相关的变量

其中使用到一些变量,比如绘制文字的颜色,绘制进度的颜色,高度等等。

这里使用的方法是在成员变量中进行了设置默认的值

    /**
     * 定义一个画笔
     */
    protected Paint mPaint = new Paint();
    /**
     * 设置默认的显示进度文字的颜色
     */
    protected int mTextColor = 0xff253688;
    /**
     * 设置显示默认的显示进度的文字的大小
     */
    protected int mTextSize = sp2px(10);

    /**
     * 设置默认的绘制进度条的高度
     */
    protected int mProgressBarHeight = dp2px(10);

    /**
     * 设置默认的绘制进度条颜色
     */
    protected int mBarColor = 0xffffcc00;
    /**
     * 未加载进度条的颜色
     */
    protected int mUnBarColor = 0xffe6e6e6;

    /**
     * 绘制进度条的实际宽度
     */
    protected int mRealWidth;

第一个变量是我们绘制过程中使用到的画笔,我们这里在类加载的时候进行了初时化操作,同时也给这个画笔设置一些对应的属性值


    
    
    private  void  initFunction(){
        
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);


    }
    


我们这里设置的是显示文字的大小与颜色(如果用到测量的话,在测量的时候可能会用到要测量绘制文字的大小,而我们这里是通过画笔的属性进行测量的)


变量mRealWidth是我们实际中需要绘制的进度条的实际宽度,可以在onMeaure方法中进行初始化(请查看下面的代码块)

也可以在方法中进行初始化

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        
        mRealWidth = w-getPaddingLeft()-getPaddingRight();
        
    }


其他的相应变量就是一些颜色与大小 ,其中有一个个将dp值转为px值的方法和sp转为px的方法(这是一些工具类) 

    /**
     * dp 2 px
     *
     * @param dpVal
     */
    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }

    /**
     * sp 2 px
     *
     * @param spVal
     * @return
     */
    protected int sp2px(int spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, getResources().getDisplayMetrics());

    }
走到这里,我们的自定义进度条就可以使用了

当然我们可以设置初始化这些变量的值

 /**
     * 设置已绘制的进度条的颜色
     *
     * @param mBarColor
     */
    public void setmBarColor(int mBarColor) {
        this.mBarColor = mBarColor;
    }

    /**
     * 设置过度条的高度
     *
     * @param mProgressBarHeight
     */
    public void setmProgressBarHeight(int mProgressBarHeight) {
        this.mProgressBarHeight = mProgressBarHeight;
    }

    /**
     * 设置指示进度条的显示文字的颜色
     *
     * @param mTextColor
     */
    public void setmTextColor(int mTextColor) {
        this.mTextColor = mTextColor;
    }

    /**
     * 设置指示进度条进度的显示文字的颜色
     *
     * @param mTextSize
     */
    public void setmTextSize(int mTextSize) {
        this.mTextSize = mTextSize;
    }

    /**
     * 设置未加载进度条处的进度颜色
     *
     * @param mUnBarColor
     */
    public void setmUnBarColor(int mUnBarColor) {
        this.mUnBarColor = mUnBarColor;
    }

9-4 自定义属性方式设置初始化变量值 


也可以通过自定义属性的方式来进行操作

values文件夹下attrs.xml文件中 

定义自定义属性 :绘制文本的颜色

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="HorizonProgressBarWidthNumber">
        <attr name="textProColor" format="color" />
    </declare-styleable>

</resources>


在构造方法中获取到自定义属性的值,并进行相应的赋值操作

    /**
     * 获取自定义属性操作
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void initFunction(Context context, AttributeSet attrs, int defStyle) {
        
        final TypedArray attributes = getContext().obtainStyledAttributes(
                attrs, R.styleable.HorizonProgressBarWidthNumber);

        mTextColor = attributes.getColor(R.styleable.HorizonProgressBarWidthNumber_textProColor, 0xff000000);
    }


9-5 onMeasure方法中的测量

在onMeasure方法进行一些测量

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec,
                                          int heightMeasureSpec) {


        /**
         * 1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
         * 2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
         * 3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)
         */

        /**
         * 三种测量模式
         * UNSPECIFIED:父布局没有给子布局任何限制,子布局可以任意大小。
         * EXACTLY:父布局决定子布局的确切大小。不论子布局多大,它都必须限制在这个界限里。
         * AT_MOST:子布局可以根据自己的大小选择任意大小。
         */

        /**
         * 获取测量宽度大小
         */
        int width = MeasureSpec.getSize(widthMeasureSpec);
        /**
         * 对高度进度测量
         */
        int height = 0;

        /**
         * 获取高度的测量模式
         */
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        /**
         * 获取测量高度的大小
         */
        int specSize = MeasureSpec.getSize(heightMeasureSpec);
        /**
         * 判断如果是非精准度的,那么就进行测量大小的重新设定
         */
        if (specMode == MeasureSpec.EXACTLY) {
            height = specSize;
        } else {
            /**
             * 获取显示加载进度的显示文本的宽度与高度
             */
            float textHeight = (mPaint.descent() - mPaint.ascent());
            /**
             * 计算测量的高度
             */
            height = (int) (getPaddingTop() + getPaddingBottom() + Math.max(
                    mProgressBarHeight, Math.abs(textHeight)));
            if (specMode == MeasureSpec.AT_MOST) {
                height = Math.min(height, specSize);
            }
        }
        /**
         * 设置测量
         */
        setMeasuredDimension(width, height);

        /**
         * 获取实际需要绘制进度条的宽度
         */
        mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
    }


9-6 风骚进度条设置使用

使用:

在xml中引入控件 

在java代码中

public class CustomProgressActivity extends Activity {

    private HorizontalProgressBarWithNumber mProgressBarView;
   

    private int mNumber = 0;
 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_progress);
        mProgressBarView = (HorizontalProgressBarWithNumber) findViewById(R.id.custom_progress_view);
        mProgressBarView.setMax(100);

       
        handler.sendEmptyMessage(1001);
       

    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            
            if (msg.what == 1001) {
                mProgressBarView.setmBarColor(randomColor());
                mProgressBarView.setProgress(mNumber);
                if (mNumber > 100) {
                    handler.removeMessages(1001);
                }
                if (mNumber < 100) {
                    handler.sendEmptyMessageDelayed(1001, 300);
                }
              
                mNumber++;

            }
           
        }
    };


    public  int randomColor(){
        Random random = new Random();
        //如果值太大,会偏白,太小则会偏黑,所以需要对颜色的值进行范围限定
        int red = random.nextInt(150)+50;//50-199
        int green = random.nextInt(150)+50;//50-199
        int blue = random.nextInt(150)+50;//50-199
        return Color.rgb(red, green, blue);//根据rgb混合生成一种新的颜色
    }


}

到这里就可以设置比较风骚的水平进度条了,我这里只是动态改变了绘制已加载进度条的颜色


10 通过自定义View的方式来实现进度条 -圆形进度条


效果图 10-1


     技术分享

        写作过程同 9 ,主要是在onDraw方法中进行的绘制

	@Override
	protected synchronized void onDraw(Canvas canvas)
	{


		/**
		 * 获取显示进度的文字指示
		 */
		String text = getProgress() + "%";
		/**
		 * 获取显示进度的文字的宽与高
		 */
		float textWidth = mPaint.measureText(text);
		float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;

		canvas.save();
		/**
		 * 将画布移动到中心
		 */
		canvas.translate(getPaddingLeft() + mProgressBarHeight / 2, getPaddingTop()
				+ mProgressBarHeight / 2);
		mPaint.setStyle(Style.STROKE);
		/**
		 * 绘制未加载的进度
		 */
		mPaint.setColor(mUnReachedBarColor);
		mPaint.setStrokeWidth(mProgressBarHeight);
		canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);

		/**
		 * 绘制已加载的圆环进度
		 */

		mPaint.setColor(mReachedBarColor);
		mPaint.setStrokeWidth(mProgressBarHeight);
		float sweepAngle = getProgress() * 1.0f / getMax() * 360;
		canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), 0,
				sweepAngle, false, mPaint);

		/**
		 * 绘制显示进行的颜色
		 */
		mPaint.setStyle(Style.FILL);
		canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight,
				mPaint);

		canvas.restore();

	}

相关的变量说明

	/**
	 * 定义设置进度圆的默认半径
	 */
	private int mRadius = dp2px(30);

	/**
	 * 圆环的默认宽度
	 */
	private  int mProgressBarHeight = dp2px(5);

	/**
	 * 声明初始化一个画笔
	 */
	private Paint mPaint = new Paint();
	/**
	 * 设置未加载进度的默认颜色
	 */
	private int mUnReachedBarColor = 0xffe6e6e6;

	/**
	 * 设置已加载进度的默认颜色
	 */
	private int mReachedBarColor = 0xff89cc99;


	/**
	 * 设置进度已加载进度条的颜色
	 * 这里只写了这个设置颜色
	 * 当然也可以写出代码动态设置改变 未加载进度条的颜色
	 * 还有显示文字的颜色 
	 * 还有进度条的宽度等等
	 * @param color
	 */
	public void setReachedBarColor(int color){
		this.mReachedBarColor = color;
	}
	

相关的构造方法以及构造方法中的初始化操作

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

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

	public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		mPaint.setStyle(Style.STROKE);
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setStrokeCap(Cap.ROUND);
	}


代码中的使用


public class MainActivity extends Activity {

    private  int number =0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final RoundProgressBar progress1 = (RoundProgressBar)findViewById(R.id.progress1);
        progress1.setMax(100);

        final RoundProgressBar progress2 = (RoundProgressBar)findViewById(R.id.progress2);
        progress2.setMax(100);

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                if (number>10){
                    progress2.setReachedBarColor(0xff00FF00);
                }else if (number>10){
                    progress2.setReachedBarColor(0xff00FF00);
                }else if (number>20){
                    progress2.setReachedBarColor(0xff228B22);
                }else if (number>30){
                    progress2.setReachedBarColor(0xff008000);
                }else if (number>40){
                    progress2.setReachedBarColor(0xff006400);
                }else if (number>50){
                    progress2.setReachedBarColor(0xff483D8B);
                }else if (number>60){
                    progress2.setReachedBarColor(0xff8A2BE2);
                }else if (number>70){
                    progress2.setReachedBarColor(0xff4B0082);
                }else if (number>90){
                    progress2.setReachedBarColor(0xff8B008B);
                }
                progress2.setProgress(number);
                progress1.setProgress(number);
                number+=1;
            }
        }, 0, 100);
    }
}


可以看到这里是随着进度不断的设置加载进度条的绘制颜色

关于计时器Timer与TimerTask使用 可以点击查看










Android多种样式的进度条

原文:http://blog.csdn.net/zl18603543572/article/details/51250216

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!