赞
踩
目前对于view还处于学习阶段,本来打算学习结束之后再写一篇进行总结,但是发现自己自制力太差,学习效率太低,所以在此,边学边写博客,不仅督促自己完成对view的学习,而且还可以看看大家对于view有什么想知道的,顺便来看看自己需要研究些什么。
请尊重技术原创,转载请注明出处 ,本文出自
View是基本的用户界面组件,一个view拥有屏幕上的一块儿矩形区域,可以进行绘制以及事件events的处理。View类是各种控件widget类的基类,控件widget是那些用户交互UI组件,比如,button,textview,imageview等等。View的子类ViewGroup是界面布局layout的基类,layout是指linearlayout,relativelayout等等,这些layout是一些不可见但占有space的invisible的布局容器,可以包括layout或者widget,并且可以声明他们自己的layout属性。(笔者注:invisible是说控件存在屏幕上已经布局了该view但是不可见此时控件可以有事件处理逻辑,gone是指控件不存在屏幕上现在不存在该view);
一个Window窗口中所有的view都在同一个tree即树形结构中。往一个树形结构中添加view有两种方法
1,可以通过代码添加(笔者注:调用viewgroup的addview方法 ,如下代码),
- RelativeLayout mRl = (RelativeLayout) findViewById(R.id.rl);
- TextView tv = new TextView(this);
- tv.setText("这是在代码中加载的view");
- tv.setTextColor(Color.RED);
- mRl.addView(tv);
要想自定义view,你可以覆写一些framework层使用view时调用的一些标准方法,不需要覆写所有的,事实上,可以覆写onDraw,如下表所示
Category | Methods | Description |
Creation | Constructors(构造器方法) | 当view在代码中被创建时会调用该方法,填充xml文件时也会调用该方法 |
onFinishInflate() | 当view以及他所有的子view都被填充时会调用该方法 | |
Layout | onMeasure(int ,int ) | 决定view与子view所要求的大小时调用 |
onLayout(boolean,int,int,int,int) | 当view给子view分配size和position,大小和位置的时候会调用 | |
onSizeChanged(int,int,int,int) | 当view的size发生改变时会调用 | |
Drawing | onDraw | 当view需要提供content内容时调用 |
Event Processing(事件处理) | onKeyDown(int,KeyEvent) | 当有物理按键被按下时会调用 |
onKeyUp(int,KeyEvent) | 当物理按键抬起时会调用 | |
onTrackBallEvent(MotionEvent) | ???Called when a trackball motion event occurs(笔者注:何时触发,view轨迹移动) | |
onTouchEvent(MotionEvent) | 当有触摸事件发生时会触发 | |
Focus | onFocusChanged(boolean,int,android.graphics.Rect) | 当view的焦点发生改变时(失去或者获取焦点)会调用该方法 |
onWindowFocusChanged(boolean) | 当包含这个view的window获取或者失去焦点时(activity的生命周期有关) | |
Attaching | onAttachedToWindow() | 当与window绑定时会调用该方法 |
onDetachedFromWindow() | 当与window解除绑定时会调用该方法 | |
onWindowVisibilityChanged(int) | 当所绑定的window的可见性发生改变时会调用 |
在笔者刚开始自定义view时问题很多,比如在xml文件中使用时会报出填充异常等等,很多都是因为对view的构造方法不熟悉导致的。只有了解了基础,才能进行举一反三,毕竟关于view的这些都是依靠这些基础而来的,不论再多变,不变的是基础!!!
对于onMeasure,onLayout,onDraw以及事件的处理,需要仔细分析。对于这些方法的分析先留着以后进行,接下来继续对view的介绍
对于view的id应该没什么好说的了,经常使用。view需要一个整形的id与其对应,在你所查找的view树范围(一个window窗口)内,ID具有唯一性。所以在view树中可以通过ID来寻找view
view的几何形状是个矩形(笔者注:自定义selector改变形状除外),left和top的值决定了view的location(位置),宽和高的大小决定了view的size(尺寸大小),不论是尺寸还是位置单位都是像素。笔者注:所以可以知道通过getLeft(view的X坐标)和getTop(view的Y坐标)就可以获取到view的位置(但是所获取到的getLeft和getTop都是相对于它的父view来说的)
Size:View的大小通过宽和高两个值来体现,事实上一个view拥有两对宽和高的值
Padding : 为了测量view的尺寸,需要将Padding考虑在内,View的padding包括left、top、right、bottom。padding用来表示view的内容的偏移量,(这个不再多说,目前还没看到需要有什么注意的地方,如果以后有遇到再说)
Margins:margin说的是view与view之间的距离,所以对于单个view来说没有margin的概念,margin是针对viewgroup来说的。
- <resources>
-
- 。。。。。
- <item name="R.tag.view" type="id"/>
- </resources>
可以看到有两种方式,第一是setTag(要保存的信息),第二种是setTag(key,value);如果你只需要保存一个view相关的信息,完全可以使用setTag(value)的方式,但如果要保存的view的信息有多个,那就要使用setTag(key,value)来保存,然后通过对应的tag的key来获取所保存的信息。
其他与measure,layout,draw以及触摸或者按键事件的处理过程需要详细研究
【S】【actor added 】【2016-12-29】
Layout包含两个过程:measure测量过程和layout定位布局的过程。
通过measure(int,int)来实现测量过程,测量是对view树从上到下进行递归测量的一个过程。在递归测量的过程中每一个view把自己的测量数据交给view树。在测量过程结束后每一个view存储了自己的测量值。
layout定位布局的过程发生在layout(int,int,int,int),也是沿着view树从上到下的过程,在layout过程中每一个父view有责任根据measure过程中所计算的子view的大小去定位子view的位置。
当一个view的measure的方法返回时,该view的measuredWIdth和measuredHeight必须被设置,也就是说,如果调用了measure方法对view进行了测量,那就必须调用setMeasuredDimensionRaw方法将view包括该view的子view的measuredHeight和measuredWidth保存起来。view的measuredHeight/measuredWidth大小必须遵循父view对子view的限制。只有这样才能保证在测量过程结束后父view能够接受子view的尺寸,进行更好的布局。父view可能对子view多次调用measure方法。例如,父view去测量未指明大小的view所想要的size,又或者所有view的大小加起来过大或者过小时就会重新进行measure。
measure的过程涉及到两个类。一个是MeasureSpec(测量规范)用来让子view告诉父view他们想要怎样被测量。还有一个LayoutParams类用来描述一个view想要多大,对于view的尺寸可能是以下三种的一个值
不同的viewgroup有不同 的layoutparams的子类,例如,Absolutelayout的layoutparams的子类可以添加X和Y的值。
测量规范是父view对子view的一个测量规范,一个测量规范有三种模式
通过调用requestlayout()方法可以初始化layout,当一个view察觉到当前的边界已经不再适合时会调用。
Drawing用来遍历整个view树并且渲染无效区域的view,因为drawing是沿着view进行遍历的,这也就意味着父view优先于子view的绘制,同一级的view是按照他们view树中出现的顺序进行绘制,如果你给一个view设置了背景图片,那么在回调onDraw方法之前会优先绘制背景图片。
framework不会绘制不处于无效区域(无效区域是指还未被使用的一片区域)的view。
通过调用invaliate()方法来强制进行drawing。
可以调用setAnimation(animation)或者startAnimation(animation)来给view绑定一个动画。动画可以是view进行伸缩,旋转,平移和透明度渐变的动画。如果一个有子view的view添加了动画,那么这个动画会影响以该view为一个根节点沿着view树向下的所有view。当开始动画后,framework会按照动画要求对view进行重新绘制,直到动画结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。