Android 自定义View属性相关细节

来源:互联网 发布:日语打字员淘宝兼职 编辑:程序博客网 时间:2024/05/12 20:17

从鸿洋的公众号上看到的,在博客上没找到,自己也一直疑惑所以记了下来。(1.19日更新:擦,微信图片被屏蔽了,害得我自己专门截图)

  1. 自定义View中构造方法中调用初始化代码,两种写法的区别

(1)第一种




(2)第二种

      在每个方法中通过自己定义的init()方法初始化数据。


对于两种写法,大家都不陌生吧,肯定的,谁都见过,但是很少有人会去问:这两种有什么区别呢?

说实话,区别不大,但是在使用场景上还是需要注意的,下面简单说几个场景。


1. 如果需要设置obtainStyledAttributes的第三个参数,即`defStyleAttr`,一般会使用第一种方式,会在两个参数的构造中,去调用三个参数的构造,同时传入`defStyleAttr `。如果没有此需求,两种写法没有什么区别。

2. 继承系统已有的控件去自定义View,比如你继承Button,去做一些事情

第一种方式会覆盖掉Button默认在theme里面设置的style,相对来说第二种方式更为合适(这条是一定要注意的,切记,切记)。

当然了,如果你继承系统这个View,完全不在乎它原本的样子,那么就无所谓了。这种情况呢,也是存在的,就是我要的是系统控件的特性,但是它的样子不需要,比如:https://github.com/hongyangAndroid/Android-ProgressBarWidthNumber,你可以看到这个代码,继承了ProgressBar,因为要自定义UI风格,完全不需要系统的默认的样子,于是使用了第一种方式。

  1. 自定义View中获取自定义属性,两种写法的区别 看到这个标题,你是不是很郁闷,我擦,获取自定义属性,也有两种写法?

(1) 第一种方式



(2)第二种方式




等你细细的看完,你可能会认为,我擦,这种写法好傻逼,直接指定index不就行了,这个for循环根本没鸟用。其实并不是这样的,这种写法有它考虑到的地方,而且系统中很多类中获取属性的方式都是这样的方式(例如:TextView)。


注:如果switch报错,可以改为if-else


不过,这种写法和第一种写法还是有一定的区别的:


  •  第一种写法,不管你有没有在布局文件中使用该属性,都会去执行getXXX方法赋值,

  • 第二种写法,只有在你布局文件中设置了该属性后,才会去调用getXXX方法赋值。


那么,有什么影响呢?


假设这么个场景:


private int attr_mode = 1;//默认为1//然后你在写getXXX方法的时候,是这么写的:attr_mode = array.getInt(i, 0);


可能你的自定义属性有个默认的值,然后你在写赋值的时候,一看是整形,就默默的第二个参数就给了个0,然而用户根本没有在布局文件里面设置这个属性,你却在运行时将其变为了0(而不是默认值),而第二种就不存在这个问题。当然这个场景可以由规范的书写代码的方式来避免,(把默认值提取出来,都设置对就好了)。


其实还有个场景,假设你是继承自某个View,父类的View已经对该成员变量进行赋值了,然后你这边需要根据用户的设置情况,去更新这个值,第一种写法,如果用户根本没有设置,你可能就将父类的赋值给覆盖了。


在日常编码中时候,这些细节经常被忽视,而且很难发现!


ok,文本都是一些自定义View时平时可能会忽略的东西,希望可以帮助到你。


0 0
原创粉丝点击