在上一篇文章我已经说过如何制作一个最简单的自定义组件
这一篇,接着上一篇,再深一些些,比如,如何给你的自定义组件添加一些自定义属性,
自定义属性
举个例子,我们在xml创建一个imageview的时候,我们可以在xml里面填入图片资源id,如下图:
<ImageView
android:id="@+id/testsimple"
android:src="@drawable/timg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后imageview就会根据这个src提供的图片id将这张图片timg给显示出来,
而在上一节我们已经知道,自定义组件其实就是在构造函数之后,调用onDraw函数绘画组件出来而已,
那么,为什么imageview里的src到底是怎么传给imageview这个组件的?
这就是自定义属性了
自定义属性的创建其实非常简单,一共可以分为三个步骤,
第一个步骤:在你工程的res文件下的values文件下新建一个属性文件——attrs.xml,如下图
第二个步骤:在xml文件中编写你要获取的自定义属性,如下面,我定义了两个,一个是获取图片资源id,一个是获取一个整数类型的inSampleSize参数
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="circleImageView">
<attr name="imageSrc" format="reference"/>
<attr name="inSampleSize" format="integer"/>
</declare-styleable>
</resources>
在这里说一下,根据你要获取的资源类型不同,你的format的值也应该不同,大概有下面这么多种类型:
1. reference:参考某一资源ID。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference" />
</declare-styleable>
(2)属性使用:
<ImageView
android:layout_width = "42dip"
android:layout_height = "42dip"
android:background = "@drawable/图片ID"
/>
2. color:颜色值。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "textColor" format = "color" />
</declare-styleable>
(2)属性使用:
<TextView
android:layout_width = "42dip"
android:layout_height = "42dip"
android:textColor = "#00FF00"
/>
3. boolean:布尔值。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "focusable" format = "boolean" />
</declare-styleable>
(2)属性使用:
<Button
android:layout_width = "42dip"
android:layout_height = "42dip"
android:focusable = "true"
/>
4. dimension:尺寸值。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "layout_width" format = "dimension" />
</declare-styleable>
(2)属性使用:
<Button
android:layout_width = "42dip"
android:layout_height = "42dip"
/>
5. float:浮点值。
(1)属性定义:
<declare-styleable name = "AlphaAnimation">
<attr name = "fromAlpha" format = "float" />
<attr name = "toAlpha" format = "float" />
</declare-styleable>
(2)属性使用:
<alpha
android:fromAlpha = "1.0"
android:toAlpha = "0.7"
/>
6. integer:整型值。
(1)属性定义:
<declare-styleable name = "AnimatedRotateDrawable">
<attr name = "visible" />
<attr name = "frameDuration" format="integer" />
<attr name = "framesCount" format="integer" />
<attr name = "pivotX" />
<attr name = "pivotY" />
<attr name = "drawable" />
</declare-styleable>
(2)属性使用:
<animated-rotate
xmlns:android = "http://schemas.android.com/apk/res/android"
android:drawable = "@drawable/图片ID"
android:pivotX = "50%"
android:pivotY = "50%"
android:framesCount = "12"
android:frameDuration = "100"
/>
7. string:字符串。
(1)属性定义:
<declare-styleable name = "MapView">
<attr name = "apiKey" format = "string" />
</declare-styleable>
(2)属性使用:
<com.google.android.maps.MapView
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"
/>
8. fraction:百分数。
(1)属性定义:
<declare-styleable name="RotateDrawable">
<attr name = "visible" />
<attr name = "fromDegrees" format = "float" />
<attr name = "toDegrees" format = "float" />
<attr name = "pivotX" format = "fraction" />
<attr name = "pivotY" format = "fraction" />
<attr name = "drawable" />
</declare-styleable>
(2)属性使用:
<rotate
xmlns:android = "http://schemas.android.com/apk/res/android"
android:interpolator = "@anim/动画ID"
android:fromDegrees = "0"
android:toDegrees = "360"
android:pivotX = "200%"
android:pivotY = "300%"
android:duration = "5000"
android:repeatMode = "restart"
android:repeatCount = "infinite"
/>
9. enum:枚举值。
(1)属性定义:
<declare-styleable name="名称">
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</declare-styleable>
(2)属性使用:
<LinearLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
>
</LinearLayout>
10. flag:位或运算。
(1)属性定义:
<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>
(2)属性使用:
<activity
android:name = ".StyleAndThemeActivity"
android:label = "@string/app_name"
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
注意:
属性定义时可以指定多种类型值。
(1)属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
(2)属性使用:
<ImageView
android:layout_width = "42dip"
android:layout_height = "42dip"
android:background = "@drawable/图片ID|#00FF00"
/>
第三个步骤:在你的自定义组件中获取你从xml里得到的这些参数!获取方法如同下图:
(在前面我说过我在上面定义了两个参数):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="circleImageView">
<attr name="imageSrc" format="reference"/>
<attr name="inSampleSize" format="integer"/>
</declare-styleable>
</resources>
所以这两个参数的获取方法如下图,在自定义组件的构造方法中,调用obtainStyledAttributes方法,如下:
public circleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.circleImageView, 0, 0);
System.out.println("imageResourceId="+imageResourceId);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.circleImageView_imageSrc:
imageResourceId=a.getResourceId(attr,R.drawable.moren);
break;
case R.styleable.circleImageView_inSampleSize:
mInSampleSize=a.getInteger(attr,1);
break;
}
}
a.recycle();
}
在这里说一下,obtainStyledAttributes方法需要四个参数,这四个参数意义如下:
1. 第一个参数是xml文件中的定义的属性集(理解为键值对),
2. 第二个参数是你要获取的目标属性,如我上面自定义那个属性name为circleImageView,所以这里填入R.styleable.circleImageView。
3. 第三个是系统当前theme下默认的属性集(理解为建值对),这里的默认的Style是指它在当前Application或Activity所用的Theme中的默认Style
4. 第四个是备用的一个style(理解为键值对)。
假如想要多了解这个函数,可以参考一下这篇文章:https://www.cnblogs.com/angeldevil/p/3479431.html
好啦,这样你就可以自定义了你自己的自定义组件属性啦