您的位置:首页 > 移动开发 > Android开发

Android自定义属性

2016-05-12 17:33 435 查看
custom attributes and styles

自定义属性

自定义一个CustomView(extends View)类

编写values/custom_attrs.xml,在其中编写styleable和item等标签元素

在布局文件中CustomView使用自定义的属性(注意namespace)

在CustomView的构造方法中通过TypedArray获取

custom_attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="custom_src" format="string" />
<attr name="custom_text" format="string" />
<attr name="custom_text_size" format="dimension" />
<attr name="custom_text_color" format="color" />
<attr name="custom_bg" format="reference|color" />
</declare-styleable>
</resources>


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.heqiang.testsomething"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">

<com.example.heqiang.testsomething.CustonView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#ffff0000"
custom:custom_src="Hello"
custom:custom_text="@string/hello_world"
custom:custom_bg="@mipmap/ic_launcher"
custom:custom_text_size="10sp"
/>

</LinearLayout>


MainActivity.java

public class CustonView extends View {
private static final String TAG = "CustonView";
public CustonView(Context context, AttributeSet attrs) {
super(context, attrs);

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView);

String src = ta.getString(R.styleable.CustomView_custom_src);
String text = ta.getString(R.styleable.CustomView_custom_text);
float textSize = ta.getDimension(R.styleable.CustomView_custom_text_size, 10);
Drawable drawable = ta.getDrawable(R.styleable.CustomView_custom_bg);

Log.e(TAG, "src = " + src + " , text = " + text + " , textSize = "+textSize);
Log.e(TAG, "drawable = " + drawable);

ta.recycle();
}
}


打印结果:

E/CustonView(30405): src = Hello , text = Hello world! , textSize = 30.0
E/CustonView(30405): drawable = android.graphics.drawable.BitmapDrawable@28a01041 , text = Hello world! , textSize = 30.0


format选项

boolean:布尔值

color:颜色值

dimension:尺寸值

enum:枚举值

flag:位或运算

float:浮点值

fraction:百分数

integer:整型值

reference:参考某一资源ID

string:字符串

flag与enum的差别:flag表示这几个值可以做或运算,你可以叠加使用,如用bold|italic表示既加粗也变成斜体,而enum只能让你选择其中一个值。

format即使用错,只要你自定义的View中获取对应类型值也是可以的,只是在布局中写代码时,IDE就不会根据你定义的format给出相应的提示了,所以最好在自定义View时还是仔细斟酌下类型。

AttributeSet与TypedArray

AttributeSet中保存的是该View声明的所有的属性,并且外面的确可以通过它去获取(自定义的)属性。但它和通过TypedArray获取到的有什么区别呢?

看下面代码:

public class CustonView extends View {
private static final String TAG = "CustonView";
public CustonView(Context context, AttributeSet attrs) {
super(context, attrs);

int count = attrs.getAttributeCount();
for (int i = 0; i < count; i++) {
String attrName = attrs.getAttributeName(i);
String attrVal = attrs.getAttributeValue(i);
Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);
}
}
}


结果:

E/CustonView(30405): attrName = background , attrVal = #ffff0000
E/CustonView(30405): attrName = layout_width , attrVal = 50.0dip
E/CustonView(30405): attrName = layout_height , attrVal = 50.0dip
E/CustonView(30405): attrName = custom_src , attrVal = Hello
E/CustonView(30405): attrName = custom_text , attrVal = @2131165186
E/CustonView(30405): attrName = custom_text_size , attrVal = 10.0sp
E/CustonView(30405): attrName = custom_bg , attrVal = @2130903040


看到这些打印相信大家就明白了,如果某个属性我们用的是引用,那么通过AttributeSet获取的值只是这个资源的ID,而TypedArray获得的是解析过的ID的值。因此使用TypedArray是比较方便的。

在自定义Style中加入自定义attr

values/custom_attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="custom_src" format="string" />
<attr name="custom_text" format="string" />
<attr name="custom_text_size" format="dimension" />
<attr name="custom_text_color" format="color" />
<attr name="custom_bg" format="reference|color" />
</declare-styleable>

<declare-styleable name="CustomTheme">
<attr name="customTheme" format="reference" />
</declare-styleable>
</resources>


values/styles.xml

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>

<style name="CustomTheme">
<item name="android:background">#ffff0000</item>
<item name="custom_src">Hello</item>
<item name="custom_text">@string/hello_world</item>
<item name="custom_bg">@mipmap/ic_launcher</item>
<item name="custom_text_size">10sp</item>
<item name="custom_text_color">#ffffff00</item>
</style>

</resources>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.heqiang.testsomething"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">

<com.example.heqiang.testsomething.CustonView
android:layout_width="50dp"
android:layout_height="50dp"
custom:customTheme="@style/CustomTheme"
/>

</LinearLayout>


public class CustonView extends View {
private static final String TAG = "CustonView";
public CustonView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, R.attr.customTheme);
}

public CustonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//init(context, attrs, defStyleAttr);
}

private void init(Context context, AttributeSet attrs, int defStyle) {

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CustomTheme, defStyle, 0);
int customTheme = ta.getResourceId(R.styleable.CustomTheme_customTheme, 0);
ta.recycle();
Log.e(TAG, "customTheme=" + customTheme);

//获取自定义的5个属性
TypedArray a = context.getTheme().obtainStyledAttributes(customTheme, R.styleable.CustomView);

String src = null;
String text = null;
float textSize = 0f;
Drawable drawable = null;
int textColor = 0;

int N = a.getIndexCount();
Log.e(TAG, "N="+N);
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
if(attr == R.styleable.CustomView_custom_src){
src = a.getString(R.styleable.CustomView_custom_src);
} else if(attr == R.styleable.CustomView_custom_text){
text = a.getString(R.styleable.CustomView_custom_text);
} else if(attr == R.styleable.CustomView_custom_text_size){
textSize = a.getDimension(R.styleable.CustomView_custom_text_size, 10);
} else if(attr == R.styleable.CustomView_custom_bg){
drawable = a.getDrawable(R.styleable.CustomView_custom_bg);
} else if(attr == R.styleable.CustomView_custom_text_color){
textColor = a.getColor(R.styleable.CustomView_custom_text_color,0xffffffff);
}
}

Log.e(TAG, "src = " + src + " , text = " + text + " , textSize = "+textSize);
Log.e(TAG, "drawable = " + drawable+", textColor = "+textColor);
a.recycle();

//获取<item name="android:background">#ffff0000</item>
TypedArray a1 = context.getTheme().obtainStyledAttributes(customTheme, styleable.View);
int N1 = a.getIndexCount();
for (int i = 0; i < N1; i++) {
int attr = a.getIndex(i);
if(attr == styleable.View_background){
Log.e(TAG,"View_background attr "+attr);
Drawable backgroundDr = a.getDrawable(attr);
setBackground(backgroundDr);
}
}
a1.recycle();
}

public static class styleable {
private static final Class<?> sClassStyleable = getStyleableClass();
public static int[] View;
public static int View_background;
static {
try {
View = (int[]) sClassStyleable.getField("View").get(null);

} catch (Exception e) {
Log.w(TAG, "", e);
}

try {
View_background = sClassStyleable.getField("View_background").getInt(null);
} catch (Exception e) {
Log.w(TAG, "", e);
}
}

private static Class<?> getStyleableClass() {
try {
Class<?> clz = Class.forName("com.android.internal.R$styleable");
return clz;
} catch (Exception e) {
Log.e(TAG, "", e);
}
return null;
}
}
}


打印结果:

E/CustonView(19597): customTheme=2131034113
E/CustonView(19597): N=5
E/CustonView(19597): src = Hello , text = Hello world! , textSize = 30.0
E/CustonView(19597): drawable = android.graphics.drawable.BitmapDrawable@22bfaf1b, textColor = -256
E/CustonView(19597): View_background attr 13


UI展现的结果是和上面的一样的。

相关介绍

http://www.jianshu.com/p/dd79220b47dd
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: