感觉自己很low,android学了这么久,只会写写布局,写写点击事件,用点三方框架,这些东西会一点android都可以做?为什么自己写android到现在还是这么low,突然想到要提升自己的逼格,想到自定义控件是一个好东西,哈哈,接下来是我学习的一些随笔。
1.自定义控件的要求:
1.应当遵守Android标准的规范(命名,事件处理等)
2.在xml布局中可配置空间的属性(自定义属性)
3.对交互应当有合适的反馈,(点击,长按等)
4.具有兼容性,android版本很多,应该具有广泛的适用性。
2.自定义控件的学习步骤:
1.View的工作原理
2.编写View类
3.为View类增加属性
4.绘制屏幕
5.响应用户消息
6.自定义回调函数
3.自定义控件的两种方式:
1.继承ViewGroup:如:framelayout、Linearlayout、RelativeLayout等
2.继承View:如:View、Textview、imageview、button等
4.自定义控件的基本绘制原理;
View的绘制基本上由measure()、layout()、draw()这个三个函数完成的
1.第一步 测量 —— measure; 此步骤是计算视图的大小,View measure过程相关方法主要有三个:
public final void measure(int widthMeasureSpec,int heightMeasureSpec)
protected final void setMeasureDimension(int measuredWidth,int measureHeight)
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec)
measure调用onMeasure,onMeasure测量宽度、高度,然后调用setMeasureDimension保存测量结果,measure,setMeasureDimension是final类型,View的子类不需要重写,只在子类中重写onMeasure方法。
关于 MeasureSpec:
1.UPSPECIFIED:父容器对子容器没有任何限制,子容器想要多大就多大。
2.EXACTlY:父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大空间
3.AT_MOST:子容器可以是声明大小内的任意大小
2.第二步 布局 —— layout;此步骤用于设置试图在屏幕中显示的位置,View layout过程相关方法主要是三个:
public void layout(int l,int t,int r,int b)
protected boolean setFram(int left,int top,int right,int bottom)
protected void onLayout(boolean changed,int left,int top,int right,int bottom)
layout通过调用setFrame(left,top,right,bottom) , l,t,r,b即子试图在父试图中的具体位置,onLayout一般只会在自定义的ViewGroup中才会使用。
3.第三步 绘制 —— draw,此步骤用于利用前两步得到的参数,将试图显示在屏幕上,到这里也就完成了整个试图绘制工作。
public void draw(Canvas canvas)
protected void onDraw(Canvas canvas)
通过调用draw函数进行视图绘制,在View类中onDraw函数是空函数,最终的绘制需求需要在自定义的onDraw函数中进行实现,比如imageView完成图片的绘制,如果自定义ViewGroup这个函数则不需要重载。
在绘制的时候通常我们都会用到画笔,自定义控件一般都会开启抗锯齿功能,使画出来的图形更加美观mPaint = new Paint(); mPaint.setAntiAlias(true); //开启抗锯齿 mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//填充和描边
canvas.drawArc()的用法
/** * oval :指定圆弧的外轮廓矩形区域。 startAngle: 圆弧起始角度,单位为度。 sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。 useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。关键是这个变量,下面将会详细介绍。 paint: 绘制圆弧的画板属性,如颜色,是否填充等。 */ canvas.drawArc(oval,270,120,false,mPaint);
具体说一下画笔的作用,因为在自定义控件,界面都需要paint来画出来,主要说下paint的style
mArcPaint.setStyle(Paint.Style.STROKE);//设置画圆弧的画笔的属性为描边(空心),个人喜欢叫它描边,叫空心有点会引起歧义,只画圆弧的范围
正常使用画笔,为了图像质量比较好都会设置为 mPaint.setAntiAlias(true); //开启抗锯齿 mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//填充和描边
mPaint.setStrokeWidth(10); //如果是划线的情况下,此方法可以增加画笔的粗细。
这里需要提一点 onMeasure() 和onLayout()方法会执行好几遍, onMeasure会执行三次,onLayout()会执行两次
如果在这两个方法中获取宽高不是很好,会重复, 所以获取宽高最好是在onSizeChanged()方法,此方法执行,activity肯定测量好了内部每一个布局的大小。所以在onSizeChanged中获取控件的宽、高,肯定不会有任何问题。