前言:最近一段时间总是用到自定义view,每次总是查资料,然后模仿写,时间长了自己就有了惰性,感觉每次写都要去查,就下决心自己研究下,自己总结了一下关于自定义view的属性的理解,本文参考了自定义view的文章。
正文:关于自定义view的属性获取。
一。自定义view一般需要重写其三个构造方法
public ImageTextView(Context context) {
super(context);
}
public ImageTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ImageTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
1.第一个方法比较简单,只是简单的实例化就可以了.
2.第二个方法需要定义相应的属性,但是没有使用style的情况下使用.
3.地三个方法也需要自定义属性,在使用style的情况下使用.
ps:当然在项目中自定义view的时候这三个构造方法按情景使用,并且可以只使用一个super,其余两个用this调用其他的构造方法即可。
二。关于上述后两个构造方法的属性。attribute(属性) declare(声明) format(版式,样式)
为了方便在使用view 的时候像原生的view一样可以使用属性来直接约束或者赋值,自定义view的时候需要
自定义属性。
1.属性的创建or获得
/**
* TypedArray:对象描述类似数组的一个潜在的二进制数据的缓冲区(官方描述)
* 就是系统在默认的资源文件R.styleable中去获取相关的配置。
* 如果appearance不为空,它就会去寻找获取相关属性
* 也就是冲我们自定属性样式中,来引用你需要的某条属性
*/
TypedArray typedArray = context.obtainStyleAttribute(attrs, R.styleable.TextView);
这里获得的对象是TypedArray;attrs为xml布局文件里使用的属性集合,后边的是我们自己自定义的declare- styleable。
2.自定义declare-styleable
在values文件夹下 创建资源文件起名attrs在其中创建我们的declare-styleable资源属性
例:<declare-styleable name="TextView">
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="text" format="string"/>
<attr name="gravity" format="enum">
<enum name="center" value="0"/>
<enum name="top" value="1"/>
<enum name="bottom" value="2"/>
<enum name="left" value="3"/>
<enum name="right" value="4"/>
<enum name="center_horizontal" value="5"/>
<enum name="center_vertical" value="6"/>
</attr>
</declare-styleable>
这里有几点要说明一下:
(1)起的名字name="TextView"要与自定义view的类名最好一致,这样在使用的时候可以自动提示你自己命名的 属性;
(2)<attr name="textSize" format="dimension"/>使用自己定义的属性需要写好版式
<attr name=“android:text"/>使用系统的属性,不能添加format,否则会编译失败,因为系统已经制定,不能重 复。同样也不能在同一个工程里使用相同命名的属性,否则会编译出错。可以 在<resources>标签下
<attr name="name" format="string" />
<attr name="weight" format="float" />
进行事先声明然后公用 <attr name="name" /> 即可
(3)这里的枚举是为了像在LinearLayout 使用android:orientation="vertical"的时候自动提示并且限定输入范围。
3.属性的处理
int mTextColor = typedArray.getColor(R.styleable.TextView_textColor, Color.BLACK);
用typedArray对象去获得相应自定义属性的取值,当然这里的值有些是有默认的,比如int dimension等。
这里就将布局文件里自己赋进去的属性值取到了,然后可以对布局的相关view座自己想要的操作,比如tv.setTextColor(mTextColor);
这里自定义的操作比较多,不一一细说了,包括view的内容,样式,位置,动画等都可以进行相应的设置达到产品的需求。
PS:最后处理完以后要typedArray.recycle();这个是为了加入缓存循环利用。
4.属性值的类型format
format支持的类型一共有11种
(1).属性定义refrence
<attr name = "background" format = "reference" /> <ImageView android:background = "@drawable/图片ID"/>
(2).颜色值 color
<attr name = "textColor" format = "color" /> <TextView android:textColor = "#000000" />
(3).布尔值 boolean
<attr name = "isSelected" format = "booelean" /> <Button android:isSelected = "true"/>
(4).尺寸值 dimension
<attr name = "textSize" format = "dimension" /> <TextView android:textSize = "12sp" />
(5).浮点值 float
<attr name = "alpha" format = "float" /> <TextView android:alpha = "0.5" />
(6).整型值 integer
<attr name = "count" format = "integer" /> <TextView android:alpha = "5" />
(7).字符串 string
<attr name = "text" format = "string" /> <TextView android:text = "字符串" />
(8).百分数 fraction
<attr name = "pivotX" format = "fraction" /> <rotate android:pivotX = "100%"/>
(9).枚举值 enum 枚举值只能使用一个
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
<LinearLayout android:orientation = "vertical"></LinearLayout>
(10).位或运算 flag
<declare-styleable name="名称">
<attr name="windowSoftInputMode">
<flag name = "stateUnspecified" value = "0" />
<flag name = "stateUnchanged" value = "1" />
<flag name = "stateHidden" value = "2" />
<flag name = "stateAlwaysHidden" value = "3" />
<flag name = "stateVisible" value = "4" />
<flag name = "stateAlwaysVisible" value = "5" />
<flag name = "adjustUnspecified" value = "0x00" />
<flag name = "adjustResize" value = "0x10" />
<flag name = "adjustPan" value = "0x20" />
<flag name = "adjustNothing" value = "0x30" />
</attr>
</declare-styleable>
android:windowSoftInputMode = "stateUnspecified | stateUnchanged|stateHidden">可以同时使用。
(11).混合类型:属性定义时可以指定多种类型值
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
<ImageView android:background = "@drawable/图片ID" /> 或者: <ImageViewandroid:background ="#00FF00" />
5. Attributeset和TypedArray以及declare-styleable
a.Attributeset看名字就知道是一个属性的集合,实际上,它内部就是一个XML解析器,帮我们将布局文件中该控件的所有属性解析出来,并以key-value的兼职对形式维护起来。其实我们完全可以只用他来获取我们的属性就行。通过测试发现通过Attributeset获取属性的值时,它将我们布局文件中的值原原本本的获取出来的,比如宽度200.0dip,其实这并不是我们想要的,如果我们接下来要使用宽度值,我们还需要将dip去掉,然后转换成整型,这多麻烦。其实这都不算什么,更恶心的是,backgroud我应用了一个color资源ID,它直接给我拿到了这个id值,前面还加了个@,接下来我要自己获取资源,并通过这个ID值获取到真正的颜色。
b.我们都知道所有的资源文件在R中都会对应一个整型常亮,我们可以通过这个ID值找到资源文件。 属性在R中对应的类是public static final class attr,如果我们写了declare-styleable,在R文件中就会生成styleable类,
这个类其实就是将每个控件的属性分组,然后记录属性的索引值,而TypedArray正好需要通过此索引值获取属性。我们得到了想要的宽高(float型),背景颜色(color的十进制)等,TypedArray提供了一系列获取不同类型属性的方法,这样就可以直接得到我们想要的数据类型,而不用像Attributeset获取属性后还要一个个处理才能得到具体的数据,实际上TypedArray是为我们获取属性值提供了方便.