I am trying to write a custom behavior but android studio flags the custom attributes as missing i.e
attrs.xml
<declare-styleable name="VerticalDisplacement_Params">
<attr name="custom_Attr" format="boolean" />
</declare-styleable>
layout.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
app:layout_behavior=".Behavior"
app:custom_Attr="true">
custom_Attr is flagged as an invalid prefix
I plugged your custom element into a custom view I had made and it worked fine. Some things I would suggest:
Check that your <declare-stylable> is wrapped in a <resources> tag:
<resources>
<declare-styleable name="VerticalDisplacement_Params">
<attr name="custom_Attr" format="boolean" />
</declare-styleable>
<resources>
That the app namespace is defined as xmlns:app="http://schemas.android.com/apk/res-auto"
The declare-styleable needs to have the name of the component. If you're adding a new attribute to ContraintLayout - you'll have to extend the ContraintLayout class, but this did work for me:
<declare-styleable name="ConstraintLayout">
<attr name="custom_Attr" format="boolean" />
</declare-styleable>
Your attrs.xml exists inside the values folder
I have added some attributes into file attr.xml. Here its code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="gallery_view">
<attr name="android:galleryItemBackground"/>
</declare-styleable>
<declare-styleable name="Dot">
<attr name="color" format="color"/>
<attr name="radius" format="dimension"/>
</declare-styleable>
</resources>
But I don't why when I use:
R.styleable.gallery_view_android_galleryItemBackground: no error.
R.styleable.Dot_color will notice error because cannot see this field in R file.
Please help me about this.
Thanks :)
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Dot);
a.getColor....
I created many custom Views and any of views has a custom attribute: mystyle.
so that in my attr.xml:
<resources>
<declare-styleable name="MyView1">
<attr name="mystyle" format="string" />
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="mystyle" format="string" />
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="mystyle" format="string" />
</declare-styleable>
...
</resources>
I think that's not grace. Is there any way to use one attr for all the custome view?
You can try to make abstract ParentView and declare attribute for it. Then all your custom views will extend ParentView, and attribute will be declared
I'm trying to create a custom attribute called Tag for all editable elements. I added the following to attrs.xml
<declare-styleable name="Spinner">
<attr name="tag" format="string" />
</declare-styleable>
<declare-styleable name="EditText">
<attr name="tag" format="string" />
</declare-styleable>
I get an error saying "Attribute tag has already been defined" for the EditText. Is it not possible to create a custom attribute of the same name on different elements?
If you are going to use an attr in more than one place then put it in the root element inside the <resources> element like the following :
<resources>
<attr name="tag" format="string" />
<declare-styleable name="Spinner">
<attr name="tag" />
</declare-styleable>
<declare-styleable name="EditText">
<attr name="tag" />
</declare-styleable>
</resources>
Now you can use the tag attribute in anywhere you want inside this xml file.
See if my detailed answer about custom attributes helps: Defining custom attrs
I'm writing a few custom views which share some same-named attributes. In their respective <declare-styleable> section in attrs.xml I'd like to use the same names for attributes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView1">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
</resources>
I'm getting an error saying that myattr1 and myattr2 are already defined. I found that I should omit the format attribute for myattr1 and myattr2 in MyView2, but if I do that, I obtain the following error in the console:
[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute
Is there a way I could accomplish this, maybe some sort of namespacing (just guessing)?
Solution: Simply extract common attributes from both views and add them directly as children of the <resources> node:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<declare-styleable name="MyView1">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
</resources>
I am posting this answer as the above-posted solution didn't work out for me in Android Studio. I need to share my custom attributes among my custom views so I tried the above solution in Android Studio but had no luck. So I experiment and go a way to do it. Hope it might help someone looking for the same problem.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- parent styleable -->
<declare-styleable name="MyView">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
</resources>
This works for me completely.
We need to make a Parent styleable and then we need to inherit that parent styleable. For example, as I have done above :
Parent styleable name MyView and inherited this to my other styleable like MyView1 and MyView2 respectively.
As Priya Singhal answered, Android Studio requires the common attribute names to be defined within their own style name. They can't be at the root any more.
However, there are a couple other things to note (which is why I am also adding an answer):
The common styles don't need to be named the same thing as a view. (Thanks to this answer for pointing that out.)
You don't need to use inheritance with a parent.
Example
Here is what I did in a recent project that has two custom views that both share the same attributes. As long as the custom views still have the names for the attributes and don't include a format, I can still access them as normal from code.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes to all custom text based views -->
<declare-styleable name="TextAttributes">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<!-- custom text views -->
<declare-styleable name="View1">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
Streamlined example
In fact, I don't even need to put the attributes under a custom name. As long as I define them (give them a format) for at least one custom view, I can use them anywhere (without the format). So this also works (and looks cleaner):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="View1">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
For a large project, though, this could get messy and defining them at the top in a single location might be better (as recommended here).
Thanks Lewis
I had the same problem , and your inheritance solution gave me the hint for doing it like below and it works fine.I just declared common attributes at the above and rewrite it in the body of style declaration again without formatting.
I hope it helps someone
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
Just in case someone still stuck with this problem after tried available solution. I stuck with add subtitle attribute with string format.
My solution is remove the format.
before:
<attr name="subtitle" format="string"/>
after:
<attr name="subtitle"/>