【Android 应用开发】 自定义 圆形进度条 组件

代码下载 : 

-- CSDN 下载地址 : http://download.csdn.net/detail/han1202012/8069497 ;

-- GitHub 地址 : https://github.com/han1202012/CircleProcess.git ;

-- 工程示例 : 

 

一. 相关知识点解析

 

 

1. 自定义 View 组件构造方法

 

构造方法 : 自定义的 View 组件, 一般需要实现 三个构造方法, 分别有 一个, 两个, 三个参数;

-- 一个参数 : public CircleProcess(Context context);

-- 两个参数 : public CircleProcess(Context context, AttributeSet attrs);

-- 三个参数 : public CircleProcess(Context context, AttributeSet attrs, int defStyle);

 

构造方法注意点 : 

-- 调用上级方法 : 每个构造方法中必须调用 super() 方法, 方法中的参数与该构造方法参数一样;

-- 常用构造方法 : 一般在2参数构造方法中实现逻辑;

 

构造方法示例 : 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 画笔 */  
  2. private Paint mPaint;  
  3. /** 上下文对象 */  
  4. private Context mContext;  
  5. /** 进度条的值 */  
  6. private int mProcessValue;  
  7.   
  8. public CircleProcess(Context context, AttributeSet attrs) {  
  9.     super(context, attrs);  
  10.     // 初始化成员变量 Context  
  11.     mContext = context;  
  12.     // 创建画笔, 并设置画笔属性  
  13.     mPaint = new Paint();  
  14.     // 消除绘制时产生的锯齿  
  15.     mPaint.setAntiAlias(true);  
  16.     // 绘制空心圆形需要设置该样式  
  17.     mPaint.setStyle(Style.STROKE);  
  18. }  
  19.   
  20. /** 
  21.  * 自定义布局实现的 只有 Context 参数的构造方法 
  22.  * @param context 
  23.  */  
  24. public CircleProcess(Context context) {  
  25.     super(context);  
  26. }  
  27.   
  28. /** 
  29.  * 自定义布局实现的 三个参数的构造方法 
  30.  * @param context 
  31.  * @param attrs 
  32.  * @param defStyle 
  33.  */  
  34. public CircleProcess(Context context, AttributeSet attrs, int defStyle) {  
  35.     super(context, attrs, defStyle);  
  36. }  


 

2. dip 和 px 单位转换

 

 

(1) dip 转 px

 

公式 : 

-- 基本公式 : px / dip = dpi / 160;

-- 计算公式 : px = dpi / 160 * dip;

 

一些概念解析 : 

-- dpi 概念 : dpi (dot per inch), 每英寸像素数 归一化的值 120 160 240 320 480;

-- 区分 dpi 和 density : dpi 是归一化的值, density 是实际的值, 可能不是整数;

 

代码示例 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 将手机的 设备独立像素 转为 像素值 
  3.  *  
  4.  *      公式 : px / dip = dpi / 160 
  5.  *             px = dip * dpi / 160; 
  6.  * @param context 
  7.  *              上下文对象 
  8.  * @param dpValue 
  9.  *              设备独立像素值 
  10.  * @return 
  11.  *              转化后的 像素值 
  12.  */  
  13. public static int dip2px(Context context, float dpValue) {  
  14.     final float scale = context.getResources().getDisplayMetrics().density;  
  15.     return (int) (dpValue * scale + 0.5f);  
  16. }  


 

(2) px 转 dip

 

公式 : 

-- 基本公式 : px / dip = dpi / 160;

-- 计算公式 : dip = 160 / dpi * px;

 

代码 : 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 将手机的 像素值 转为 设备独立像素 
  3.  *      公式 : px/dip = dpi/160 
  4.  *             dip = px * 160 / dpi 
  5.  *             dpi (dot per inch) : 每英寸像素数 归一化的值 120 160 240 320 480; 
  6.  *             density : 每英寸的像素数, 精准的像素数, 可以用来计算准确的值 
  7.  *             从 DisplayMetics 中获取的 
  8.  * @param context 
  9.  *              上下文对象 
  10.  * @param pxValue 
  11.  *              像素值 
  12.  * @return 
  13.  *              转化后的 设备独立像素值 
  14.  */  
  15. public static int px2dip(Context context, float pxValue) {  
  16.     final float scale = context.getResources().getDisplayMetrics().density;  
  17.     return (int) (pxValue / scale + 0.5f);  
  18. }  


 

 

3. 关于 组件 宽 和 高 计算

 

 

(1) MesureSpec 简介

 

MeasureSpec 组成 : 每个 MeasureSpec 都代表一个 int 类型数值, 共 32 位, 前两位是模式位, 后 30 位 是数值位;

-- 模式 : int 类型的前 2 位, 共有三种模式, 通过 MeasureSpec.getMode(int) 方法获取, 下面会详细介绍模式;

-- 大小 : int 类型的后 30 位, 通过 MeasureSpec.getSize(int) 方法获取大小;

 

MeasureSpec 模式简介 : 注意下面的数字是二进制的

-- 00 : MeasureSpec.UNSPECIFIED, 未指定模式;
-- 01 : MeasureSpec.EXACTLY, 精准模式;
-- 11 : MeasureSpec.AT_MOST, 最大模式;

 

MeasureSpec 常用方法介绍 : 

-- MeasureSpec.getMode(int) : 获取模式;
-- MeasureSpec.getSize(int) : 获取大小;
-- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec;
-- MeasureSpec.toString(int) : 模式 + 大小 字符串;

 

 

(2) 通过 MeasureSpec 计算组件大小

 

计算方法 : 

-- 精准模式 : 该模式下 长度的大小 就是 从 MeasureSpec 中获取的 size 大小;

-- 最大模式 : 获取 默认大小 和 size 中的较小的那个;

-- 未定义模式 : 默认大小;

 

通用计算方法代码 : 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 获取组件宽度 
  3.  *  
  4.  * MeasureSpec : 该 int 类型有 32 位, 前两位是状态位, 后面 30 位是大小值; 
  5.  *      常用方法 :  
  6.  *      -- MeasureSpec.getMode(int) : 获取模式 
  7.  *      -- MeasureSpec.getSize(int) : 获取大小 
  8.  *      -- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec; 
  9.  *      -- MeasureSpec.toString(int) : 模式 + 大小 字符串 
  10.  *       
  11.  *      模式介绍 : 注意下面的数字是二进制的 
  12.  *      -- 00 : MeasureSpec.UNSPECIFIED, 未指定模式; 
  13.  *      -- 01 : MeasureSpec.EXACTLY, 精准模式; 
  14.  *      -- 11 : MeasureSpec.AT_MOST, 最大模式; 
  15.  *       
  16.  *      注意 : 这个 MeasureSpec 模式是在 onMeasure 方法中自动生成的, 一般不用去创建这个对象 
  17.  *       
  18.  * @param widthMeasureSpec 
  19.  *              MeasureSpec 数值 
  20.  * @return 
  21.  *              组件的宽度 
  22.  */  
  23. private int measure(int measureSpec) {  
  24.     //返回的结果, 即组件宽度  
  25.     int result = 0;  
  26.     //获取组件的宽度模式  
  27.     int mode = MeasureSpec.getMode(measureSpec);  
  28.     //获取组件的宽度大小 单位px  
  29.     int size = MeasureSpec.getSize(measureSpec);  
  30.       
  31.     if(mode == MeasureSpec.EXACTLY){//精准模式  
  32.         result = size;  
  33.     }else{//未定义模式 或者 最大模式  
  34.         //注意 200 是默认大小, 在 warp_content 时使用这个值, 如果组件中定义了大小, 就不使用该值  
  35.         result = dip2px(mContext, 200);  
  36.         if(mode == MeasureSpec.AT_MOST){//最大模式  
  37.             //最大模式下获取一个稍小的值  
  38.             result = Math.min(result, size);  
  39.         }  
  40.     }  
  41.       
  42.     return result;  
  43. }  


 

(3) 设置 组件大小方法

 

setMeasuredDimension() 方法 : 该方法决定 View 组件的大小;

-- 使用场所 : 在 onMeasure() 方法中调用该方法, 就设置了组件的宽 和 高, 然后在其它位置调用 getWidth() 和 getHeight() 方法时, 获取的就是 该方法设置的值;

-- 代码示例 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  3.     super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  4.     /* 
  5.      * setMeasuredDimension 方法 : 该方法决定当前的 View 的大小 
  6.      * 根据 View 在布局中的显示, 动态获取 View 的宽高 
  7.      *  
  8.      * 当布局组件 warp_content 时 :  
  9.      * 从 MeasureSpec 获取的宽度 : 492 高度 836 ,  
  10.      * 默认 宽高 都是 120dip转化完毕后 180px  
  11.      *  
  12.      * 当将布局组件 的宽高设置为 240 dp :  
  13.      * 宽度 和 高度 MeasureSpec 获取的都是 360, 此时 MeasureSpec 属于精准模式 
  14.      *  
  15.      */  
  16.     setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));  
  17. }  


 

4. 图形绘制

 

(1) 设置画笔

 

画笔相关方法 : 

-- 消除锯齿 : setAntiAlias(boolean);

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. // 消除绘制时产生的锯齿  
  2. mPaint.setAntiAlias(true);  

 

-- 绘制空心圆设置的样式 : setStyle(Style.STROKE);

 

[plain] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. // 绘制空心圆形需要设置该样式  
  2. mPaint.setStyle(Style.STROKE);  

 

-- 绘制实心图形文字需要设置的样式 : mPaint.setStrokeWidth(0);

-- 设置画笔颜色 : setColor(Color.BLUE);

-- 设置文字大小 : setTextSize(float);

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //设置数字的大小, 注意要根据 内圆半径设置  
  2. mPaint.setTextSize(innerRadius / 2);  


 

(2) 绘制图形

 

绘制圆 : canvas.drawCircle(float cx, float cy, float radius, Paint paint);

-- cx 参数 : 圆心的 x 轴距离;

-- cy 参数 : 圆心的 y 轴距离;

-- radius 参数 : 半径;

-- paint : 画笔;

 

绘制圆弧 : 

-- 创建圆弧 : RectF rectf = new RectF(left, top, right, bottom);

-- 绘制 : canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);

-- 示例 : 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //创建圆弧对象  
  2. RectF rectf = new RectF(left, top, right, bottom);  
  3. //绘制圆弧 参数介绍 : 圆弧, 开始度数, 累加度数, 是否闭合圆弧, 画笔  
  4. canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);  

绘制文字 : canvas.drawText(str, textX, textY, mPaint);

 

 

 

二. 代码示例

 

1. 自定义 View 代码

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package cn.org.octopus.circle;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.graphics.Paint.Style;  
  8. import android.graphics.Rect;  
  9. import android.graphics.RectF;  
  10. import android.graphics.Typeface;  
  11. import android.util.AttributeSet;  
  12. import android.widget.ImageView;  
  13.   
  14. public class CircleProcess extends ImageView {  
  15.   
  16.     /** 画笔 */  
  17.     private Paint mPaint;  
  18.     /** 上下文对象 */  
  19.     private Context mContext;  
  20.     /** 进度条的值 */  
  21.     private int mProcessValue;  
  22.       
  23.     public CircleProcess(Context context, AttributeSet attrs) {  
  24.         super(context, attrs);  
  25.         // 初始化成员变量 Context  
  26.         mContext = context;  
  27.         // 创建画笔, 并设置画笔属性  
  28.         mPaint = new Paint();  
  29.         // 消除绘制时产生的锯齿  
  30.         mPaint.setAntiAlias(true);  
  31.         // 绘制空心圆形需要设置该样式  
  32.         mPaint.setStyle(Style.STROKE);  
  33.     }  
  34.       
  35.     /** 
  36.      * 自定义布局实现的 只有 Context 参数的构造方法 
  37.      * @param context 
  38.      */  
  39.     public CircleProcess(Context context) {  
  40.         super(context);  
  41.     }  
  42.       
  43.     /** 
  44.      * 自定义布局实现的 三个参数的构造方法 
  45.      * @param context 
  46.      * @param attrs 
  47.      * @param defStyle 
  48.      */  
  49.     public CircleProcess(Context context, AttributeSet attrs, int defStyle) {  
  50.         super(context, attrs, defStyle);  
  51.     }  
  52.       
  53.     @Override  
  54.     protected void onDraw(Canvas canvas) {  
  55.         super.onDraw(canvas);  
  56.           
  57.         //获取圆心的 x 轴位置  
  58.         int center = getWidth() / 2;  
  59.         /* 
  60.          * 中间位置 x 减去左侧位置 的绝对值就是圆半径,  
  61.          * 注意 : 由于 padding 属性存在, |left - right| 可能与 width 不同 
  62.          */  
  63.         int outerRadius = Math.abs(getLeft() - center);  
  64.         //计算内圆半径大小, 内圆半径 是 外圆半径的一般  
  65.         int innerRadius = outerRadius / 2;  
  66.           
  67.         //设置画笔颜色  
  68.         mPaint.setColor(Color.BLUE);  
  69.         //设置画笔宽度  
  70.         mPaint.setStrokeWidth(2);  
  71.         //绘制内圆方法 前两个参数是 x, y 轴坐标, 第三个是内圆半径, 第四个参数是 画笔  
  72.         canvas.drawCircle(center, center, innerRadius, mPaint);  
  73.           
  74.         /* 
  75.          * 绘制进度条的圆弧 
  76.          *  
  77.          * 绘制图形需要 left top right bottom 坐标, 下面需要计算这个坐标 
  78.          */  
  79.           
  80.         //计算圆弧宽度  
  81.         int width = outerRadius - innerRadius;  
  82.         //将圆弧的宽度设置给 画笔  
  83.         mPaint.setStrokeWidth(width);  
  84.         /* 
  85.          * 计算画布绘制圆弧填入的 top left bottom right 值,  
  86.          * 这里注意给的值要在圆弧的一半位置, 绘制的时候参数是从中间开始绘制 
  87.          */  
  88.         int top = center - (innerRadius + width/2);  
  89.         int left = top;  
  90.         int bottom = center + (innerRadius + width/2);  
  91.         int right = bottom;  
  92.           
  93.         //创建圆弧对象  
  94.         RectF rectf = new RectF(left, top, right, bottom);  
  95.         //绘制圆弧 参数介绍 : 圆弧, 开始度数, 累加度数, 是否闭合圆弧, 画笔  
  96.         canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);  
  97.           
  98.         //绘制外圆  
  99.         mPaint.setStrokeWidth(2);  
  100.         canvas.drawCircle(center, center, innerRadius + width, mPaint);  
  101.           
  102.         /* 
  103.          * 在内部正中央绘制一个数字 
  104.          */  
  105.         //生成百分比数字  
  106.         String str = (int)(mProcessValue * 1.0 / 360 * 100) + "%";   
  107.         /* 
  108.          * 测量这个数字的宽 和 高 
  109.          */  
  110.         //创建数字的边界对象  
  111.         Rect textRect = new Rect();  
  112.         //设置数字的大小, 注意要根据 内圆半径设置  
  113.         mPaint.setTextSize(innerRadius / 2);  
  114.         mPaint.setStrokeWidth(0);  
  115.         //获取数字边界  
  116.         mPaint.getTextBounds(str, 0, str.length(), textRect);  
  117.         int textWidth = textRect.width();  
  118.         int textHeight = textRect.height();  
  119.           
  120.         //根据数字大小获取绘制位置, 以便数字能够在正中央绘制出来  
  121.         int textX = center - textWidth / 2;  
  122.         int textY = center + textHeight / 2;  
  123.           
  124.         //正式开始绘制数字  
  125.         canvas.drawText(str, textX, textY, mPaint);  
  126.     }  
  127.   
  128.       
  129.     @Override  
  130.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  131.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  132.         /* 
  133.          * setMeasuredDimension 方法 : 该方法决定当前的 View 的大小 
  134.          * 根据 View 在布局中的显示, 动态获取 View 的宽高 
  135.          *  
  136.          * 当布局组件 warp_content 时 :  
  137.          * 从 MeasureSpec 获取的宽度 : 492 高度 836 ,  
  138.          * 默认 宽高 都是 120dip转化完毕后 180px  
  139.          *  
  140.          * 当将布局组件 的宽高设置为 240 dp :  
  141.          * 宽度 和 高度 MeasureSpec 获取的都是 360, 此时 MeasureSpec 属于精准模式 
  142.          *  
  143.          */  
  144.         setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));  
  145.     }  
  146.       
  147.     /** 
  148.      * 获取组件宽度 
  149.      *  
  150.      * MeasureSpec : 该 int 类型有 32 位, 前两位是状态位, 后面 30 位是大小值; 
  151.      *      常用方法 :  
  152.      *      -- MeasureSpec.getMode(int) : 获取模式 
  153.      *      -- MeasureSpec.getSize(int) : 获取大小 
  154.      *      -- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec; 
  155.      *      -- MeasureSpec.toString(int) : 模式 + 大小 字符串 
  156.      *       
  157.      *      模式介绍 : 注意下面的数字是二进制的 
  158.      *      -- 00 : MeasureSpec.UNSPECIFIED, 未指定模式; 
  159.      *      -- 01 : MeasureSpec.EXACTLY, 精准模式; 
  160.      *      -- 11 : MeasureSpec.AT_MOST, 最大模式; 
  161.      *       
  162.      *      注意 : 这个 MeasureSpec 模式是在 onMeasure 方法中自动生成的, 一般不用去创建这个对象 
  163.      *       
  164.      * @param widthMeasureSpec 
  165.      *              MeasureSpec 数值 
  166.      * @return 
  167.      *              组件的宽度 
  168.      */  
  169.     private int measure(int measureSpec) {  
  170.         //返回的结果, 即组件宽度  
  171.         int result = 0;  
  172.         //获取组件的宽度模式  
  173.         int mode = MeasureSpec.getMode(measureSpec);  
  174.         //获取组件的宽度大小 单位px  
  175.         int size = MeasureSpec.getSize(measureSpec);  
  176.           
  177.         if(mode == MeasureSpec.EXACTLY){//精准模式  
  178.             result = size;  
  179.         }else{//未定义模式 或者 最大模式  
  180.             //注意 200 是默认大小, 在 warp_content 时使用这个值, 如果组件中定义了大小, 就不使用该值  
  181.             result = dip2px(mContext, 200);  
  182.             if(mode == MeasureSpec.AT_MOST){//最大模式  
  183.                 //最大模式下获取一个稍小的值  
  184.                 result = Math.min(result, size);  
  185.             }  
  186.         }  
  187.           
  188.         return result;  
  189.     }  
  190.       
  191.       
  192.     /** 
  193.      * 将手机的 设备独立像素 转为 像素值 
  194.      *  
  195.      *      公式 : px / dip = dpi / 160 
  196.      *             px = dip * dpi / 160; 
  197.      * @param context 
  198.      *              上下文对象 
  199.      * @param dpValue 
  200.      *              设备独立像素值 
  201.      * @return 
  202.      *              转化后的 像素值 
  203.      */  
  204.     public static int dip2px(Context context, float dpValue) {  
  205.         final float scale = context.getResources().getDisplayMetrics().density;  
  206.         return (int) (dpValue * scale + 0.5f);  
  207.     }  
  208.   
  209.     /** 
  210.      * 将手机的 像素值 转为 设备独立像素 
  211.      *      公式 : px/dip = dpi/160 
  212.      *             dip = px * 160 / dpi 
  213.      *             dpi (dot per inch) : 每英寸像素数 归一化的值 120 160 240 320 480; 
  214.      *             density : 每英寸的像素数, 精准的像素数, 可以用来计算准确的值 
  215.      *             从 DisplayMetics 中获取的 
  216.      * @param context 
  217.      *              上下文对象 
  218.      * @param pxValue 
  219.      *              像素值 
  220.      * @return 
  221.      *              转化后的 设备独立像素值 
  222.      */  
  223.     public static int px2dip(Context context, float pxValue) {  
  224.         final float scale = context.getResources().getDisplayMetrics().density;  
  225.         return (int) (pxValue / scale + 0.5f);  
  226.     }  
  227.   
  228.     /** 
  229.      * 获取当前进度值 
  230.      * @return 
  231.      *              返回当前进度值 
  232.      */  
  233.     public int getmProcessValue() {  
  234.         return mProcessValue;  
  235.     }  
  236.   
  237.     /** 
  238.      * 为该组件设置进度值 
  239.      * @param mProcessValue 
  240.      *              设置的进度值参数 
  241.      */  
  242.     public void setmProcessValue(int mProcessValue) {  
  243.         this.mProcessValue = mProcessValue;  
  244.     }  
  245.       
  246. }  


 

2. Activity 代码

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package cn.org.octopus.circle;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.ActionBar;  
  5. import android.app.Fragment;  
  6. import android.os.AsyncTask;  
  7. import android.os.Bundle;  
  8. import android.view.LayoutInflater;  
  9. import android.view.Menu;  
  10. import android.view.MenuItem;  
  11. import android.view.View;  
  12. import android.view.ViewGroup;  
  13. import android.os.Build;  
  14.   
  15. public class MainActivity extends Activity {  
  16.   
  17.     private static CircleProcess circle_process;  
  18.       
  19.     @Override  
  20.     protected void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.activity_main);  
  23.   
  24.         //加载 Fragment  
  25.         if (savedInstanceState == null) {  
  26.             getFragmentManager().beginTransaction()  
  27.                     .add(R.id.container, new PlaceholderFragment())  
  28.                     .commit();  
  29.         }  
  30.           
  31.         new CircleProcessAnimation().execute();  
  32.     }  
  33.   
  34.     /** 
  35.      * 设置 异步任务, 在这个任务中 设置 圆形进度条的进度值 
  36.      * @author octopus  
  37.      * 
  38.      */  
  39.     class CircleProcessAnimation extends AsyncTask<Void, Integer, Void>{  
  40.   
  41.         @Override  
  42.         protected Void doInBackground(Void... arg0) {  
  43.             for(int i = 1; i <= 360; i ++){  
  44.                 try {  
  45.                     //激活圆形进度条显示方法  
  46.                     publishProgress(i);  
  47.                     //每隔 50 毫秒更新一次数据  
  48.                     Thread.sleep(50);  
  49.                 } catch (InterruptedException e) {  
  50.                     e.printStackTrace();  
  51.                 }  
  52.             }  
  53.             return null;  
  54.         }  
  55.           
  56.         @Override  
  57.         protected void onProgressUpdate(Integer... values) {  
  58.             super.onProgressUpdate(values);  
  59.               
  60.             //为圆形进度条组件设置进度值  
  61.             circle_process.setmProcessValue(values[0]);  
  62.             //刷新圆形进度条显示  
  63.             circle_process.invalidate();  
  64.         }  
  65.           
  66.     }  
  67.       
  68.     /** 
  69.      * 界面显示的 Fragment  
  70.      * @author octopus 
  71.      */  
  72.     public static class PlaceholderFragment extends Fragment {  
  73.   
  74.         public PlaceholderFragment() {  
  75.         }  
  76.   
  77.         @Override  
  78.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  79.                 Bundle savedInstanceState) {  
  80.             View rootView = inflater.inflate(R.layout.fragment_main, container, false);  
  81.             circle_process = (CircleProcess) rootView.findViewById(R.id.circle_process);  
  82.             return rootView;  
  83.         }  
  84.     }  
  85.       
  86.       
  87.   
  88.     @Override  
  89.     public boolean onCreateOptionsMenu(Menu menu) {  
  90.         getMenuInflater().inflate(R.menu.main, menu);  
  91.         return true;  
  92.     }  
  93.   
  94.     @Override  
  95.     public boolean onOptionsItemSelected(MenuItem item) {  
  96.         int id = item.getItemId();  
  97.         if (id == R.id.action_settings) {  
  98.             return true;  
  99.         }  
  100.         return super.onOptionsItemSelected(item);  
  101.     }  
  102. }  


 

3. 布局文件代码 

 

 

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context="cn.org.octopus.circle.MainActivity$PlaceholderFragment"  
  10.     android:gravity="center">  
  11.   
  12.     <cn.org.octopus.circle.CircleProcess   
  13.         android:id="@+id/circle_process"  
  14.         android:layout_width="300dip"  
  15.         android:layout_height="300dip"/>  
  16.   
  17. </RelativeLayout>  


 

 

 

代码下载 : 

-- CSDN 下载地址 : http://download.csdn.net/detail/han1202012/8069497 ;

-- GitHub 地址 : https://github.com/han1202012/CircleProcess.git ;

-- 工程示例 : 


 

 

 
2
posted @ 2017-04-21 13:42  天涯海角路  阅读(164)  评论(0)    收藏  举报