带你初始View

什么是自定义View 那么是View , View是Adnroid中所有控件的基类,不管是简单的Button 还是TextView 都是复杂的RelativeLayout 和ListView 他们的基类无非都是View, View是一种的界面层的控件的一种抽象,他代表了一个控件。除了View还有ViewGroup,ViewGroup的内部包含了很多控件,也就是一组View。在Adnroid中ViewGroup 也是继承自View所以说View本身可以是单个控件也可以是多个控件组成的一组控件, 这种关系就形成了View树的结构,这和Web前端中的DOM树的结构的概念是相似的。

一. View位置的参数

View位置主要是由它的四个定点来决定,分别对应于View的四个属性:top,left/right,bottom,

top 左上角纵坐标, left是左下角横坐标,right是左下角横坐标 , bottom是右下角纵坐标

注意: 这些其实都是根据父容器的来说的因此是一个相对坐标

那么如何得到View的四个参数 方法 getLeft(),getRight(),getTop(),getBottom()

从安卓3.0开始View增加了额外的几个参数:X,Y,translationX,和translationY其中X和Y是View左上角的坐标,而translation和 translationY是View左上角相对于父容器的偏离,并且translationX,和translationY的默认值是0和View的四个基本位置一样都提供了get/set方法。

x=left+translationX y=top+translationY

需要注意的是View在平移的过程中,top和left表示的是原始左上角的信息,值并不会发成改变,但改变X/Y,translationX/translationY

二.自定View需要了解的事件 MotionEvent

1:在手指触摸屏后产生的一系列的事件中典型的事件有

ACTION_DOWN----------手指接触到屏幕也就是按下事件

ACTION_MOVE----------手指在屏幕上移动

ACTION_UO---------------手指从屏幕上松开

正常的情况下一次手指触摸屏幕的行为是ACTION_DOWN 中间可能按住滑动也就是说有多个ACTION_MOVE到ACTION_UO

并且可以通过MotionEvent可以获得X/Y的坐标,方法getX/getY,这俩方法返回的是相对于当前View左上角的X和Y的坐标而getRawX/getRawY返回的是相对于手机屏幕左上角的X和Y的坐标

以上是对View的认识 接下来就是自定义View的探索了, 喝口水咱们继续

三 View的绘制过程了解

View的绘制流程是ViewRoot 中的perfromTraversals的方法开始,它经过measure,layout,draw三个过程才能将一个View绘制出来,其中

measure用来测量View的宽和高,layout用来确定View在父容器中的放置位置,draw负责讲View绘制在屏幕,并且measure是用final修饰的方法 也就以为这子类不能重写此方法,但是在measure中回去调用View的OnMeasure的方法

measure的过程决定了View的宽高,在Measure完成后可以通过getMeasuredWidth/getMeuredHeight方法来获取View测量后的宽/高,但是在一些复杂的布局中或者极端的情况写measure可能会调用多次因此getMeasuredWidth/getMeuredHeight方法获取的宽/高可能不准确也就是在OnMeasure方法中拿到的,但是一般在OnLayout中去拿View的测量宽和高比较好

layout完成后可以通过 getLeft(),getRight(),getTop(),getBottom()拿到View的四个顶点的坐标,还可以通过getWidth/getHeight获取到View的最终宽高

以上了解了自定义View的绘制过程

四 ViewGroup的绘制过程

ViewGroup是存放的一组控件的容器所以在完成自己measure过程后还会去遍历去调用所有子元素的measure方法是通过for循环进行遍历遍历的是数组通过for循环的索引进行遍历,了·9,和View不同的ViewGroup是一个抽象的类,因此它没有重写Veiw的OnMeasure方法但提供了measreChildren的方法

五 layout的过程

Layout 的作用是ViewGroup用来确定子元素的位置,在ViewGroup的位置确认后,它在 OnLayout中会遍历所用的子元素并调用其layout方法,在layout方法中OnLayout方法又会调用,lauout方法确认View本身的位置,而OnLaout方法则会确定所有子元素的位置。

六. draw过程

它的作用是将View绘制到频幕上,View的过程是一下几步

1,绘制背景( basckground.draw(canvas) )

2,绘制自己 ( onDraw )

3,绘制children (dispatchDraw )

4,绘制装饰( onDrawScrollbars )

7, 扩展

measure用来测量View的宽和高, 假如在我Activity已经启动的时候就做一件任务,这一任务就是获取某个View的宽高,你在这肯定想在OnCreate或者OnResume里面去获取这个View的宽高, 哈哈那么你就中招了不信你可以试试,

实际上在OnCreate,OnStract,OnResume,中均无法正确获取这个View的正确信息,这是因为View在measure过程和Activity中的生命周期方法不是同步执行所以在Activity的生命周期中是无法保证measure某个View的高度,如果View没有测量完成那就全是0;

这边提供4 和方法能够解决这个问题

(1) onWindoFocusChanged

这个方法是View已经初始化完成,宽和高已经可以正确获取,但是此方法在Activity的窗口得到焦点和失去焦点的时候都会调用多次。

(2) view.post(runnable)

将一个线程投递到消息队列的尾部,然后等待Looper调用此runnable的时候View已经初始化好了

(3) ViewTreeObserver

这个和第一个差不多都会调用多次。

(4)view.measure(int widthMeasureSpec,int heightMeasureSpec)

转载说明出处

猜你喜欢

转载自blog.csdn.net/qq_42046338/article/details/82490572