首页 菜鸟问答正文

Android自定义View属性相关细节

piaodoo 菜鸟问答 2022-08-04 06:32:22 860 0

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,如下:solidworks2018安装教程

我们在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,它们都会在构造里面指定第三个参数:solidworks2018安装教程

提供一些参数的样式,比如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)第二种

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

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

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

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

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

那么我们简单写个例子:

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

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

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

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

https://github.com/hongyangAndroid/Android-ProgressBarWidthNumbersolidworks2018安装教程

4

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

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

(1) 第一种方式

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

(2)第二种方式

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

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

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

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

那么,有什么影响呢?

假设这么个场景:

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

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

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

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

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

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

--- End ---

欢迎关注公众号。

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:https://www.piaodoo.com/119075.html

社交距离(socialdistance)

  • 表距离还在用distance吗?其实你还有其他选择

    表距离还在用distance吗?其实你还有其他选择

  • △5日,海南三亚,核酸检测有序开展。

  • 全国疫情今天(8月6日)最新消息通报:昨日本土新增310+275,其中海南262+46

  • 北京疫情地图分布图实时更新(查询入口)

    北京疫情地图分布图实时更新(查询入口)

  • 搜索

    文章专栏

    最近发表

    标签列表