so I recently migrated to gradle now my custom view attributes return null
my project looks like this
--custom_icon_view // library that holds the custom view with custom attributes
--my application // this is the main app that actually uses the custom view
in my layout I have the namespace defined like this :
xmlns:iconview="http://schemas.android.com/lib/be.webelite.iconview"
because using apk/res-auto retuns an error saying attibutes could not be identified
this is how I try to get the icon name defined in xml, this used to work perfectlly
but now it doesnt. and all I changed was migrating to gradle.
final TypedArray a = context.obtainStyledAttributes(attrs,be.webelite.iconview.R.styleable.icon);
icon_name = a.getString(be.webelite.iconview.R.styleable.icon_name);
so I'm guessing my gradle.build files are causing a problem?
I have the library set to
apply plugin: 'android-library'
end the main app gradle.build as
apply plugin: 'android'
this has been giving me headache for 2 days now :( any help/hints are very apperciated.
here are my gradle files
http://pastie.org/private/h57o8nanydosq0dtm6eiq
and here is the folder structure
http://pastie.org/private/nvbzomx2zeagdpzt8qqjsq
this is how I declare my view in the xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<!-- tried res-auto didn't work -->
xmlns:iconview="http://schemas.android.com/apk/lib/be.webelite.iconview"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_gray">
<be.webelite.iconview.IconView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
iconview:icon_name="entypo_search"
android:textSize="25dp"/>
attrs.xml in IconView>res>values directory
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="icon">
<attr name="name" format="string" />
</declare-styleable>
</resources>
Can't really see what's wrong in your project. Here is how I use custom view & attrs in mine :
In my library project :
attrs.xml :
<declare-styleable name="CustomFontSize">
<attr name="typeFace" format="string" />
</declare-styleable>
in my custom class :
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomFontSize);
if (a == null) {
return;
}
CharSequence s = a.getString(R.styleable.CustomFontSize_typeFace);
if (s != null) {
// do something
}
In my Main Project here an example of one of my layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/border_margin_pulltorefresh"
android:paddingRight="@dimen/border_margin_pulltorefresh"
android:paddingBottom="@dimen/divider_height">
<com.custom.view.TextViewFont
style="@style/DateStyle"
android:id="@+id/news_date"
android:shadowColor="@color/white"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
custom:typeFace="@string/font_roboto_condensed_bold"/>
</LinearLayout>
Hope it will help ...
Edit :
in my build.gradle of my "main project"
dependencies {
compile project(":MyLibraryProject")
}
And here the build.gradle of my library :
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}
apply plugin: 'android-library'
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:support-v4:19.0.0'
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
compile project(':WebediaCore:dependencies:DataDroid')
compile project(':WebediaCore:dependencies:ViewPagerIndicator')
compile project(':WebediaCore:dependencies:ActionBar-PullToRefresh')
compile project(':WebediaCore:dependencies:Android-Universal-Image-Loader')
}
android {
compileSdkVersion 19
buildToolsVersion '19'
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
}
}
EDIT1 :
Try to use this namespace :
xmlns:custom="http://schemas.android.com/apk/res-auto"
and replace :
iconview:icon_name="entypo_search"
by :
custom:name="entypo_search"
I think you should use
iconview:name="entypo_search"
instead of
iconview:icon_name="entypo_search"
If you are grabbing attributes in your custom view's init method with hard references to that specific namespace then changing to res-auto will break that. Instead, you will need to change those references also to res-auto. Or the preferred method is to just grab the typed interface. For example, in my project this:
textStyle = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/com.bodybuilding.mobile", "textStyle", 10);
shadowInner = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.bodybuilding.mobile", "shadowInner", true);
shadowOuter = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.bodybuilding.mobile", "shadowOuter", false);
allowResize = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.bodybuilding.mobile", "allowResize", true);
Became either this:
textStyle = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto", "textStyle", 10);
shadowInner = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res-auto", "shadowInner", true);
shadowOuter = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res-auto", "shadowOuter", false);
allowResize = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res-auto", "allowResize", true);
but preferably this:
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.BBcomButton);
textStyle = a.getInt(R.styleable.BBcomButton_textStyle, 10);
shadowInner = a.getBoolean(R.styleable.BBcomButton_shadowInner, true);
shadowOuter = a.getBoolean(R.styleable.BBcomButton_shadowOuter, false);
shadowInnerColor = a.getColor(R.styleable.BBcomButton_shadowInnerColor, 0xff000000);
shadowOuterColor = a.getColor(R.styleable.BBcomButton_shadowOuterColor, 0xff000000);
allowResize = a.getBoolean(R.styleable.BBcomButton_allowResize, true);
To make it work
You will get this error when you have statically declared your package name as a namespace (e.g xmlns:iconview="http://schemas.android.com/apk/lib/be.webelite.iconview" in your case) in a layout file and try building the project with Lint on. Check the Android Gradle Lint checks:
In Gradle projects, the actual package used in the final APK can vary; for
example,you can add a .debug package suffix in one version and not the other.
Therefore, you should not hardcode the application package in the resource;
instead, use the special namespace http://schemas.android.com/apk/res-auto
which will cause the tools to figure out the right namespace for the resource
regardless of the actual package used during the build.
If anyone is here and nothing appears to be working. From what I can see, having an underscore in your namespace appears to work fine in the editor, but breaks unexpectedly as you build the app.