Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说android自定义属性详解_android自定义组合控件,希望能够帮助你!!!。
分享职场生活、职场攻略、领导同事相处技巧和创业资源
01
对于一个Android开发者来说,自定义控件是一项重要的技能,然而对于大部分人而言,感觉自定义控件并不是那么好对付。在工作过程中难免需要遇到一些特效需要通过自定义控件来实现,如果对自定义不是很熟练,开发起来会比较吃力。
在学习自定义控件,不知你有没有这样的疑问:
今天我们一起来探讨自定义属性。
要使用自定义属性首先我们得有这个自定义属性。
常见的TextView控件的Android:text属性是怎么来的呢,我们来一起看一下系统的自定义属性源码,系统定义的所有属性我们可以\sdk\platforms\Android-xx\data\res\values目录下找到attrs.xml这个文件,这里只找几个很常见的view属性。
<declare-styleable name="View">
<attr name="id" format="reference" />
<attr name="background" format="reference|color" />
<attr name="padding" format="dimension" />
...
</declare-styleable>
<declare-styleable name="TextView">
<attr name="text" format="string" localization="suggested" />
<attr name="hint" format="string" />
<attr name="textColor" />
<attr name="textColorHighlight" />
<attr name="textColorHint" />
...
</declare-styleable>
<declare-styleable name="ViewGroup_Layout">
<attr name="layout_width" format="dimension">
<enum name="fill_parent" value="-1" />
<enum name="match_parent" value="-1" />
<enum name="wrap_content" value="-2" />
</attr>
<attr name="layout_height" format="dimension">
<enum name="fill_parent" value="-1" />
<enum name="match_parent" value="-1" />
<enum name="wrap_content" value="-2" />
</attr>
</declare-styleable>
<declare-styleable name="LinearLayout_Layout">
<attr name="layout_width" />
<attr name="layout_height" />
<attr name="layout_weight" format="float" />
<attr name="layout_gravity" />
</declare-styleable>
<declare-styleable name="RelativeLayout_Layout">
<attr name="layout_centerInParent" format="boolean" />
<attr name="layout_centerHorizontal" format="boolean" />
<attr name="layout_centerVertical" format="boolean" />
...
</declare-styleable>
我们知道我控件都是继承自View的,View类具有的属性我们继承它的子类也拥有了,而我们父view类却不能使用子View的特有的属性,充分的体现了我们的语言的多态性。
聪明的你应该发现上面都有一个共同点,就是 里面还有一系列子标签,而这些子标签就表示这是其属性。
但并不是每个控件都能使用所有属性,譬如LinearLayout有layout_weight属性,而RelativeLayout却没有,因为layout_weight是为LinearLayout的LayoutParams定义的。
细心的你,应该注意到,attr标签后面有的带了format属性,有的没有。带有format的就是自定义属性,没有带format的就是在使用已有的属性,name的值就是属性的名称,format则是限定当前定义的属性能接受什么值。
我们知道,系统定义的属性一般引用是android:XX引用,如果我们现在要定义一个text属性。
常规定义方式:
<resources>
<declare-styleable name="CustomerTextView">
<attr name=“text" format="string" />
</declare-styleable>
</resources>
或者引用系统已经定义:
<resources>
<declare-styleable name="CustomerTextView">
<attr name=“android:text"/>
</declare-styleable>
</resources>
format一共支持11种类型
1、 reference
属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference" />
</declare-styleable>
属性使用:
<ImageView android:background = "@drawable/ImageViewId"/>
2、color
属性定义:
<attr name = "textColor" format = "color" />
属性使用:
<TextView android:textColor = "#00FF00" />
3、boolean
属性定义:
<attr name = "focusable" format = "boolean" />
属性使用:
<Button android:focusable = "true"/>
4、dimension
属性定义:
<attr name = "layout_width" format = "dimension" />
属性使用:
<Button android:layout_width = "42dip"/>
5、float
属性定义:
<attr name = "fromAlpha" format = "float" />
属性使用:
<alpha android:fromAlpha = "1.0"/>
6、integer
属性定义:
<attr name = "framesCount" format="integer" />
属性使用:
<animated-rotate android:framesCount = "12"/>
7、string
属性定义:
<attr name = "text" format = "string" />
属性使用:
<TextView android:text = "我是文本"/>
8、fraction
属性定义:
<attr name = "pivotX" format = "fraction" />
属性使用:
<rotate android:pivotX = "200%"/>
9、 enum:枚举值
属性定义:
<declare-styleable name="名称">
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</declare-styleable>
属性使用:
注意:当使用枚举属性的话不能在一个属性中同时使用两个值
10、 flag:位或运算
属性定义:
<declare-styleable name="名称">
<attr name="gravity">
<flag name="top" value="0x30" />
<flag name="bottom" value="0x50" />
<flag name="left" value="0x03" />
<flag name="right" value="0x05" />
<flag name="center_vertical" value="0x10" />
...
</attr>
</declare-styleable>
属性使用:
位运算符在使用的时候可以使用多个属性
11、混合类型:属性定义时可以指定多种类型值
属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
属性使用:
<ImageView android:background = "@drawable/图片ID" />
或者:
下面我们通过一个案例来加深理解。
首先在attrs文件中添加我们的自定义属性
<declare-styleable name="CircleSplashView">
<attr name="solid_circle_radius" format="dimension" />
<attr name="solid_circle_color" format="color" />
<attr name="empty_circle_color" format="color" />
<attr name="empty_circle_radius" format="dimension" />
<attr name="circle_text_size" format="dimension" />
<attr name="circle_text_color" format="color" />
<attr name="circle_draw_orientation" format="enum">
<enum name="clockwise" value="1" />
<enum name="anticlockwise" value="2" />
</attr>
<attr name="time_length" format="integer" />
</declare-styleable>
这样我们就可以在布局文件中添加我们的自定义属性,这里要注意一下要引入我们的自定义空间,一般来说有两种:xmlns:circletimerview="http://schemas.android.com/apk/res-auto”,res-auto表示自动查找,还有一种写法xmlns:circletimerview="http://schemas.android.com/apk/com.book.aikaifa.tallybook",其中com.book.aikaifa.tallybook 为我们自身应用程序的包名。
<com.book.aikaifa.tallybook.view.CircleSplashView
android:id="@+id/circle_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
circletimerview:circle_draw_orientation="clockwise"
circletimerview:circle_text_color="@android:color/white"
circletimerview:circle_text_size="16sp"
circletimerview:empty_circle_color="#3F51B5"
circletimerview:empty_circle_radius="22dp"
circletimerview:solid_circle_color="@color/colorPrimaryDark"
circletimerview:solid_circle_radius="20dp"
circletimerview:time_length="5" />
另外,我们可以在构造方法中获取我们的自定义属性
/**
* 自定义属性
*/
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleSplashView);
mSolidCircleColor = typedArray.getColor(R.styleable.CircleSplashView_solid_circle_color, defaultSolidCircleColor);
mSolidCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_solid_circle_radius, defaultSolidCircleRadius);
mEmptyCircleColor = typedArray.getColor(R.styleable.CircleSplashView_empty_circle_color, defaultEmptyCircleColor);
mEmptyCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_empty_circle_radius, defaultEmptyCircleRadius);
mTextColor = typedArray.getColor(R.styleable.CircleSplashView_circle_text_color, defaultTextColor);
mTextSize = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_circle_text_size, defaultTextSize);
mDrawOrientation = typedArray.getInt(R.styleable.CircleSplashView_circle_draw_orientation, defaultDrawOrietation);
mTimeLength = typedArray.getInt(R.styleable.CircleSplashView_time_length, defaultTimeLength);
typedArray.recycle();
这样,我们基本使用了我们自定义的属性,这里我们顺便对AttributeSet和TypeArray类简单阐述一下。
Attributeset看命名好像是一个属性的集合,实际上,它内部就是一个XML解析器,可以将布局文件中该控件的所有属性解析出来,并以key-value的形式存起来。其实我们完全可以只用他通过下面的代码来获取我们的属性就行。
for (int i = 0; i < attrs.getAttributeCount(); i++) {
Log.i(TAG, "name:" + attrs.getAttributeName(i) + " value: " + attrs.getAttributeValue(i));
}
输出结果:
可以看到使用Attributeset得到的属性的值是取到的xml文件中的值,而我们想要的textsize的大小,还得想方法将sp去掉才能拿到我们的16.0,或是dip去掉,这时typeArray就应运而生了,我们回头看看使用TypeArray后得到的数据
/**
* 自定义属性
*/
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleSplashView);
mSolidCircleColor = typedArray.getColor(R.styleable.CircleSplashView_solid_circle_color, defaultSolidCircleColor);
mSolidCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_solid_circle_radius, defaultSolidCircleRadius);
mEmptyCircleColor = typedArray.getColor(R.styleable.CircleSplashView_empty_circle_color, defaultEmptyCircleColor);
mEmptyCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_empty_circle_radius, defaultEmptyCircleRadius);
mTextColor = typedArray.getColor(R.styleable.CircleSplashView_circle_text_color, defaultTextColor);
mTextSize = typedArray.getDimensionPixelOffset(R.styleable.CircleSplashView_circle_text_size, defaultTextSize);
mDrawOrientation = typedArray.getInt(R.styleable.CircleSplashView_circle_draw_orientation, defaultDrawOrietation);
mTimeLength = typedArray.getInt(R.styleable.CircleSplashView_time_length, defaultTimeLength);
typedArray.recycle();
这些数据才是我们真正想要的数据。
好了,今天的分享就先到这。晚安!
【END】
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。