View 类的四个构造函数

写过自定义 View 的都知道,View 有四个构造函数,一般大家都知道第一个构造方法是简单的在代码中new View 的时候调用的,第二个构造方法使用最广泛,是对应的生成 xml 中定义的 View 的时候调用的。剩下的两个构造方法,大家了解的就比较少了。一般在自定义 View 的时候都会不加思索的按照固定的写法。

那么你有没有想探究一下里面的关系呢?

构造方法 View(Context context)

最简单的构造方法,当在代码中创建一个 View 的时候使用。这种构造方法我们一般不会使用。一般都是在 xml 中定义 view ,很少有直接进行 new view 的,这样写法也不符合规范!

构造方法 View(Context context,@Nullable AttributeSet attrs)

这个构造方法是我们最常用的,当我们在 xml 中定义了 View 然后在代码中使用这个 View 的时候,这个 View 就是利用这个构造方法生成的。View 的属性值来自 AttributeSet 的值。

构造方法 View(Context context,@Nullable AttributeSet attrs,int defStyleAttr)

这个构造方法就是提供了默认的 defStyleAttr 用于指定基本的属性。也就是允许 View 有自己基础的风格。例如:一个 Button 类在调用这个构造函数的时候会给 defStyleAttr 赋予一个默认的值 R.attr.buttonStyle 这个值包含了 Button 的一些基本的风格(会在 Theme 中给出),比如:最小宽度,最大宽度等等基础风格。当然这些值我们都可以在 xml 中通过属性直接改变。

构造方法 View(Context context ,@Nullable AttributeSet attrs,int defStyleAttr,int defStyleRes)

这个构造方法对比构造方法三就多了一个参数 defStyleRes 这个参数的作用就是再提供一个给 View 提供默认属性的手段。defStyleRes 就是把一些我们想要的属性写到一个 Style 里面,然后把这个 style 赋值给 defStyleRes 就可以了。

四个构造函数总结

第一个构造函数:这个构造函数就是在代码中直接 new view 的时候使用,这样出来的 View 默认是没有任何的属性值,需要后面自己手动 set。

第二个构造函数:这个构造函数是在代码中生成对应 xml 中定义的 View 使用的。这个时候在 xml 中定义的属性值会通过 AttributeSet 传递,这样生成的 View 对象是有默认的属性值的。

第三个构造函数:这个构造函数就是相对于第二个构造函数,多提供了一种给 View 添加默认属性的方式,通过 deftStyleAttr 如果没有默认的值,就用 0 。这样做的好处就是,我们可以默认一个 View 的基础风格。比如可以在 defSyleAttr 中设置背景颜色,字体大小等等基础风格,这样我们定义的这个 View 就有了原始风格了,当然如果你在 xml 中又设置了背景颜色,等于改变了原始的风格,是最优先于 xml 中的属性的。

其实我们使用的很多系统 View 都是通过这种方式来,这里用 Button 来举个例子

可以看到 Button 在使用第三个构造函数的时候,传入了 com.android.internal.R.attr.buttonSyle 这个属性,这个属性我们在属性定义文件 attr 中找到,这个属性的出现就是用来定义 Button 的默认风格的。

然后在主题中给 buttonStyle 赋值,找到系统 Theme

可以看到在系统的 Theme 中给 buttonSyle 赋值了,指向了 style/Widget.Holo.Light.Button 这个风格就指定了 Button 的默认风格,当然我们在定义主题的时候,可以自己定义 buttonStyle 这个属性的值。

看一下 style/Widget.Holo.Light.Button 的内容

这里定义了 Button 的一些默认的样式。

其他的 View 也都一样,都是这样的一个路子。

第四个构造函数:第四个构造函数相对第三个构造函数就多了一个 defStyleRes ,说白了就是多了一种提供 View 默认属性的一种方式。这种方式更加的简单,直接在代码中传入 R.style.XX 就可以了。如果没有默认值的话就为 0 。这个参数只有 defStyleAttr 为 0 的时候才会生效。

关于 AttributeSet

我们在 xml 布局文件中,定义 View 的时候,会设定这个 View 很多的属性。AttributeSet 就可以看做是这些属性的集合,包含了属性名和属性值。

举例说明:

第一步:定义 CustomTextView

可以看到,我在第二个构造函数中把 AttributeSet 的 name 和 value 都打印出来了。

第二步:xml 中使用 CustomTextView

第三步:运行程序,查看结果

可以看到 xml 中定义的 5 个属性全部打印出来。因此 AttributeSet 对应的就是 xml 布局文件中定义的属性

给 View 提供样式的方式

  • 直接通过 xml 中的属性

    这种方式是最直接的,体现形式就是直接在布局中设置属性,在 xml 布局文件中使用 style 也属于这种方式

  • 通过 deftStyleAttr 设置属性

    这种方式主要是用来设置默认属性风格的,使用方式见上面 button,主题中设置不同的类型,View的默认风格会发生改变。

  • 通过 defStyleRes 设置属性

    这种方式是直接在代码中指定一个默认的 style,和 Context 的主题没有关系

  • 在 Theme 中设置属性

    这种方式非常不常见,就是把在布局文件中设置的属性,直接放到 Them 中。

如果同时使用这几种方式给 View 设置了属性那么 View 听谁的呢?

xml中直接定义 > xml 中 style 定义 >defStyleAttr > defStyleRes > Theme 中直接定义

从 View 的四个构造方法说起的更多相关文章

  1. Android XML中引用自定义内部类view的四个why

    今天碰到了在XML中应用以内部类形式定义的自定义view,结果遇到了一些坑.虽然通过看了一些前辈写的文章解决了这个问题,但是我看到的几篇都没有完整说清楚why,于是决定做这个总结. 使用自定义内部类v ...

  2. 线程 Thread类 的四个构造方法简介

    在线程中,Thread类有四个构造方法: 当我们使用 Thread类创建对象的时候,传入参数,就会用到构造方法.ThreadStart 和ParameterizedThreadStart 都是 委托类 ...

  3. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  4. View (四)视图状态及重绘流程分析

    相 信大家在平时使用View的时候都会发现它是有状态的,比如说有一个按钮,普通状态下是一种效果,但是当手指按下的时候就会变成另外一种效果,这样才会给 人产生一种点击了按钮的感觉.当然了,这种效果相信几 ...

  5. 自定义View(四) ViewGroup 动态添加变长Tag标签 支持自动换行

    欲实现如下效果: 思路很简单就2步: 1.测量出ViewGroup的大小 2.找出子View的位置 若要实现动态添加标签view,就要实现ViewGroup的onMeasure().onLayout( ...

  6. Android View 上下左右四种间距的设置方法

    RecyclerView控件大家肯定不陌生,已经应用有一段时间了,最近在项目中写一个GridLayout样式的RecyclerView时需要设置,item之间左右的间距,下面是我总结的一个设置间距的方 ...

  7. Android艺术开发探索第四章——View的工作原理(上)

    这章就比较好玩了,主要介绍一下View的工作原理,还有自定义View的实现方法,在Android中,View是一个很重要的角色,简单来说,View是Android中视觉的呈现,在界面上Android提 ...

  8. 第四章:View的工作原理

    4.1 ViewRoot和DecorView ViewRoot对应于ViewRootImplement类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过Vie ...

  9. View绘制详解(四),谝一谝layout过程

    上篇博客我们介绍了View的测量过程,这只是View显示过程的第一步,第二步就是layout了,这个我们一般译作布局,其实就是在View测量完成之后根据View的大小,将其一个一个摆放在ViewGro ...

随机推荐

  1. 在springboot中使用swagger2

    1.在springboot中使用swagger的话,首先在pom文件中引入依赖 <!-- https://mvnrepository.com/artifact/io.springfox/spri ...

  2. Android studio 混淆打包安装后报错NullPointerException int java.util.List.size()

    菜鸟的我,尝试混淆打包app...打包之前没有什么问题,混淆打包之后遇到各种问题.首先,感谢原博主的分享.解决了我的问题.谢谢. 原文地址:http://blog.csdn.net/tou_star/ ...

  3. c语言进阶2-变量的作用域与无参函数

    一.       什么是函数 函数是具有特定功能的模块.可以说一个完整的程序其实是由多个函数共同完成的.C语言的全部工作都是由程式各样的函数完成的,所以也把C语言称为函数式语言.使用模块化设计可能 使 ...

  4. 2017day2

    系统模块: # Author: sonny# -*- coding:utf-8 -*-import sys; #print(sys.path);print(sys.argv);print(sys.ar ...

  5. compute节点上开启服务openstack-nova-compute.service时,无法启动的解决方法

          本文前一部分为本人解决问题的过程,但最终没有解决:无奈在网上找方法时,看到有网友评论说:修改controller上的guest账号密码,再重启openstack-nova-compute. ...

  6. 支持微信页面右侧悬浮QQ在线客服

    使用方法: 1.将style里的css样式复制到你的样式表中 2.将body中的代码部分拷贝到你需要的地方即可 (js.图片采用绝对路径,不建议修改) <!DOCTYPE html PUBLIC ...

  7. python课堂整理16---内置函数

    1. abs :求绝对值 print(abs(-1)) 2. all()传入一个可迭代对象,对该对象进行bool值运算,若都为True 就返回True,有一个为假,就返回False print(all ...

  8. 完美解决eclipse编辑器中文字符过小问题

    window – preferences – general – appearance – colors and fonts – basic – text font – edit 把弹出页面中“西欧语 ...

  9. web设计_8_数据表格内容样式分离

    1.页面需要用到table的时候,样式重置CSS要设置: table{ border-collapse: collapse; border-spacing:; } 2. HTML结构 <tabl ...

  10. Django安装 测试、导入项目以及运行开发服务器

    安装Django  下载Django包,解压缩. CMD 进入解压路径下. 执行:python setup.py install 增加环境变量: C:\Python27\Scripts 测试djang ...