自定义属性
在 /res/values/中创建自定义的resources型资源文件attr.xml。其中自定义的属性将关联到自定义类中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="UTF-8"?> <resources> <!-- 在自定义类中使用 --> <!-- 自定义属性集合 name=自定义名称 --> <declare-styleable name="udfstyle"> <!-- 圆环背景色。定义一个roundColor属性,值为16RGB颜色类型 --> <attr name="ringBackgroundColor" format="color" /> <!-- 前景色 --> <attr name="ringForegroundColor" format="color" /> <!-- 圆环宽。尺寸类型 --> <attr name="ringSize" format="dimension" /> <!-- 文字颜色 --> <attr name="textColor" format="color" /> <!-- 文字大小 --> <attr name="textSize" format="dimension" /> <!-- 最大值 --> <attr name="max" format="integer" /> </declare-styleable> </resources> |
自定义View类
本质是个View,重写其中的onDraw方法,按要求进行绘制。用到了系统传入的画布,和自定义的画笔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
package com.cuiweyou.udfprsbar; // 注意包路径 import *; /** * 自定义环形进度条 * @author cuiweiyou.com */ public class ProgressView extends View { /** 画笔 */ private Paint paint; /** 自定义控件的属性s */ private TypedArray attributes; /** 圆环最大值 */ private int max; /** 文字尺寸 */ private float textSize; /** 文字颜色 */ private int textColor; /** 圆环前景色-轨迹颜色 */ private int ringForegroundColor; /** 圆环背景色-轨道颜色 */ private int ringBackgroudnColor; /** 圆环轨迹宽度 */ private float ringSize; /** 圆环当前进度 */ private int progress; /** 圆心位置 */ private int center; /** 圆半径 */ private int radius; /** 最好是为在xml里定义的这些属性提供set、get方法 */ // 2参构造方法在xml里引用 public ProgressView(Context context, AttributeSet attrs) { super(context, attrs); paint = new Paint(); // 读取/res/values/attr.xml中的自定义配置 attributes = context.obtainStyledAttributes(attrs, R.styleable.udfstyle); // 读取每个自定义属性,(xml里配置的属性值,读不到时的默认值) ringBackgroudnColor = attributes.getColor(R.styleable.udfstyle_ringBackgroundColor, Color.RED); ringForegroundColor = attributes.getColor(R.styleable.udfstyle_ringForegroundColor, Color.GREEN); textColor = attributes.getColor(R.styleable.udfstyle_textColor, Color.BLACK); textSize = attributes.getDimension(R.styleable.udfstyle_textSize, 15); ringSize = attributes.getDimension(R.styleable.udfstyle_ringSize, 5); max = attributes.getInteger(R.styleable.udfstyle_max, 100); attributes.recycle(); } /** * 绘制控件 此方法持续调用 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); center = getWidth() / 2; // 此时可以获取控件的尺寸了 radius = (int) ((center - ringSize) / 2); //Log.e("ard", "控件中心:" + center + "px,半径:" + radius + "px"); cal(canvas); arc(canvas); txt(canvas); } /** * 绘制圆环轨道 */ private void cal(Canvas canvas) { paint.setStyle(Paint.Style.STROKE); // 设置空心 paint.setColor(ringBackgroudnColor); // 设置圆环轨道颜色 paint.setStrokeWidth(ringSize); // 设置圆环的宽度 paint.setAntiAlias(true); // 消除锯齿 // 画出圆形(圆心x、圆心y,半径,画笔),如果paint为空心模式,画出来的就是圆环;实心模式画出的是圆饼 // xml里配的宽高400dp canvas.drawCircle(center, center, radius, paint); } /** * 圆环的进度-轨迹 */ private void arc(Canvas canvas) { paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(ringSize); // 设置圆环的宽度 paint.setColor(ringForegroundColor); // 设置进度的颜色 // 定义一个矩形区域(左,上,右,下)。正好重合圆环所在的范围 RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); // 绘制圆弧(绘制范围,顺时针起始角度,结束角度,是否显示指针,画笔) canvas.drawArc(oval, 0, 360 * progress / max, false, paint); // 根据进度画圆弧 } /** * 画进度百分比 */ private void txt(Canvas canvas) { paint.setStrokeWidth(0); paint.setColor(textColor); paint.setTextSize(textSize); paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体 float percent = (float)progress / (float)max * 100; // 进度百分比 float textWidth = paint.measureText((int)percent + "%"); // 字体宽度 // 绘制文本(文本,绘制区域x起点,y起点,画笔) canvas.drawText((int)percent + "%", center - textWidth / 2, center + textSize / 2, paint); } /** * 获取进度.需要同步 * @return */ public int getProgress() { return progress; } /** * 设置进度 * @param progress */ public void setProgress(int progress) { if (progress < 0) { progress = 0; } if (progress > max) { progress = max; } this.progress = progress; // 刷新控件。刷一次即执行一次onDraw。postInvalidate()能在非UI线程刷新 postInvalidate(); } } |
在UI的布局中引用自定义进度条
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:cuiweiyou="http://schemas.android.com/apk/res/com.cuiweyou.udfprsbar" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- 上面的xmlns:cuiweiyou是自定义的约束,/res/后面即自定义View的包路径 --> <!-- 这些属性都是在attr.xml中声明了,自定义View中定义了的 --> <com.cuiweyou.udfprsbar.ProgressView android:id="@+id/udfprsbar" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="9" cuiweiyou:ringBackgroundColor="#ff9900" cuiweiyou:ringForegroundColor="#0099ff" cuiweiyou:ringSize="10dp" cuiweiyou:textColor="#000000" cuiweiyou:textSize="18sp"/> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="ddd" /> </LinearLayout> |
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public class MainActivity extends Activity { private int progress; private ProgressView mPrsBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPrsBar = (ProgressView) findViewById(R.id.udfprsbar); progress = 0; findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { if(progress <=100){ // 持续刷新,不停的onDraw while (progress <= 100) { mPrsBar.setProgress(progress += 5); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } else { while (progress >= 0) { mPrsBar.setProgress(progress -= 5); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); } }); } } |
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/1745.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设