Android自定义View属性相关细节
您已经看过
[清空]
    fa-home|fa-star-o
    域名查询linux虚拟主机域名注册主机域名rpc服务器不可用注册域名私人服务器vps美国服务器租用多少钱一年时间同步服务器
    当前位置:网站交易_网站买卖_高权重网站出售_权重域名>日收高权重域名>Android自定义View属性相关细节

    Android自定义View属性相关细节

    1

    概述

    在自定义View中去定义属性、获取属性,相关大家肯定都不陌生,不过在整个过程中还是会涉及到一些可能被大家忽略的细节问题。

    今天的文章主要讨论下面几个细节:

    1、obtainStyledAttributes 四个参数的详细的作用。

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

    3、自定义View中获取自定义属性,两种写法的区别 。

    是不是现在在想两种写法是什么玩意?恩,看完就知道了。

    2

    obtainStyledAttributes详解

    (1)基本用法

    ok,首先看一个非常常见的写法,假设我有一个自定义View叫做:AttrView,我们随便给它定义几个属性:

    res/values/attrs.xml

    对于在自定义View里面获取以上的属性,那么一般我们的代码是这样的:

    相信大家都很熟悉了~~

    obtainStyledAttributes这个方法实际上最终调用的是:

    可以看到实际上有4个参数,那么对于后两个参数到底是干嘛的呢,怎么使用呢?

    我们先看第4个参数,再看第3个参数。

    (2)defStyleRes

    接下来,我们先看最后一个参数,最后一个参数叫`defStyleRes `,其实是用于指定一个style,如下:777网站

    我们在styles.xml里面编写:

    可以看到我们声明了一个style,然后我们修改我们刚才获取属性的代码,修改为:

    ok,目前我们的布局文件是这样的(并未设置任何属性):

    运行看下结果:

    E/TAG﹕ test1 = falseE/TAG﹕ test2 = 3333E/TAG﹕ test3 = 278//139dp

    运行结果很明显的可以看出,如果我们不在布局文件中设置任何属性,那么会从在这个style中读取相关属性。

    下面接续看第三个参数

    (3)defStyleAttr

    注释上是这么描述的:

    An attribute in the current theme that contains a reference to a style resource

    说明它是一个引用类型的属性,指向一个style,并且在当前的theme中进行设置,如下:

    那么首先,我们先声明一个attr,当然还是写在attrs.xml里面:

    添加了一个新的引用格式的属性`attrViewStyleRef `。

    然后去styles.xml里面,找到我们所使用的theme,添加一条item:

    然后修改我们关键的一行代码:

    再次运行的结果为:

    E/TAG﹕ test1 = trueE/TAG﹕ test2 = 10086E/TAG﹕ test3 = 1776//888dp

    那么对于第三个参数呢,实际上用的还是比较多的,比如看系统的Button,EditText,它们都会在构造里面指定第三个参数:777网站

    提供一些参数的样式,比如background,textAppearance,textColor等,所以当我们切换不同的主题时,你会发现控件的样式会发生一些变化,就是因为不同的主题,设置了一些不同的style。

    那么推演到我们自定义的View,如果你的属性非常多,你也可以去提供默认的style,然后让用户去设置到theme里面即可。

    那么这样的话,大家对于obtainStyledAttributes应该有了进一步的认识,不过,如果同时设置defStyleAttr与defStyleRes,那么哪个优先级更高呢?

    defStyleRes的注释是这样介绍的:

    A resource identifier of a style resource that supplies default values for the TypedArray, used only if defStyleAttr is 0 or can not be found in the theme.

    那么可以看出,只有defStyleAttr设置为0或者在当前的theme中没有找到相关属性时,才会去defStyleRes中读取,那么很明显优先级是defStyleAttr更高,具体的实验大家自己测试。

    ok,那么解决了今天的第一个问题,接下来下一个。

    3

    构造方法中调用初始化代码

    大家可能会困惑,哪两种写法呢?

    (1)第一种

    (2)第二种

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

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

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

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

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

    那么我们简单写个例子:

    你在布局文件里面去声明,最后的效果是这样的:

    看到这样的效果,你信它是个按钮吗?

    当然了,如果你继承系统这个View,完全不在乎它原本的样子,那么就无所谓了。

    这种情况呢,也是存在的,就是我要的是系统控件的特性,但是它的样子不需要,比如你可以看到这个代码,继承了ProgressBar,因为要自定义UI风格,完全不需要系统的默认的样子,于是使用了第一种方式。

    https://github.com/hongyangAndroid/Android-ProgressBarWidthNumber777网站

    4

    获取自定义属性两种写法的区别

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

    (1) 第一种方式

    略(就是我们上面的写法)。

    (2)第二种方式

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

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

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

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

    那么,有什么影响呢?

    假设这么个场景:

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

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

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

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

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

    你还遇到过哪些值得注意的地方?欢迎留言。

    --- End ---

    欢迎关注公众号。

    Android自定义View属性相关细节》由《网站交易_网站买卖_高权重网站出售_权重域名》整理呈现,请在转载分享时带上本文链接,谢谢!

    支持Ctrl+Enter提交
    网站交易_网站买卖_高权重网站出售_权重域名 © All Rights Reserved.  Copyright Your WebSite.Some Rights Reserved.
    Powered by 网站交易 Themes by 日收域名出售