I am creating a custom view to represent some kind of a content. I want this content to be scrollable (vertically) and I want standard scroll bars to be visible during the scroll. In order to do this I've included the following code to the cinstructor of my custom view:
setVerticalScrollBarEnabled(true);
setHorizontalScrollBarEnabled(false);
TypedArray a = context.obtainStyledAttributes(R.styleable.View);
initializeScrollbars(a);
a.recycle();
Now, this R.stylable.View is as follows:
<declare-styleable name="View">
<attr name="android:fadeScrollbars"/>
<attr name="android:scrollbarAlwaysDrawHorizontalTrack"/>
<attr name="android:scrollbarAlwaysDrawVerticalTrack"/>
<attr name="android:scrollbarDefaultDelayBeforeFade"/>
<attr name="android:scrollbarFadeDuration"/>
<attr name="android:scrollbarSize"/>
<attr name="android:scrollbarStyle"/>
<attr name="android:scrollbarThumbHorizontal"/>
<attr name="android:scrollbarThumbVertical"/>
<attr name="android:scrollbarTrackHorizontal"/>
<attr name="android:scrollbarTrackVertical"/>
<attr name="android:scrollbars"/>
</declare-styleable>
This code works properly on each and every Android device. Except for the Sony Xperia Z which gives me the NumberFormatException each time it comes across initializeScrollbars(a) :
Caused by: java.lang.NumberFormatException: Invalid int: "25.0dip"
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parse(Integer.java:375)
at java.lang.Integer.parseInt(Integer.java:366)
at com.android.internal.util.XmlUtils.convertValueToInt(XmlUtils.java:122)
at android.content.res.TypedArray.getInt(TypedArray.java:254)
at android.view.View.initializeScrollbars(View.java:4172)
at TheCustomViewIAmTryingToCreate.<init>(MyCustomView.java:164)
... 36 more
I can see that it interprets some XML-defined value incorrectly but I can not get which one exactly. This line:
at android.view.View.initializeScrollbars(View.java:4172)
points me to the source of View class which I reviewed in order to find the reason. The problem is that initializeScrollbars method (official Android source) has nothing to do with line 4172. Obviuosly Sony (in some way) modified Android on their devices which now makes my code crash.
Does anyone know what causes such a problem or where can I find sources for Android installed on Xperia Z1 (C6903) to look at the reason of this problem?
Edit: This also happens on Xperia Tablet Z (SGP321) and Xperia ZL (C6503)
I still do not know what caused this crash but I have managed to fix it. I ended up extending R.stylable.View with some more attributes:
<declare-styleable name="View">
<attr name="android:background"/>
<attr name="android:clickable"/>
<attr name="android:contentDescription"/>
<attr name="android:drawingCacheQuality"/>
<attr name="android:duplicateParentState"/>
<attr name="android:fadeScrollbars"/>
<attr name="android:fadingEdge"/>
<attr name="android:fadingEdgeLength"/>
<attr name="android:fitsSystemWindows"/>
<attr name="android:focusable"/>
<attr name="android:focusableInTouchMode"/>
<attr name="android:hapticFeedbackEnabled"/>
<attr name="android:id"/>
<attr name="android:isScrollContainer"/>
<attr name="android:keepScreenOn"/>
<attr name="android:longClickable"/>
<attr name="android:minHeight"/>
<attr name="android:minWidth"/>
<attr name="android:nextFocusDown"/>
<attr name="android:nextFocusLeft"/>
<attr name="android:nextFocusRight"/>
<attr name="android:nextFocusUp"/>
<attr name="android:onClick"/>
<attr name="android:padding"/>
<attr name="android:paddingBottom"/>
<attr name="android:paddingLeft"/>
<attr name="android:paddingRight"/>
<attr name="android:paddingTop"/>
<attr name="android:saveEnabled"/>
<attr name="android:scrollX"/>
<attr name="android:scrollY"/>
<attr name="android:scrollbarAlwaysDrawHorizontalTrack"/>
<attr name="android:scrollbarAlwaysDrawVerticalTrack"/>
<attr name="android:scrollbarDefaultDelayBeforeFade"/>
<attr name="android:scrollbarFadeDuration"/>
<attr name="android:scrollbarSize"/>
<attr name="android:scrollbarStyle"/>
<attr name="android:scrollbarThumbHorizontal"/>
<attr name="android:scrollbarThumbVertical"/>
<attr name="android:scrollbarTrackHorizontal"/>
<attr name="android:scrollbarTrackVertical"/>
<attr name="android:scrollbars"/>
<attr name="android:soundEffectsEnabled"/>
<attr name="android:tag"/>
<attr name="android:visibility"/>
</declare-styleable>
Maybe this is too much but my application no longer crashes after that.
Though it is not necessary anymore, still if anyone has any idea on where I went wrong please do not leave me unenlightened.
Related
I would like to add the design suppport library (com.android.support:design:22.2.0) but I got this error message:
"headerLayout" has already been defined
I tried to find which library use this from my library list and maybe this one:
https://github.com/traex/ExpandableLayout
How can I use theme same time? Thank you!
Edit:
here is some detail:
Error:(1) Attribute "headerLayout" has already been defined ...
...debug\values\values.xml:440: error: Attribute "headerLayout" has already been defined
And this is the 440. line:
<declare-styleable name="NavigationView">
<attr name="android:background"/><attr name="android:fitsSystemWindows"/>
<attr name="android:maxWidth"/><attr name="elevation"/>
<attr format="reference" name="menu"/>
<attr format="color" name="itemIconTint"/>
<attr format="color" name="itemTextColor"/>
<attr format="reference" name="itemBackground"/>
<attr format="reference" name="headerLayout"/>
</declare-styleable>
and I found another item with this reference name, which is come from ExpandableLayout:
<declare-styleable name="ExpandableLayout">
<attr format="reference" name="headerLayout"/>
<attr format="reference" name="contentLayout"/>
<attr format="integer" name="duration"/>
</declare-styleable>
What is the solution? Because I can't modify these properties.
It would be more useful if you post your Error log and a code snippet for the affected code.
It does not seem like a dependency error, check to see if you have a variable called headerLayout and see you have that declared more than once.
Edit:
A workaround would be to change one of the name "headerLayout" to something else. Of course all reference to it must also be updated. This is an ambiguity error.
This is an old question but i will answer anyway, maybe will help someone.
Change de version of ExpandableLayout to:
compile 'com.github.traex.expandablelayout:library:1.3'
Than you will have other issues:
Error:(16) No resource identifier found for attribute 'contentLayout' in package ....
change:
contentLayout ---> el_contentLayout
headerLayout ---> el_headerLayout
if you call the contentLayout or header layout in JAVA, change:
getHeaderRelativeLayout() ----> getHeaderLayout()
getContentRelativeLayout() ----> getContentLayout()
and everything will work just fine :)
In my Android project I have a couple of custom components that use custom attributes.
The attrs.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources >
<declare-styleable name = "TextBox">
<attr name = "font" format = "string"/>
</declare-styleable>
<declare-styleable name = "ButtonBox">
<attr name = "font" format = "string"/>
</declare-styleable>
</resources>
I am pulling in the attributes just fine in the custom component, but when I go to run the code I see the following error.
Error: Found item Attr/font more than one time
Error: Execution failed for task ':app:mergeDebugResources'.
It shouldn't make a difference that there are similar attribute names in two different declare-styleable resources correct?
If you have any help it would be greatly appreciated, thank you!
As you can see here, the attr itself can have multiple properties and can be defined only once and you can configure multiple details inside it.
So you should give it different names or, since they have the same properties, use only one declare-styable for both.
Check out this link too, there's a good example.
Here is how it should be:
<?xml version="1.0" encoding="utf-8"?>
<resources >
<declare-styleable name="Box">
<attr name="font" format="string"/>
</declare-styleable>
</resources>
You can use Box on text, button, etc.
Android — Custom Views: same Attribute on multiple Custom Views
You may have tried something like the code below in your attrs.xml:
'''
<resources>
<declare-styleable name="MyComponent1">
<attr name="myAttr" format="string" />
</declare-styleable>
<declare-styleable name="MyComponent2">
<attr name="myAttr" format="string" />
</declare-styleable>
</resources>
'''
But this does not work, and we get an Error:
Found item Attr/myAttr more than one time.
How do native views handle that?
Native Views have the same attribute names and don’t suffer from this problem.
Let’s sneak into their code and see how these attributes are declared.
Looking into their code, we can see that they create the attr tag outside declare-styleable, and then, inside of it you just need to reference it only by its name, there is no need to declare format again.
Our code should be just like that:
<resources>
<attr name="myAttr" format="string" />
<declare-styleable name="MyComponent1">
<attr name="myAttr" />
</declare-styleable>
<declare-styleable name="MyComponent2">
<attr name="myAttr" />
</declare-styleable>
</resources>
can also read this fantastic medium paper :
same Attribute on multiple Custom Views
Custom attributes are great, but all tutorials mention usage in custom views where you have AttributeSet parameter ready.
Contents of my attrs.xml:
<declare-styleable name="StyledDialogs">
<attr name="sdlDialogStyle" format="reference" />
</declare-styleable>
<declare-styleable name="DialogStyle">
...
</declare-styleable>
I'm struggling how to access those attributes in any class outside custom view.
After a few hours, I have figured out a way which works:
final TypedArray a = mContext.getTheme().obtainStyledAttributes(null, R.styleable.DialogStyle, R.attr.sdlDialogStyle, 0);
I follow this guide to make a custom ListView for my app. The tutorial uses a namespace called ottasee, which should be defined as a xml-namespace inside the element. So here is some of my code:
<com.my.app.Layout.CustomListView
xmlns:ottasee="what_should_i_put_here?"
android:id="#+id/lastCases"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#null"
android:scrollbars="none"
ottasee:dropShadowBottom="true"
ottasee:dropshadowrightsrc="#drawable/drop_shadow"
/>
I can see that the attributes ottasee:dropShadowBottom and ottasee:dropshadowrightsrc are part of my attrs.xml in the values folder. Like this:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="DropShadowListView">
<attr format="boolean" name="dropShadowLeft"></attr>
<attr format="reference" name="dropShadowLeftSrc"></attr>
<attr format="boolean" name="dropShadowRight"></attr>
<attr format="reference" name="dropShadowRightSrc"></attr>
<attr format="boolean" name="dropShadowTop"></attr>
<attr format="reference" name="dropShadowTopSrc"></attr>
<attr format="boolean" name="dropShadowBottom"></attr>
<attr format="reference" name="dropShadowBottomSrc"></attr>
</declare-styleable>
</resources>
How should I define the xml namespace for the ListView in order to grab the attributes from the attrs.xml file?
Thanks!
EDIT
My CustomListView is under the package com.my.app.Layout and I tried to declare the ns this way: xmlns:ottasee="http://schemas.android.com/apk/res/com.my.app.Layout
But I only get an error in my xml file:
Multiple annotations found at this line:
- error: No resource identifier found for attribute 'dropShadowBottom' in package
'com.my.app.Layout'
- error: No resource identifier found for attribute 'dropshadowrightsrc' in package
'com.my.app.Layout'
How can I accomplish setting the right ns?
You should add the following the following to include the necessary attributes to your namespace:
xmlns:ottasee ="http://schemas.android.com/apk/res-auto"
Slightly different to #budius's answer as it will auto-resolve the package name for you.
usually the XML editor do it for you, I've even never worried, but it's like that:
xmlns:ottasee="http://schemas.android.com/apk/res/com.your.package.name"
I'm developing an Android app, that uses sereval libraries in que. That means:
Project A is ibrary.
Project B uses library A and is library.
Project C users library B.
Now in Project A or B i try to define attributes for custom views. Since SDK 17, there should be no more problems with the namespace. When I make a declare-styleable, my R.class is generated automatically as excpected and the defined attributes listed up in the R.class, so I don't excpect any error in the xml-Files. (Normally, the R.class is not generated after clean project, when there is an error in the xml.)
Now the strange thing is, that I got an error in the R.class itself. The last } to complete the class is not built. If I insert it manually, it's removed automatically after a fiew seconds.
Here is my attrs.xml file:
<?xml version="1.0" encoding="utf-8"?>
<declare-styleable name="ContentBox">
<attr name="distanceToText" format="dimension" />
<attr name="distanceBetweenText" format="dimension" />
<attr name="titleColor" format="color" />
<attr name="textColor" format="color"></attr>
<attr name="textSizeTitle" format="dimension"></attr>
<attr name="textSizeText" format="dimension"></attr>
<attr name="paddingVerticalTitle" format="dimension"></attr>
<attr name="paddingLeftTitle" format="dimension"></attr>
<attr name="paddingHorizontalText" format="dimension"></attr>
<attr name="titleBackgroundColor" format="color"></attr>
<attr name="frameColor" format="color"></attr>
<attr name="backgroundColorClickable" format="color"></attr>
<attr name="title" format="string"></attr>
<attr name="textSizeColumnOne" format="dimension"></attr>
<attr name="textSizeColumnTwo" format="dimension"></attr>
<attr name="textColorColumnOne" format="color"></attr>
<attr name="textColorColumnTwo" format="color"></attr>
<attr name="distanceBetweenTextHoriz"></attr>
</declare-styleable>
Has anyone an idea?
If you are using the eclipse plugin,if you delete the R class,then rebuild the project,is should regen it,hopefully properly
I found the mistake. In the last line, there is no format defined, that ends in the error with the R.class...