自定义MyView继承View ;
注意事项:
1:让MyView支持Warp_content
如果不在onMeasure()方法中对warp_content,也就是AT_MOST模式做处理,就相当于和使用match_parent效果一样,就不能达预期的效果。
解决方法是对在onMeasure()方法中做相应的处理,把需要设定的宽或者高,设置成匹配内容宽高的int值,当然也要考虑内边距padding。
思路如下:判断widthMeasureSpec和heightMeasureSpec是否为AT_MOST,也就是wrap_content,如果想让实际宽度为占满父控件,就把widthSpecSize当做参数,如果不想这样,想要自己定义宽度,就填入具体数值,也可以计算内容的宽度来作为参数。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if(widthSpecMode==MeasureSpec.AT_MOST&&heightMeasureSpec==MeasureSpec.AT_MOST){
setMeasuredDimension(200, 200);
}else if(widthSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(200, heightSpecSize);
}else if (heightSpecMode==MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, 200);
}
}
2:让MyView支持padding
这是因为直接继承了View的控件,如果不在draw方法中处理padding,那么padding属性是无法起作用的。另外,如果直接继承自ViewGroup的控件,需要在onMeasure()和onLayout()中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效。(padding是内边距,需要控件自己控制,而margin是外边距,由父控件影响)
3:尽量不要在View中使用Handler,因为View本身就提供了post系列的方法,完全可以替代Handler的作用。
4:View中如有线程或者动画,需要及时停止:
如果有线程或者动画需要停止时,那么onDetachedFromWindow是一个很好的时机。当包含此View的Activity退出或者当前View被remove时,View的onDetachedFromWindow方法会被调用,和此方法对应的是onAttachedToWindow方法会被调用。当View变得不可见时也需要停止线程和动画,如果不及时处理这种问题,有可能会造成内存泄漏。
5:注意特殊情况下的View滑动冲突
下面是一个画圆的例子:
getPaddingLeft();等等都是获取内边距的方法
getWidth();获取宽度的方法,注意这里是这个控件的宽度,并一定是园的宽度
canvas.drawCircle(cx, cy, radius, paint); 画圆的方法,第一个参数是距离左边的长度,第二个参数是距离顶部的宽度,
第三个参数是半径,第四个是画笔实例。
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setColor(Color.BLACK);
final int paddingLeft =getPaddingLeft();
final int paddingRight =getPaddingRight();
final int paddingTop =getPaddingTop();
final int paddingBottom =getPaddingBottom();
int width=getWidth()-paddingLeft-paddingRight;
int height=getHeight()-paddingTop-paddingBottom;
int radius=Math.min(width, height)/2;
canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2 , radius, paint);
}