Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

xml - Declaring styleable attributes in Android

There's precious little documentation about the declare-styleable tag by which we can declare custom styles for components. I did find this list of valid values for the format attribute of the attr tag. While that's nice as far as it goes, it doesn't explain how to use some of those values. Browsing attr.xml (the Android source for the standard attributes), I discovered that you can do things like:

<!-- The most prominent text color.  -->
<attr name="textColorPrimary" format="reference|color" />

The format attribute can evidently be set to a combination of values. Presumably the format attribute helps the parser interpret an actual style value. Then I discovered this in attr.xml:

<!-- Default text typeface. -->
<attr name="typeface">
    <enum name="normal" value="0" />
    <enum name="sans" value="1" />
    <enum name="serif" value="2" />
    <enum name="monospace" value="3" />
</attr>

<!-- Default text typeface style. -->
<attr name="textStyle">
    <flag name="normal" value="0" />
    <flag name="bold" value="1" />
    <flag name="italic" value="2" />
</attr>

Both of these seem to declare a set of allowed values for the indicated style.

So I have two questions:

  1. What's the difference between a style attribute that can take on one of a set of enum values and one that can take on a set of flag values?
  2. Does anyone know of any better documentation for how declare-styleable works (other than reverse engineering the Android source code)?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's this question here: Defining custom attrs with some info, but not much.

And this post . It has good info about flags and enums:

Custom XML Attribute Flags

Flags are special attribute types in that they are allowed only a very small subset of values, namely those that are defined underneath the attribute tag. Flags are specified by a “name” attribute and a “value” attribute. The names are required to be unique within that attribute type but the values need not be. This is the reason that during the evolution of the Android platform we had “fill_parent” and “match_parent” both mapping to the same behavior. Their values were identical.

The name attribute maps to the name used in the value place within the layout XML and does not require a namespace prefix. Hence, for the “tilingMode” above I chose “center” as the attribute value. I could have just as easily chosen “stretched” or “repeating” but nothing else. Not even substituting in the actual values would have been allowed.

The value attribute must be an integer. The choice of hexadecimal or standard numeral representation is up to you. There’s a few places within the Android code where both are used and the Android compiler is happy to accept either.

Custom XML Attribute Enums

Enums are used in an almost identical manner as flags with one provision, they may be used interchangeably with integers. Under the hood Enums and Integers are mapped to the same data type, namely, an Integer. When appearing in the attribute definition with Integers, Enums serve to prevent “magic numbers” which are always bad. This is why you can have an “android:layout_width” with either a dimension, integer, or named string “fill_parent.”

To put this into context, let’s suppose that I create a custom attribute called “layout_scroll_height” which accepts either an integer or a string “scroll_to_top.” To do so I’d add an “integer” format attribute and follow that with the enum:

<attr name="layout_scroll_height" format="integer">  
    <enum name="scroll_to_top" value="-1"/> 
</attr>

The one stipulation when using Enums in this manner is that a developer using your custom View could purposefully place the value “-1″ into the layout parameters. This would trigger the special case logic of “scroll_to_top.” Such unexpected (or expected) behavior could quickly relegate your library to the “legacy code” pile if the Enum values were chosen poorly.


As I see it, the real values you can add in reality to an attribute is limited by what you can obtain from it. Check the AttributeSet class reference here for more hints.

You can obtain:

  • booleans (getAttributeBooleanValue),
  • floats (getAttributeFloatValue),
  • ints (getAttributeIntValue),
  • ints (as getAttributeUnsignedIntValue),
  • and strings (getAttributeValue)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...