转载请注明出处:http://blog.csdn.net/darling_R/article/details/54861805
本文出自:哎呀小嘿的博客
今天练习了一下自定义view,效果图如下:
那么就来先了解一下一些属性的类型,方便后面使用:string , integer , dimension , reference , color…
1. reference:参考某一资源ID。
2. color:颜色值。
3. boolean:布尔值。
4. dimension:尺寸值。
5. float:浮点值。
6. integer:整型值。
7. string:字符串。
8. fraction:百分数。
9. enum:枚举值。
10. flag:位或运算。
注意:
属性定义时可以指定多种类型值。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
(2)属性使用:
<ImageView
android:layout_width = "42dip"
android:layout_height = "42dip"
android:background = "@drawable/图片ID|#00FF00"/>
自定义view步骤可分为以下几步:
1。自定义属性
首先在res/value 文件夹下新建一个attrs.xml文件,在里面定义一些可以供用户自定义的一些属性。
例如,提取自定义控件的几个属性,分别为大圆的背景色,进度条颜色,进度条宽度,百分比字体大小,百分比字体颜色,圆的半径。
<declare-styleable name="CirclePercentView">
<attr name="circleBg" format="color" />
<attr name="progressColor" format="color" />
<attr name="progressWidth" format="dimension" />
<attr name="percentSize" format="dimension" />
<attr name="percentColor" format="color" />
<attr name="radius" format="dimension" />
</declare-styleable>
2。新建一个类MyTextView继承View,重写三个构造方法。
这里要注意一点,自动生成的构造方法,里面是 super(),要把前两个改成 this(context,null)和this(context,attrs,0);或者在每个构造方法里都初始化一下也行;
public CirclePercentView(Context context) {
this(context, null);
}
public CirclePercentView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CirclePercentView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
在第三个构造方法里面获取自定义的属性,在最后位置一定要记得调用 typedArray.recycle() 释放;
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CirclePercentView, defStyleAttr, 0);
mCirColor = ta.getColor(R.styleable.CirclePercentView_circleBg, 0xff3d3d3d);//默认黑灰色
mPerTextColor = ta.getColor(R.styleable.CirclePercentView_percentColor, 0xffff3030);
mPerTextSize = ta.getDimensionPixelSize(R.styleable.CirclePercentView_percentSize, DensityUtils.sp2px(context, 14));
mProWidth = ta.getDimensionPixelSize(R.styleable.CirclePercentView_progressWidth, DensityUtils.dp2px(context, 5));
mProColor = ta.getColor(R.styleable.CirclePercentView_progressColor, 0xfff0f0f0);
mRadius = ta.getDimensionPixelSize(R.styleable.CirclePercentView_radius, DensityUtils.dp2px(context, 100));
ta.recycle();
紧接着,初始化一些所需要的画笔,便于后面绘制使用:
mCirPaint = new Paint();
mCirPaint.setColor(mCirColor);
mPerPaint = new Paint();
mPerPaint.setColor(mPerTextColor);
mPerPaint.setTextSize(mPerTextSize);
mProPaint = new Paint();
mProPaint.setStyle(Paint.Style.STROKE);
mProPaint.setColor(mProColor);
mProPaint.setStrokeWidth(mProWidth);
mBounds = new Rect();
mRectF = new RectF();
3。这里就可以重写onMeasure了,计算自定义控件的宽高;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureDimension(widthMeasureSpec), measureDimension(heightMeasureSpec));
}
private int measureDimension(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {//指定宽高了
result = specSize;
} else {// 一般为WARP_CONTENT
result = 2 * mRadius;
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
准备工作做完了,就可以把控件内容画出来了
4,重写onDraw方法,
@Override
protected void onDraw(Canvas canvas) {
//画背景圆
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mCirPaint);
//画进度条
mRectF.set(getWidth() / 2 - mRadius + mProWidth / 2, getHeight() / 2 - mRadius + mProWidth / 2, getWidth() / 2 + mRadius - mProWidth / 2, getHeight() / 2 + mRadius - mProWidth / 2);
canvas.drawArc(mRectF, 270, 360 * mCurPercent / 100, false, mProPaint);
//画百分比文本
String text = mCurPercent + "%";
mPerPaint.getTextBounds(text, 0, text.length(), mBounds);
canvas.drawText(text, getWidth() / 2 - mBounds.width() / 2, getHeight() / 2 + mBounds.height() / 2, mPerPaint);
}
到这里,自定义的一个view就算完事了,下面就可以调用了;
在xml布局文件里这样引用:
<!-- 注意添加下面第二行,cust:是名字,可以随便叫-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cust="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.yh.customviewone.MainActivity">
<!--在这里引用attrs里面的属性名,设置属性值-->
<com.yh.customviewone.CirclePercentView
android:id="@+id/circleView"
android:layout_width="200dp"
android:layout_height="200dp"
cust:circleBg="#3d3d3d"
cust:percentColor="#ff0000"
cust:percentSize="50sp"
cust:progressColor="#0efefe"
cust:progressWidth="5dp"
cust:radius="100dp" />
</LinearLayout>
ps:
<resources>
<attr name="titleText" format="string" />
<attr name="titleTextColor" format="color" />
<attr name="titleTextSize" format="dimension" />
<declare-styleable name="CustomTitleView">
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources>
类似于生命全局变量一样,把共有的属性提取出来,在标签里引用就行,方便有多个自定义view时,重复多个属性,这样可以减少代码量
附上代码地址:https://github.com/XiaoHeia/CirclePercentView/tree/master