Android XML自定义属性始终返回默认值。

12 浏览
0 Comments

Android XML自定义属性始终返回默认值。

我需要实现类似于com.android.R.attr中的自定义属性。

官方文档中没有找到相关内容,因此我需要了解如何定义这些属性以及如何在我的代码中使用它们。

0
0 Comments

问题的原因是在实现自定义属性时,使用了错误的命名空间。解决方法是将命名空间更改为"http://schemas.android.com/apk/res-auto"。

最近才添加了这个解决方法,大约在几周前。我认为这个问题比那还要早,但肯定是在Qberticus回答之后很久才添加的。我并不责怪他,只是添加了一个有用的细节。

我已经更新了Qbericus的回答,使用了"xmlns:whatever="http://schemas.android.com/apk/res-auto"来避免混淆。

0
0 Comments

问题的原因是当自定义属性没有设置样式时,使用的是(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自定义属性总是返回默认值的问题的原因和解决方法的整理。

0
0 Comments

问题出现的原因:

- 所有属性共享相同的全局命名空间,即使在元素内创建新属性,它也可以在外部使用,并且不能创建具有不同类型的相同名称的另一个属性。

问题的解决方法:

- 在自定义视图的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)。

您可以在顶部元素或元素内定义属性。如果我要在多个地方使用属性,我会将其放在根元素中。请注意,所有属性共享相同的全局命名空间。这意味着,即使您在元素内创建新属性,它也可以在外部使用,并且您不能创建具有不同类型的相同名称的另一个属性。

元素有两个xml属性name和format。name属性让您给它命名,并且这是您在代码中引用它的方式,例如R.attr.my_attribute。format属性可以根据您想要的属性类型具有不同的值。

- 引用-如果它引用另一个资源id(例如,“/my_color”,“/my_layout”)

- color

- boolean

- dimension

- float

- integer

- string

- fraction

- enum-通常是隐式定义的

- flag-通常是隐式定义的

您可以使用|将格式设置为多种类型,例如format="reference|color"。

枚举属性可以定义如下:

标志属性类似,只是需要定义值以便可以将它们链接在一起:

除了属性之外,还有元素。这允许您定义自定义视图可以使用的属性。您可以通过指定元素来实现此目的,如果以前已定义,则不需要指定format。如果要重用android属性(例如android:gravity),则可以在name中执行此操作,如下所示。

自定义视图的示例

在自定义视图的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();

}

0