Android自定义属性
2016-05-12 17:33
435 查看
custom attributes and styles
编写values/custom_attrs.xml,在其中编写styleable和item等标签元素
在布局文件中CustomView使用自定义的属性(注意namespace)
在CustomView的构造方法中通过TypedArray获取
custom_attrs.xml
activity_main.xml
MainActivity.java
打印结果:
color:颜色值
dimension:尺寸值
enum:枚举值
flag:位或运算
float:浮点值
fraction:百分数
integer:整型值
reference:参考某一资源ID
string:字符串
flag与enum的差别:flag表示这几个值可以做或运算,你可以叠加使用,如用bold|italic表示既加粗也变成斜体,而enum只能让你选择其中一个值。
format即使用错,只要你自定义的View中获取对应类型值也是可以的,只是在布局中写代码时,IDE就不会根据你定义的format给出相应的提示了,所以最好在自定义View时还是仔细斟酌下类型。
看下面代码:
结果:
看到这些打印相信大家就明白了,如果某个属性我们用的是引用,那么通过AttributeSet获取的值只是这个资源的ID,而TypedArray获得的是解析过的ID的值。因此使用TypedArray是比较方便的。
values/styles.xml
打印结果:
UI展现的结果是和上面的一样的。
自定义属性
自定义一个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相关文章推荐
- Android入门开发之Intent
- Android Studio环境下EditText的BUG
- Android 一个小例子理解实际开发中坐标计算的过程
- Android学习--《数据的保存》
- android动画入门
- 怎么去除android listview的默认点击效果
- 用Android访问本地站点---(localhost,10.0.2.2)要区别
- android 存取数据。
- 安卓系统权限申请列表
- android 常用util方法
- 条形码、二维码扫一扫和生成二维码采用ZXing3.0开源库在android studio中实现
- Android双击back键退出程序
- Android的Button按钮,ACTION_UP事件不触发解决方案
- android Looper源码分析
- Android之Service与IntentService的比较
- Android DrawerLayout 高仿QQ5.2双向侧滑菜单
- android studio
- Activity设置android:windowIsTranslucent属性之后,点击按钮跳转到其他的Activity
- 控制父控件不可拦截子控件事件
- (android:windowIsTranslucent)影响(android:windowAnimationStyle)Activity切换动画无效