自定义View(待整理)

1.坐标系

View获取自身宽高
  • getHeight():获取View自身高度
  • getWidth():获取View自身宽度
View自身坐标

通过如下方法可以获得View到其父控件(ViewGroup)的距离:

  • getTop():获取View自身顶边到其父布局顶边的距离
  • getLeft():获取View自身左边到其父布局左边的距离
  • getRight():获取View自身右边到其父布局左边的距离
  • getBottom():获取View自身底边到其父布局顶边的距离
MotionEvent提供的方法

无论是View还是ViewGroup,最终的点击事件都会由onTouchEvent(MotionEvent event)方法来处理,MotionEvent也提供了各种获取焦点坐标的方法:

  • getX():获取点击事件距离控件左边的距离,即视图坐标
  • getY():获取点击事件距离控件顶边的距离,即视图坐标
  • getRawX():获取点击事件距离整个屏幕左边距离,即绝对坐标
  • getRawY():获取点击事件距离整个屏幕顶边的的距离,即绝对坐标

2.View测量模式

单一View测量过程
image

ViewRootImpl调用performMeasure方法后该方法中的DecorView又调用了measure方法,而DecorView的本质其实是集成自FrameLayout,那么本质就是一个ViewGroup,但是在FrameLayout和ViewGroup的源码中都没发现measure方法, 这就用到刚才的知识点了,ViewGroup本身也是View的子类,我们就去View的源码中查看一下,果然,measure方法赫然其中,在measure方法中,View又调用了其自身的方法onMeasure,而起自身的onMeasure方法中又调用setMeasureDimension方法,该方法有两个参数,这两个参数分别代表要设置的宽和高,而这两个参数都是是通过getDefaultSize方法来计算的,而getDefaultSize方法中有一个参数是根据getSuggestedMinimumWidth或getSuggestedMinimumHeight获得的。

ViewGroup的测量过程
image

通过遍历所有的子View进行子View的测量,然后将所有子View的尺寸进行合并,最终得到ViewGroup父视图的测量值。

MeasureSpec————测量规格

第一个功能自然是测量值了(Size),第二个功能是测量的模式(Mode),这两个参数通过二进制将其打包成一个int(32位)值来减少对内存的分配,其高2位(31,32位)存放的是测量模式,而低30位则存储的是其测量值。

  • UNSPECIFIED模式:本质就是不限制模式,父视图不对子View进行任何约束,View想要多大要多大,想要多长要多长,这个在我们写自定义View中的时候非常少见,一般都是系统内部在设置ListView或者是ScrollView的时候才会用到。
  • EXACTLY模式:该模式其实对应的场景就是match_parent或者是一个具体的数据(50dp或80px),父视图为子View指定一个确切的大小,无论子View的值设置多大,都不能超出父视图的范围。
  • AT_MOST模式:这个模式对应的场景就是wrap_content,其内容就是父视图给子View设置一个最大尺寸,子View只要不超过这个尺寸即可。

3.view体系结构

  1. View 是Android UI 控件的基类,ViewGroup也是继承自View,Android中的控件分为两部分,直接继承自View的控件和继承ViewGroup的布局(控件的集合),使整个Android控件形成的界面呈现出一个树形结构
  2. 在每个 Activity 创建时,同时会创建一个 Window (抽象类),Window 的具体通过 PhotoWindow 类实现,它也是唯一的 Window 实现类,PhotoWindow 又创建了一个 DecorView(间接的继承自View)作为整个Activity的根布局。DecorView 被分为两部分:ActionBar 部分(一般开发过程中都会隐藏,采用 google 推荐的 ToolBar)和 id 为 content的FragmentLayout部分,我们 setContentView(@LayoutRes int layoutResID) 设置的Activity XML布局就是在FragmentLayout中

4.view生命周期

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

自定义view实现方式分为四类:

  1. 继承五大布局(已经帮我们写好了一些容器规则),组合控件
  2. 继承viewgroup,流式布局
  3. 继承原生控件(textview,xrecyclerview,xlistview)
  4. 继承view

你可能感兴趣的:(自定义View(待整理))