Android View 四个构造函数详解

本文是在网上看到,感觉很好,就厚着脸皮拿过来了,在这里先对原著大牛叩罪,有时候遇到一个问题想在网上寻找答案,但能找到自己想要的答案既费时又费力,最终费了九牛二虎之力找到,又怕过些时间链接失效了,姑且把原文拿来自己保存,以便日后查阅,还是要叩谢作者,望谅解。

在开发android开发过程中,很多人都会遇到自定义view,一般都需要继承自View类,而当你打开View类的源码时,发现会有四个构造函数,那么这四个构造函数是如何使用的呢,怎么合理的利用四个构造函数呢,本文将进行一定探究,希望能够抛砖引玉。

一View类的四个构造函数

先从android源码中把四个构造函数拉出来看看。。

1第一个构造函数

1

2第二个构造函数

2

3 第三个构造函数

3

4 第4个构造函数

4

二 构造函数的调用

【第一个问题】

如果我们在继承了View类实现自定义类时,需要重写哪个构造函数?

回答这个问题,首先需要知道,在定义了View时,我们都调用了哪个构造函数。我这里做了一个简单的实验:

我们声明一个简单的View,继承自TextView,什么都不改,只是在4个constructor中打印几个tag,查看到底哪个构造函数被调用。

【实验】

实验

在布局文件layout中加上这个View

layout

[实验结果]

结果

【实验—结果分析】

通过上面的实验输出中的Second Constructor,我们知道,当我们自定义一个View,且在布局文件中引用时,在系统初始化该View时,调用的是第二个构造函数,而且我还把第二个构造函数中的attrs参数也打了出来,可以看出其中的参数attrs是我们在xml中配置的参数。

其实第一个构造函数用途并不大,主要是在Java代码中声明一个View时所用,不过如果只用第一个构造函数,声明的View并没有任何的参数,基本是个空的View对象。

三View的第三和第四个构造函数

在回答了第一个问题后,还有后两个构造函数,这是本文的重点。

1 View的属性和主题

在说后两个构造函数之前,先说说View的属性,在View中有不同的属性,比如layout_width等,TextView还有textColor这些特有的属性,我们可以对这些属性进行不同的配置进而实现不同的效果。而且属性也可以在不同的位置进行配置。以TextView为例,android:textColor这个属性可以在多个地方配置,可以直接写在xml中,可以在xml中以style的形式定义,这两种是我们平时见得较多的,其实还有一种背后的力量可以给属性赋值,那就是主题。

我们在android中可以配置一个主题,从而使得一些View即使你不对其进行任何配置,它都会有一些已经默认赋值的属性,这就是主题的功劳。

View类的后两个构造函数都是与主题相关的,也就是说,在你自定义View时,如果不需要你的View随着主题变化而变化,有前两个构造函数就OK了,但是如果你想你的View随着主题变化而变化,就需要利用后两个构造函数了。

2 属性赋值的优先级

当可以在多个地方赋值属性时,一个问题就不可避免的出现了:优先级!!!

一个属性可以在多个地方赋值,xml定义,xml中引入style,theme中直接指定,defStyleAttr,defStyleRes 这5个地方。(后面会将这几个地方的用处)

【第二个问题】

属性在多个地方被赋值后,系统以哪个属性为准呢?

我将用一个实验,利用多个TextView整体说明属性赋值的优先级,这个实验将贯穿文章后面,我将分块讲解。

【实验】

首先我们定义一个style文件,从style中可以看出,我们定义了一个主题,主题中有两种定义textView颜色的形式,一种是对textViewStyle进行定义(蓝色),一种是直接对textColor进行定义(紫色)。这是主题运用的两种方式,后面详述,现在我们只需要知道,我们的主题默认不是白色的!!!!

后面的几种style,每种对应一个颜色,用来区分优先级。

【实验 - style文件】

实验文件

【实验 -布局文件】

我们声明一个layout文件,里面有多个TextView和我自定义的View,现在我们自需要现在只看前三个TextView

布局文件

【实验结果】


结果

【实验 -结果分析1】

我们现在只看前三个TextView

第一个由于主题的原因,是蓝色

第二个style="@style/RedTextStyle",颜色是红色,说明优先级style>theme

第三个style和xml定义同时存在,

style="@style/RedTextStyle

android:textColor="@android:color/holo_orange_light"

显示橙色,说明优先级xml定义>style>theme

因此我们得到结论1:

【结论1】:优先级xml定义>style>theme

【实验 - 结果分析2】

但是theme的分析远没有结束,我们刚才在定义主题时,有两个赋值,

文件

为什么TextView默认的颜色是蓝色,而非紫色呢?????

这就需要研究View是如何利用系统主题,这时候需要回到我们今天的主题:View的构造函数!!!!

View中如何体现主题的信息,需要就通过实验对View进行彻底探究。这是一个复杂的问题,需要看看View的第三和第四个构造函数,在看这两个构造函数时,就不可避免的看到两个让人懵b的参数:defStyleAttr和defStyleRes。这时引入我们的第三个问题。

【第三个问题】

那么在View的第四个构造函数中的后面两个的参数都是什么意思呢?

我们首先看看View的注释:

注释

第四个构造函数中第三个参数defStyleAttr,从名字就能看出,是一个属性资源。

这个属性资源跟主题有一个奇妙的协议:只要在主题中对这个属性赋值,该View就会自动应用这个属性的值。

再看看在第四个构造函数中有一个参数defStyleRes,这个参数是什么作用呢?

先看注释:

注释

这个参数说,只有在第三个参数defStyleAttr为0,或者主题中没有找到这个defStyleAttr属性的赋值时,才可以启用。而且这个参数不再是Attr了,而是真正的style。其实这也是一种低级别的“默认主题”,即在主题未声明属性值时,我们可以主动的给一个style,使用这个构造函数定义出的View,其主题就是这个定义的defStyleRes(是一种写死的style,因此优先级被调低)。

【源码实例】

我们看一下在TextView中是如何给defStyleAttr和defStyleRes这两个参数赋值的。查看TextView的源码中,四个构造函数:

构造函数

可以看出,TextView的第2个构造函数直接调用了第3个构造函数,只是传了一个com.android.internal.R.attr.textViewStyle的参数,第三个在调用第四个构造函数时,最后一个参数是0.

【TextView 的defStyleAttr和defStyleRes】

也就是说在TextView中,TextView的第二个构造函数传入的defStyleAttrcom.android.internal.R.attr.textViewStyle

那么这个com.android.internal.R.attr.textViewStyle是个什么鬼呢,我们从源码中看看。

查看/Sdk/platforms/android-23/data/res/values这个路径中找个一个attrs.xml文件,打开看看,找到textViewStyle,如下所示,哦,原来是一个reference类型的属性,因此在给这个属性赋值时,在xml中一般使用@style/xxx形式就可以了。

style

app的主题可以为这个textViewStyle属性提供一套默认的style资源。比如在本例中,我们的主题继承自Theme.Holo中,在Theme.Holo中有一个item如下:

item

说明在Theme.Holo中,textViewStyle指向@style/Widget.Holo.TextView

因此默认情况下,TextView的属性都是在Widget.Holo.TextView这个Style中(但是其实这个style中并没有对textColor进行定义,有兴趣的可以自己去看看)。

在本例中我们自己定义了主题,通过继承Theme.Holo主题,修改这个textViewStyle的reference,使得textViewStyle指向了蓝色主题,如下所示。因此本文中app的TextView默认颜色是蓝色。

style

但是,我们的主题的内容并没有完结,很明显,我们在主题中还有一个android:textColor的赋值。

在同时使用了defStyleAttr(即主题中定义的textViewStyle)和主题直接定义时,显示了defStyleAttr的定义,说明使用了defStyleAttr的优先级要比直接在主题中声明优先级高。因此我们又得到一个结论。

【结论2】:优先级defStyleAttr>theme直接定义

【第四个问题】

从上文中我们知道了defStyleAttr和theme的顺序,那么defStyleRes的优先级呢?

现在需要确定defStyleRes的优先级了,我们重新回到我们的实验,我们的实验里,构造了三种自定义的View, CustomView, CustomBlankView和CustomGreenView。

CustomView的代码上面已写,现在将剩下两种自定义的View代码展示如下:

【实验 -CustemGreenView类】


CustemGreenView

【实验 -CustomBlankView类】

CustomBlankView

【实验-结果分析3】

在CustomGreenView中,defStyleAttr被赋值为0,defStyleRes赋值为R.style.GreenTextStyle,即我们的绿色style。

在CustomBlankView中,defStyleAttr和defStyleRes都为0,此时的颜色是紫色,即直接在theme中声明的颜色。

说明在同时在defStyleRes和主题中声明时,优先显示defStyleRes.由此又得出一个结论。

【结论3】:优先级 defStyleRes>theme直接定义

在实验的最后两个还是说明了直接在xml中写属性的优先级较高,即

【结论4】:优先级xml直接定义>xml的style定义>theme直接定义

【小结】

在Theme中的优先级主要涉及到三个部分:defStyleAttr,defStyleRes和主题直接定义

我们需要分三种情况,在构造函数中,

1 当defStyleAttr!=0时,

主题中如果对defStyleAttr属性进行赋值,显示对defStyleAttr的赋值,优先级最高!

2当(defStyleAttr==0或主题没有对defStyleAttr进行赋值)&& defStyleRes!=0而且theme中没有定义时时,显示defStyleRes,优先级中

3如果defStyleAttr==0且defStyleRes==0时,显示theme直接定义,优先级最低

由此我们得到属性赋值总体优先级:

【结论总】属性赋值优先级  Xml定义 > xml的style定义 >defStyleAttr> defStyleRes> theme直接定义

四 总结

在View类中有四个构造函数,涉及到多个参数,

Context:上线文,这个不用多说

AttributeSet attrs:从xml中定义的参数

intdefStyleAttr:主题中优先级最高的属性

intdefStyleRes: 优先级次之的内置于View的style

在android中的属性可以在多个地方进行赋值,涉及到的优先级排序为:

Xml直接定义 > xml中style引用 > defStyleAttr>defStyleRes > theme直接定义

总体来说,本文是对android中View的四个构造函数的探究,主要涉及到View属性的优先级问题。

叩谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容