在Android中控件一般分为两类View或者ViewGroup.
View的绘制过程大致有3步。
- 设置属性
- 测量
- 绘制
1.设置属性
在value下新建一个 attrs.xml 文件,用于设置文字的颜色,大小,内容。
<resources>
<declare-styleable name="MyView">
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
<attr name="textTitle" format="string" />
</declare-styleable>
</resources>
在布局中可以这样设置
<cn.jiangzehui.www.textview.MyView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="5dp"
zdy:textColor="#00ff00"
zdy:textSize="20dp"
zdy:textTitle="北京" />
设置的属性可以在构造方法中获取相应的值
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArrayarray=context.getTheme().obtainStyledAttributes(attrs,R.styleable.MyView,defStyleAttr, 0);
color = array.getColor(R.styleable.MyView_textColor, Color.BLACK);//获取颜色
size = array.getDimensionPixelSize(R.styleable.MyView_textSize,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));//获取文本大小
title = array.getString(R.styleable.MyView_textTitle);//获取内容
array.recycle();
paint = new Paint();
paint.setTextSize(size);
paint.setAntiAlias(true);
rect = new Rect();
paint.getTextBounds(title, 0, title.length(), rect);
}
2.测量
View 提供了MeasureSpec类用于测量View的宽高。
测量分为3种方法。
- EXACTLY : 一般是设定了指定的大小或者match_parent.
- AT_MOST : 当View的大小设定为wrap_content时,我们需要给View设定一个最大值,默认是屏幕的宽高。
- UNSPECIFIED: 表示View的宽高可以无限大,几乎不会用到。
测量我们需要重写OnMeasure()方法。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//如果是WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法
setMeasuredDimension(measure_wh(widthMeasureSpec,0),measure_wh(heightMeasureSpec,1));
}
/**
* 测量宽度
* @param measureSpec
* @return
*/
private int measure_wh(int measureSpec,int type) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
if(type==0){
result = getPaddingLeft()+rect.width()+getPaddingRight();
}else{
result = getPaddingTop()+rect.width()+getPaddingBottom();
}
}
if(type==0){
viewWidth=result;
}else{
viewHeight=result;
}
return result;
}
3.绘制
重写OnDraw()方法
/**
* 绘制
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.YELLOW);
canvas.drawCircle(viewWidth/2,viewHeight/2,viewWidth/2,paint);
paint.setColor(color);
canvas.drawText(title, viewWidth/2 - rect.width()/2, viewHeight/2+rect.height()/2, paint);
}
这里我们画了一个居中显示的圆和文本,下面来看一下效果图
看着效果感觉是没什么毛病,但当我们把字体放大一点后,发现文字并没有居中。
把字体设置的越大 越明显
具体原因参考
http://blog.youkuaiyun.com/carrey1989/article/details/10399727
按照他的博客进行处理,解决了我的问题O(∩_∩)O
最后看一下效果图