自定义view

  1.  
  2. 自定义view方法执行顺序
  3.  
  4. 03-18 11:32:30.198 14844-14844/? I/tag: ----  public CoustomView(Context context, AttributeSet attrs) ----  
  5. 03-18 11:32:30.198 14844-14844/? I/tag: ----  onFinishInflate() ----  
  6. 03-18 11:32:30.227 14844-14844/? I/tag: ----  onAttachedToWindow ----  
  7. 03-18 11:32:30.228 14844-14844/? I/tag: ----  onMeasure ----  
  8. 03-18 11:32:30.294 14844-14844/? I/tag: ----  onMeasure ----  
  9. 03-18 11:32:30.295 14844-14844/? I/tag: ----  onSizeChanged =  w = 1080  h = 135  oldW = 0  oldH = 0  
  10. 03-18 11:32:30.295 14844-14844/? I/tag: ----  onLayout ----  
  11. 03-18 11:32:30.310 14844-14844/? I/tag: ----  onMeasure ----  
  12. 03-18 11:32:30.310 14844-14844/? I/tag: ----  onLayout ----  
  13. 03-18 11:32:30.311 14844-14844/? I/tag: ----  onDraw ----  
  14. 03-18 11:32:30.311 14844-14844/? I/tag: ----  dispatchDraw =   
  15.  

 

2. void onFinishInflate();

当系统解析XML中声明的View后回调此方法,调用顺序:内层View->外层View,如果是viewgroup,适合在这里获取子View。
注意点
如果View没有在XML中声明而是直接在代码中构造的,则不会回调此方法
此时无法获取到View的宽高和位置

3. void onAttachedToWindow();

当view 被添加到window中回调,调用顺序:外层View->内层View。在XML中声明或在代码中构造,并调用addview(this view)方法都会回调该方法。
注意点
此时View仅仅被添加到View,而没有开始绘制所以同样获取不到宽高和位置

4. void onDetachedFromWindow();

看名字就知道是与void onAttachedToWindow();对应的方法,在VIew从Window中移除时回调,如执行removeView()方法。
注意点
如果一个View从window中被移除了,那么其内层View(如果有)也会被一起移除,都会回调该方法,且会先回调内层View的onDetachedFromWindow()方法。

5. void onWindowFocusChanged(boolean hasWindowFocus);

当View所在的Window获得或失去焦点时被回调此方法。除了常见的设置view的onGlobalLayoutListener,也可以通过这个方法取到VIew的宽高和位置;也适合在判断当失去焦点时停止一些工作,如图片轮播,动画执行等,当获取到焦点后继续执行。
hasWindowFocus:View所在Window是否获取到焦点,当该Window获得焦点时,hasWindowFocus等于true,否则等于false。

6. boolean onTouchEvent(MotionEvent event);

当手指触摸View的时候回调该方法,前提是触摸事件没有被拦截或者被子View消费掉。该方法是事件分发流程中最后的消费者。
event:触摸事件对象,包含了该事件的所有信息,如触摸的类型(down、move、up),触摸位置等。
返回值:true:事件被消费了,false:没有被消费,事件传递到外层View,super方法:同false。



 

 

自定义View流程:

步骤关键字作用
1构造函数View初始化
2onMeasure测量View大小
3onLayout确定子View布局(自定义View包含子View时有用)
4onDraw实际绘制内容
5onDraw实际绘制内容
   

About

总结自定义view的好文章  http://www.gcssloop.com/customview/CustomViewIndex/

 

 

自定义控件的生命周期

  • onFinishInflate() 当View中所有的子控件均被映射成xml后触发
  • onMeasure( int , int ) 确定所有子元素的大小
  • onLayout( boolean , int , int , int , int ) 当View分配所有的子元素的大小和位置时触发
  • onSizeChanged( int , int , int , int ) 当view的大小发生变化时触发,启动时间在onDraw之前
  • onDraw(Canvas) view渲染内容的细节
  • onKeyDown( int , KeyEvent) 有按键按下后触发
  • onKeyUp( int , KeyEvent) 有按键按下后弹起时触发
  • onTrackballEvent(MotionEvent) 轨迹球事件
  • onTouchEvent(MotionEvent) 触屏事件
  • onFocusChanged( boolean , int , Rect) 当View获取或失去焦点时触发
  • onWindowFocusChanged( boolean ) 当窗口包含的view获取或失去焦点时触发
  • onAttachedToWindow() 当view被附着到一个窗口时触发
  • onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和 onAttachedToWindow() 是相反的
  • onWindowVisibilityChanged( int ) 当窗口中包含的可见的view发生变化时触发


 

 

 

1,基准线居中的写法

mPaint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
float fontHeight = fontMetrics.bottom - fontMetrics.top;
float baseY = getHeight() - (getHeight() - fontHeight) / 2 - fontMetrics.bottom;

canvas.drawText(buttonText, getWidth() / 2, baseY, mPaint);

 

2,

android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。 
 Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 线程安全的,并且这些操作必须在UI线程中调用。 
 
 
canvas.drawArc(RectFoval, float startAngle, float sweepAngle, boolean useCenter,Paint paint);
startAngle--开始角度最右边是0°,最下面是90°
sweepAngle--转过角度从0开始

 

3,【基本语法】public void drawRoundRect (RectF rect, float rx, float ry, Paint paint)
参数说明 画圆角矩形
rect:RectF对象。
rx:x方向上的圆角半径。
ry:y方向上的圆角半径。
paint:绘制时所使用的画笔。

 

 

4,在onDraw里面不调用invalidate();   不然一直刷新

postInvalidateDelayed(200);//延迟刷新

 

5,控件设置长宽,位置Margins

LinearLayout.LayoutParamslinearParams = (LinearLayout.LayoutParams) iv_guide_up.getLayoutParams();// 取控件mGrid当前的布局参数
linearParams.height= heightNeedGuiInt;//当控件的高强制设成50linearParams.setMargins(10,2003040);
iv_guide_up.setLayoutParams(linearParams);// 使设置好的布局参数应用到控件

或者view.getLayoutParams().height = 100;
view.requestLayout();

 

requestLayout和invalidate区别

view调用invalidate将导致当前view的重绘(draw调用),view的父类将不会执行draw方法;viewGroup调用invalidate会使viewGroup的子view调用draw,也就是viewGroup内部的子view进行重绘;

requestLayout方法只会导致当前view的measure和layout,而draw不一定被执行,只有当view的位置发生改变才会执行draw方法,因此如果要使当前view重绘需要调用invalidate
 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值