3.1.1 View与ViewGroup浅析

3.1.1 View与ViewGroup浅析

标签: StudyNote


本文声明
本文由Coder-pig编写,想了解其他内容,可见CoderPig’s Android Study Note——目录
尊重作者劳动成果,未经本人授权,禁止转载!违者必究!
目录源地址:http://blog.csdn.net/coder_pig/article/details/51348769


1.简单介绍

  在Android APP中,所有的用户界面元素都是由ViewViewGroup的对象
构成的。View是绘制在屏幕上的,用户能与之交互的一个对象。而ViewGroup
则是一个用于存放其他View(和ViewGroup)对象的布局容器!
(ViewGroup是View的子类!)

  每个界面都是由View和ViewGroup组成的层次树(树形结构),我们可以根据
自己的需求,设计简单或者复杂的布局(PS:布局越简单性能越好,避免过多的布局嵌套)。

最顶层的ViewGroup我们有时也把他称为ViewParent对象,所有的交互管理事件都由
他来统一调度分配。而在Android中我们一般都是在Activity上创建用户界面,除此之外
Activity提供一些事件处理以及生命周期相关的API,Activity并不做和绘制有关的事情,
你更多的时候可以把他看作一个界面载体,在Activity中有一个Window抽象类
(通常由PhoneWindow实现)由他来完成绘制,当我们调用Activity的
setContentView()方法时,其实调用的就是Window的setContentView()方法。
而在Window类中有一个DecorView的内部类(FrameLayout扩展类),
在PhoneWindow调用setContentView()方法的时候会调用一个installDecor()的方法,
而在该方法中会创建一个DecorView作为整个应用窗口的根View。里面所有的View
的监听事件由WindowManagerService(WMS)来接收,通过Activity回调对应
的onClickListener。然后就到如图所示的TitleViewContentView了,
我们平时调用setContentView设置的就是ContentView这里的布局!


2.View的绘制流程简述

View树是遍历绘制的,每绘制一个View的逻辑是:

Created with Raphaël 2.1.0 View的绘制流程 是否需要重新测量视图大小(Measure) 是否需要重新布局(Layout) 是否重新需要绘制(Draw) View绘制完成

onMeasure(测量)

首先是测量(Measure) View的大小:
核心API是:MeasureSpec,int类型,32位,高2位保存SpecMode(测量模式),低30
位置为SpecSize(测量大小)。
测量模式有三种:

  • EXACTLY(大小固定):指定大小或者设置为match_parent会使用这个模式。
  • AT_MOST(最大值):指定为warp_content时会使用这个模式,控件大小随
    内容与子空间变化而变化,只要不超过父控件允许的最大尺寸即可。
  • UNSPECIFIED:不做任何限制,View想绘制多大就多大,自定义View才会用到。

View默认的onMeasure()方法只支持EXACTLY模式,在自定义View时不重写onMeasure()
方法就只能使用EXACTLY模式,即只支持具体大小与match_parent。如果想支持wrap_content
或者想支持UNSPECIFIED模式的话,需要重写onMeasure()方法,在onMeasure()方法中,有一个
setMeasuredDimension(measuredWidth,measureHeight)的方法,将测量后的宽高传入
即可完成测量工作,贴下简单的模板代码:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        switch (specMode) {
            case MeasureSpec.EXACTLY:
                result = specSize;
                break;
            case MeasureSpec.AT_MOST:
                result = Math.min(200,specSize);    
                break;
            case MeasureSpec.UNSPECIFIED:
                result = 300;
                break;
        }
        return result;
    }

onLayout(位置)

确定View的位置,但是要注意一点的是,一般是自定义ViewGroup才会来重写onLayout()
这个方法,ViewGroup会遍子View,然后调用该子View的layout()方法设置他的坐标值。

简单示例如下:

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        for (int i = 0, size = getChildCount(); i < size; i++) {
            View childView = getChildAt(i);

            // 获取在onMeasure中计算的视图尺寸
            int measureHeight = childView.getMeasuredHeight();
            int measuredWidth = childView.getMeasuredWidth();

            childView.layout(left,0,measuredWidth,measureHeight);
        }
    }

onDraw(绘制)

大小和位置都确定了,接着就是绘制了,onDraw()方法为我们提供了一个Canvas画板,
然后可以调用绘图相关的API对View进行绘制,我们可以在其它地方调用:
invalidate或者postInvalidate方法,让View进行重绘!


3.View与ViewGroup属性汇总

——摘自:宅学长的博客

第一类:属性值 true或者 false

属性说明
android:layout_centerHrizontal水平居中
android:layout_centerVertical垂直居中
android:layout_centerInparent相对于父元素完全居中
android:layout_alignParentBottom贴紧父元素的下边缘
android:layout_alignParentLeft贴紧父元素的左边缘
android:layout_alignParentRight贴紧父元素的右边缘
android:layout_alignParentTop贴紧父元素的上边缘
android:layout_alignWithParentIfMissing如果对应的兄弟元素找不到的话就以父元素做参照物
android:layout_alignParentStart紧贴父元素结束位置开始
android:layout_alignParentEnd紧贴父元素结束位置结束
android:animateLayoutChanges布局改变时是否有动画效果
android:clipChildren定义子布局是否一定要在限定的区域内
android:clipToPadding定义布局间是否有间距
android:animationCache定义子布局也有动画效果
android:alwaysDrawnWithCache定义子布局是否应用绘图的高速缓存
android:addStatesFromChildren定义布局是否应用子布局的背景
android:splitMotionEvents定义布局是否传递touch事件到子布局
android:focusableInTouchMode定义是否可以通过touch获取到焦点
android:isScrollContainer定义布局是否作为一个滚动容器 可以调整整个窗体
android:fadeScrollbars滚动条自动隐藏
android:fitsSystemWindows设置布局调整时是否考虑系统窗口(如状态栏)
android:visibility定义布局是否可见
android:requiresFadingEdge定义滚动时边缘是否褪色
android:clickable定义是否可点击
android:longClickable定义是否可长点击
android:saveEnabled设置是否在窗口冻结时(如旋转屏幕)保存View的数据
android:filterTouchesWhenObscured所在窗口被其它可见窗口遮住时,是否过滤触摸事件
android:keepScreenOn设置屏幕常亮
android:duplicateParentState是否从父容器中获取绘图状态(光标,按下等)
android:soundEffectsEnabled点击或触摸是否有声音效果
android:hapticFeedbackEnabled设置触感反馈

第二类:属性值必须为id的引用名“@id/idname”

属性说明
android:layout_alignBaseline本元素的文本与父元素文本对齐
android:layout_below在某元素的下方
android:layout_above在某元素的的上方
android:layout_toLeftOf在某元素的左边
android:layout_toRightOf在某元素的右边
android:layout_toStartOf本元素从某个元素开始
android:layout_toEndOf本元素在某个元素结束
android:layout_alignTop本元素的上边缘和某元素的的上边缘对齐
android:layout_alignLeft本元素的左边缘和某元素的的左边缘对齐
android:layout_alignBottom本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight本元素的右边缘和某元素的的右边缘对齐
android:layout_alignStart本元素与开始的父元素对齐
android:layout_alignEnd本元素与结束的父元素对齐
android:ignoreGravity指定元素不受重力的影响
android:layoutAnimation定义布局显示时候的动画
android:id为布局添加ID方便查找
android:tag为布局添加tag方便查找与类似
android:scrollbarThumbHorizontal设置水平滚动条的drawable
android:scrollbarThumbVertical设置垂直滚动条的drawable
android:scrollbarTrackHorizontal设置水平滚动条背景(轨迹)的色drawable
android:scrollbarTrackVertical设置垂直滚动条背景(轨迹)的色drawable
android:scrollbarAlwaysDrawHorizontalTrack设置水平滚动条是否含有轨道
android:scrollbarAlwaysDrawVerticalTrack设置垂直滚动条是否含有轨道
android:nextFocusLeft设置左边指定视图获得下一个焦点
android:nextFocusRight设置右边指定视图获得下一个焦点
android:nextFocusUp设置上边指定视图获得下一个焦点
android:nextFocusDown设置下边指定视图获得下一个焦点
android:nextFocusForward设置指定视图获得下一个焦点
android:contentDescription说明
android:OnClick点击时从上下文中调用指定的方法

第三类:属性值为具体的像素值,如30dip,40px,50dp

属性说明
android:layout_width定义本元素的宽度
android:layout_height定义本元素的高度
android:layout_margin本元素离上下左右间的距离
android:layout_marginBottom离某元素底边缘的距离
android:layout_marginLeft离某元素左边缘的距离
android:layout_marginRight离某元素右边缘的距离
android:layout_marginTop离某元素上边缘的距离
android:layout_marginStart本元素里开始的位置的距离
android:layout_marginEnd本元素里结束位置的距离
android:scrollX水平初始滚动偏移
android:scrollY垂直初始滚动偏移
android:padding指定布局与子布局的间距
android:paddingLeft指定布局左边与子布局的间距
android:paddingTop指定布局上边与子布局的间距
android:paddingRight指定布局右边与子布局的间距
android:paddingBottom指定布局下边与子布局的间距
android:paddingStart指定布局左边与子布局的间距与android:paddingLeft相同
android:paddingEnd指定布局右边与子布局的间距与android:paddingRight相同
android:fadingEdgeLength设置边框渐变的长度
android:minHeight最小高度
android:minWidth最小宽度
android:translationX水平方向的移动距离
android:translationY垂直方向的移动距离
android:transformPivotX相对于一点的水平方向偏转量
android:transformPivotY相对于一点的垂直方向偏转量

第四类:属性值为Android内置值

属性说明
android:gravity控件布局方式
android:layout_gravity布局方式
android:persistentDrawingCachehua定义绘图的高速缓存的持久性
android:descendantFocusability控制子布局焦点获取方式 常用于listView的item中包含多个控件点击无效
android:scrollbars设置滚动条的状态
android:scrollbarStyle设置滚动条的样式
android:fitsSystemWindows设置布局调整时是否考虑系统窗口(如状态栏)
android:scrollbarFadeDuration设置滚动条淡入淡出时间
android:scrollbarDefaultDelayBeforeFade设置滚动条N毫秒后开始淡化,以毫秒为单位
android:scrollbarSize设置滚动调大小
android:fadingEdge设置拉滚动条时 ,边框渐变的放向
android:drawingCacheQuality设置绘图时半透明质量
android:OverScrollMode滑动到边界时样式
android:alpha设置透明度
android:rotation旋转度数
android:rotationX水平旋转度数
android:rotationY垂直旋转度数
android:scaleX设置X轴缩放
android:scaleY设置Y轴缩放
android:verticalScrollbarPosition设置垂直滚动条的位置
android:layerType设定支持
android:layoutDirection定义布局图纸的方向
android:textDirection定义文字方向
android:textAlignment文字对齐方式
android:importantForAccessibility设置可达性的重要行
android:labelFor添加标签
android:background本元素的背景

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值