Android XML自定义属性始终返回默认值。
问题的原因是当自定义属性没有设置样式时,使用的是(Context context, AttributeSet attrs)
方法来实例化Preference。在这种情况下,可以使用context.obtainStyledAttributes(attrs, R.styleable.MyCustomView)
来获取TypedArray。
解决方法是在SeekBarPreference中添加一个属性pluralResource,用于处理复数资源(数量字符串)。如果xml中的android:summary设置为文本字符串或字符串资源,就将preference的值格式化为该字符串(字符串中应包含%d来获取值)。如果android:summary设置为复数资源,则使用该资源来格式化结果。
此外,如果想要在preference screen上设置summary,需要在preference的onDialogClosed方法中调用notifyChanged()
。
完整的代码如下:
// Use your own name space if not using an android resource. final static private String ANDROID_NS = "http://schemas.android.com/apk/res/android"; private int pluralResource; private Resources resources; private String summary; public SeekBarPreference(Context context, AttributeSet attrs) { // ... TypedArray attributes = context.obtainStyledAttributes( attrs, R.styleable.SeekBarPreference); pluralResource = attrs.getAttributeResourceValue(ANDROID_NS, "summary", 0); if (pluralResource != 0) { if (! resources.getResourceTypeName(pluralResource).equals("plurals")) { pluralResource = 0; } } if (pluralResource == 0) { summary = attributes.getString( R.styleable.SeekBarPreference_android_summary); } attributes.recycle(); } public CharSequence getSummary() { int value = getPersistedInt(defaultValue); if (pluralResource != 0) { return resources.getQuantityString(pluralResource, value, value); } return (summary == null) ? null : String.format(summary, value); } public void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); if (positiveResult) { // Handle the positive dialog result } else { // Handle the negative dialog result } notifyChanged(); }
以上是关于Android XML自定义属性总是返回默认值的问题的原因和解决方法的整理。
问题出现的原因:
- 所有属性共享相同的全局命名空间,即使在
问题的解决方法:
- 在自定义视图的XML中定义自定义属性时,需要在根布局元素上声明一个命名空间来查找属性。
- 在根布局元素上添加xmlns:whatever="http://schemas.android.com/apk/res-auto"命名空间。
- 在自定义视图的构造函数中,使用context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0)获取TypedArray,并使用a.getString(R.styleable.MyCustomView_my_custom_attribute)来访问自定义属性。
文章整理如下:
当前最好的文档是源代码。您可以在此处查看它(attrs.xml)。
您可以在顶部
- 引用-如果它引用另一个资源id(例如,“/my_color”,“/my_layout”)
- color
- boolean
- dimension
- float
- integer
- string
- fraction
- enum-通常是隐式定义的
- flag-通常是隐式定义的
您可以使用|将格式设置为多种类型,例如format="reference|color"。
枚举属性可以定义如下:
标志属性类似,只是需要定义值以便可以将它们链接在一起:
除了属性之外,还有
自定义视图的示例
在自定义视图的XML中定义自定义属性时,需要执行以下步骤。首先,必须声明一个命名空间来查找属性。在根布局元素上执行此操作。通常只有xmlns:android="http://schemas.android.com/apk/res/android"。现在,还必须添加xmlns:whatever="http://schemas.android.com/apk/res-auto"。
示例:
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:whatever="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" whatever:my_custom_attribute="Hello, world!" />
最后,要访问该自定义属性,通常在自定义视图的构造函数中执行以下操作。
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
String str = a.getString(R.styleable.MyCustomView_my_custom_attribute);
//do something with str
a.recycle();
}