I declared an android custom view
that has an enum in it
<attr name="ff_type" format="enum">
<enum name="small" value="1" />
<enum name="big" value="32" />
<enum name="medium" value="8288" />
</attr>
how to allow in my xml of the custom view to do app:ff_type="small|medium" ?
Use flag rather than enum:
<attr name="ff_type" format="flag">
<flag name="small" value="1" />
<flag name="big" value="32" />
<flag name="medium" value="8288" />
</attr>
Inclusion of format="flag" is optional.
8288 is an odd choice, you're better sticking to powers of 2. As it stands 8288 = 32 * 259. Therefore you can't select medium without implying big.
<attr name="ff_type">
<flag name="small" value="1" />
<flag name="medium" value="2" />
<flag name="big" value="4" />
</attr>
Then you can optionally add additional values as shortcuts:
<attr name="ff_type">
<flag name="small" value="1" />
<flag name="medium" value="2" />
<flag name="big" value="4" />
<flag name="smallerThanBig" value="3" />
</attr>
So here smallerThanBig is the same as small|medium (but you can use both).
<flag/>can be multiple,like gravity="center | left"
but <enum/> must be single,like layout_height="wrap_content"
Related
I tried to upgrade my Android projects targetSdkVersion from 30 to 31
Therefore i upgraded Android gradle plugin 'com.android.tools.build:gradle:3.6.4' to
'com.android.tools.build:gradle:4.2.1'
gradle version is 6.7.1
i got
.../app/src/main/res/values/attrs.xml:11:4: Invalid value 'null' for . Must be an integer. (--scan option)
error message start Exception is: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDemoDebugResources'.
here is my attrs.xml file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="GlobalStyleable">
<attr name="title" format="string" />
<attr name="text" format="string" />
<attr name="description" format="string" />
<attr name="enabled" format="boolean" />
<attr name="actionText" format="string" />
<attr name="endIcon" format="reference" />
</declare-styleable>
<declare-styleable name="SimpleEditText">
<attr name="android:enabled" />
<attr name="title" />
<attr name="text" />
<attr name="description" />
<attr name="error" format="string" />
<attr name="endIconMode" />
<attr name="endIconDrawable" />
<attr name="inputType" format="enum">
<enum name="text" value="0x00000001" />
<enum name="password" value="0x00000081" />
<enum name="passwordWithoutKeyboard" value="0x00000081" />
<enum name="number" value="0x00000002" />
</attr>
<attr name="contextMenu" format="enum">
<enum name="full" value="0" />
<enum name="onlyCopy" value="1" />
<enum name="onlyPaste" value="2" />
<enum name="none" value="3" />
</attr>
<attr name="mask" format="enum">
<enum name="phone" value="0" />
<enum name="card" value="1" />
<enum name="bin" value="2" />
<enum name="account" value="3" />
<enum name="symbol2" value="4" />
<enum name="symbol3" value="5 " />
<enum name="smsCode" value="6" />
<enum name="password" value="7" />
</attr>
</declare-styleable>
<declare-styleable name="SimpleEditTextWithStartDrawable">
<attr name="android:enabled" />
<attr name="title" />
<attr name="text" />
<attr name="description" />
<attr name="error" />
<attr name="endIconMode" />
<attr name="endIconDrawable" />
<attr name="inputType" />
<attr name="contextMenu" />
<attr name="mask" />
</declare-styleable>
<declare-styleable name="ProgressButton">
<attr name="android:text" />
<attr name="loading" format="boolean" />
</declare-styleable>
</resources>
please help
I want to use custom components in my project and i want to add it to enum attributes like below , how can i do that ?
<com.abb.abbcustomcompanents.buttons.AbbButton
android:id="#+id/abbBtn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:Type="How can i use enum here"
/>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="abbButton">
<attr name="Type" format="enum"/>
<attr name="onAction" format="string"/>
</declare-styleable>
</resources>
Thank you !
Ex :
<attr name="myProperty" format="enum">
<enum name="None" value="0"/>
<enum name="One" value="1"/>
<enum name="Two" value="2"/>
<enum name="Three" value="3"/>
</attr>
Use like this:
<YourCustomView
...
app:myProperty="One"/>
Reference
https://stackoverflow.com/a/15231645/1329126
Order inside the XML matters, at least to eclipse. Define your enum above (or inside) your declare-styleable... not below.
<attr name="quality">
<enum name="Good" value="1" />
<enum name="Better" value="2" />
<enum name="Best" value="3" />
</attr>
<declare-styleable name="SquareView">
<attr name="quality" />
</declare-styleable>
<declare-styleable name="CircleView">
<attr name="quality" />
</declare-styleable>
I had a very long enum so I placed it at the end of my XML to improve readability. It would parse correctly but reject values in Design mode.
Suppose I am making some new views with styleable attributes. I declare them thusly (this is how the documentation says to do it:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TriangleView">
<attr name="direction">
<enum name="NE" value="0" />
<enum name="NW" value="1" />
<enum name="SW" value="2" />
<enum name="SE" value="3" />
</attr>
</declare-styleable>
<declare-styleable name="BannerView">
<attr name="direction">
<enum name="NE" value="0" />
<enum name="NW" value="1" />
<enum name="SW" value="2" />
<enum name="SE" value="3" />
</attr>
<attr name="thickness" format="dimension" />
</declare-styleable>
</resources>
However, this won't work because all attributes are apparently in the same namespace, and I get the error Error: Attribute "direction" has already been defined.
So apparently I have to move the apparently duplicated attributes outside the <declare-styleable> like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="direction">
<enum name="NE" value="0" />
<enum name="NW" value="1" />
<enum name="SW" value="2" />
<enum name="SE" value="3" />
</attr>
<declare-styleable name="BannerView">
<attr name="thickness" format="dimension" />
</declare-styleable>
</resources>
But this poses two questions:
If this works, what exactly is the point of <declare-styleable>?
What if I want the attribute to behave differently in different views? For example if BannerView's direction can only be up or down.
What exactly is the point of <declare-styleable>?
<declare-stylable> tags let you declare attributes for your custom views that you can then set for those views in xml. There are really 3 parts to using the attribute:
Declare an <attr> inside of a <declare-stylable> tag.
Define a custom namespace in your xml layout pointing to your app package name (ex. app). Use the custom attribute in your layout (ex. app:direction="NW").
In your custom view, override the constructors with an AttributeSet parameter, get a TypedArray and read the custom attributes, if any, from it and then within the constructor tell the view how to use those attributes appropriately.
What if I want the attribute to behave differently in different views?
For example if BannerView's direction can only be up or down.
Try something like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="direction">
<enum name="NE" value="0" />
<enum name="NW" value="1" />
<enum name="SW" value="2" />
<enum name="SE" value="3" />
</attr>
<declare-styleable name="TriangleView">
<attr name="direction" />
</declare-styleable>
<declare-styleable name="BannerView">
<attr name="direction" />
<attr name="thickness" format="dimension" />
</declare-styleable>
</resources>
When you build your xml layout for TriangleView or BannerView, you can use the app:direction="NW" example for both. In the constructors with AttributeSet in TriangleView or BannerView, the attributes will have the same format as the original, but what you do with that value is dependent on your implementation of the constructors in each respective view (can be the same or different for both).
If you want attributes to be defined differenly (ie. different "format" or "enum") for different views, then you have to create different attributes with different names.
I have defined a custom attribute in xml that must take an enum value as a parameter. The JavaDoc that is automatically produced from my application's R.attr builds a table with enum name and value, but filling in the description column eludes me. How do I define a description that will appear in the JavaDoc?
An example attribute with enum constants:
<declare-styleable name="MyCustomView">
<attr name="directions">
<enum name="up" value="0" />
<enum name="down" value="1" />
<enum name="left" value="2" />
<enum name="right" value="3" />
</attr>
</declare-styleable>
To show what I mean, the JavaDoc for directionPriority in android.R.attr has a table for all the possible enums with "constant," "value" and "description" all filled in.
I have done a good deal of research and tried trial-and-error guesses at a tag that might allow me to include a description, but to no avail. Does anyone know the proper way to document this?
The solution is to add comments before each of the enums. These comments are automatically translated into the enum description column.
<declare-styleable name="MyCustomView">
<attr name="directions">
<!-- Go up! -->
<enum name="up" value="0" />
<!-- Go down! -->
<enum name="down" value="1" />
<!-- Go left! -->
<enum name="left" value="2" />
<!-- Go right! -->
<enum name="right" value="3" />
</attr>
</declare-styleable>
I have the following situation:
in styles.xml:
<style name="fooStyle">
<item name="android:padding">?fooView.padding</item>
<item name="android:background">?fooView.background</item>
<item name="android:gravity">?fooView.gravity</item>
</style>
in attrs.xml:
<attr name="fooView.padding" format="dimension" />
<attr name="fooView.background" format="color|reference" />
<attr name="fooView.gravity" format="????"/>
in themes.xml:
<style name="fooViewTheme" parent="android:Theme">
<item name="fooView.padding" >2dip</item>
<item name="fooView.background" >#AA000000</item>
<item name="fooView.gravity">right|bottom</item>
</style>
The problem is that I cannot figure out what the format for the fooView.gravity should be. I've already tried with string, enum and flag but none seem to work: I always get a java.lang.NumberFormatException: unable to parse 'right|bottom' as integer as soon as the view that uses this theme gets loaded.
All answers are appreciated.
Those are the gravity values used by Android. You can use that in your attrs.xml:
<resources>
<declare-styleable name="MyCustomView">
<attr name="gravity">
<flag name="bottom" value="80" />
<flag name="center" value="17" />
<flag name="center_horizontal" value="1" />
<flag name="center_vertical" value="16" />
<flag name="clip_horizontal" value="8" />
<flag name="clip_vertical" value="128" />
<flag name="end" value="8388613" />
<flag name="fill" value="119" />
<flag name="fill_horizontal" value="7" />
<flag name="fill_vertical" value="112" />
<flag name="left" value="3" />
<flag name="right" value="5" />
<flag name="start" value="8388611" />
<flag name="top" value="48" />
</attr>
</declare-styleable>
</resources>
In your layout XML you can use it this way:
<MyCustomView
custom:gravity="center|bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
And in Java code you can read the value using this:
int gravity = a.getInt(R.styleable.MyCustomView_gravity, Gravity.NO_GRAVITY);
and directly set it to a sub view, if that makes sense for you:
someSubView.setGravity(gravity);
You can look up those gravity values in the source of android.view.Gravity or here
It's a flag attribute. You need to define it in your attributes xml like this:
<attr name="gravity">
<flag name="right" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<!-- etc. -->
</attr>
...and then access the values using bit masks, like this:
boolean right = (array.getInt(R.styleable.fooView_gravity, 0) & 0x01) == 0x01;
boolean bottom = (array.getInt(R.styleable.fooView_gravity, 0) & 0x02) == 0x02;
boolean left = (array.getInt(R.styleable.fooView_gravity, 0) & 0x04) == 0x04;
// etc.
...and of course, these values can be used from XML as well:
<style name="fooViewTheme" parent="android:Theme">
<item name="fooView.gravity">right|bottom</item>
</style>
As you only need a small selection of attributes, I'd suggest using the type "enum".
http://developer.android.com/training/custom-views/create-view.html
<attr name="labelPosition" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="1"/>
</attr>
Referencing:
custom:labelPosition="left"
In Code:
mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
Seems to be integer? Doc.
Would make sense since it can be 'ored'
Edit: sorry, probably misread the problem... It's clearly saying in the error that it's int, but bottom can't be converted to int :/
Edit2: Here are the int values if you need to work-around. Sorry for no real solution.