What is the difference and more importantly the necessity of having different prefixes in Andriod view XML?
For example,
<android.support.v7.widget.Toolbar
android:id="#+id/actionToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentInsetEnd="20dp"
app:contentInsetEnd="20dp"
android:elevation="3dp"
/>
Has contentInsetEnd for both android and app.
android is usually used for attribute coming from Android SDK itself.
app is often used if you are using the support library.
You may also see other namespaces if you are using custom views (of your own or form a library).
Here is some extra information: http://developer.android.com/training/custom-views/create-view.html#customattr
app namespace is used for custom defined attributes, which are usually defined in /values/attrs.xml Here is a sample of such file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SimpleTabIndicator">
<attr name="numberOfTabs" format="integer"/>
<attr name="indicatorColor" format="color"/>
</declare-styleable>
</resources>
And a sample usage would be
<com.someapp.demo.SimpleTabIndicator
android:id="#+id/tabIndicator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#26292E"
app:indicatorColor="#FFFDE992"
app:numberOfTabs="5"/>
Android namespace you use for Android's widgets and UI controls.
app is just a namespace for any custom parameters for a custom View.
This can be anything but if you see the root element there's probably a line xmlns:app="http://schemas.android.com/apk/res-auto" that assigns the namespace .
Related
I am trying to create Android library module (API 21+) for my application, which will implement some of the business logic shared across various applications.
The issue is that I want to declare attributes in this library module, for which I will be able to set values in app modules of aforementioned projects.
The funny thing is, that my current solution works on emulator but not on physical devices.
Here is how I have it now (simplified, irrelevant parts omitted):
Library's attrs.xml:
<resources>
<attr name="lib_Background" format="reference"/>
<attr name="lib_Logo" format="reference"/>
</resources>
Applications styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="lib_Background">#drawable/back</item>
<item name="lib_Logo">#drawable/logo</item>
</style>
It does not matter whether I try to access these resources from xml of library's layout like this:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="?attr/lib_Background"
android:scaleType="centerCrop"/>
or programatically like this:
fun Context.getDrawableFromAttributes(idOfAttribute: Int): Drawable? {
val a = this.theme.obtainStyledAttributes(intArrayOf(idOfAttribute))
val resourceId = a.getResourceId(0, 0)
a.recycle()
return this.resources.getDrawable(resourceId, this.theme)
}
Still I have this image properly loaded on emulator, but "null" on physical device.
Is there some better or correct way how to achieve this?
I have kinda forgot about this question.
The issue was that I have used broken PNG for one particular density which caused it to be null. So it was not and error in implementation at all and this approach is absolutely valid.
We want to create an Android Class Library to reuse some code, mainly custom views.
I have successfully created and referenced the views in Xamarin.Android projects.
The only issue I've got is I cannot use the declare-styleable. The view is looking fine, but can't use custom attributes in the XML layout.
<resources>
<declare-styleable name="MyCustomView">
<attr name="srcLittle" format="reference" />
</declare-styleable>
</resources>
And this is how I use it:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/res-auto"
[...] >
[...]
<Core.MyCustomView
android:id="#+id/item_proposal_validation_trips_icon"
android:layout_gravity="center"
android:layout_height="48dp"
android:layout_width="48dp"
app:srcLittle="#drawable/ic_plane" /> <-- ERROR
[...]
</android.support.v7.widget.CardView>
Error in XML:
The "http://schemas.android.com/apk/res/res-auto:srcLittle" attribute is not declared
Error compiling:
1: error: No resource identifier found for attribute 'srcLittle' in package 'res-auto'
Thanks.
The namespace you've defined for the app prefix in your layout is incorrect.
xmlns:app="http://schemas.android.com/apk/res/res-auto"
The correct namespace for your app-defined attributes is http://schemas.android.com/apk/res-auto. You've got an extra res/ in there. It should be:
xmlns:app="http://schemas.android.com/apk/res-auto"
I've got a question on custom view XML-declarations.
I created my own View with the custom attributes as normal. Now I want to add more complex attributes like this: (This is non-working code)
<com.xxx.yyy.CustomTextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/customTextView1"
android:layout_marginBottom="22dp"
android:layout_toRightOf="#+id/buttonBlack"
android:text="TextView" >
<Animation
animation:property1="123"
animation:property2="456" />
<Animation
animation:property1="789"
animation:property2="012" >
</Animation>
</com.xxx.yyy.CustomTextView>
I didnt find a way to do this on my own but maybe someone has got an idea.
Thanks!
Edit:
I just solved the problem more or less nicely.
I created a new .xml file in my /res/xml folder called animations.xml
<animations>
<animation
name="Animation name 1"
float1="1.1"
float2="1.2"
integer1="11"
integer2="12" />
<animation
name="Animation name 2"
float1="2.1"
float2="2.2"
integer1="21"
integer2="22" />
</animations>
My custom view in attrs.xml contains an attribute which is used to reference the animations.xml file from above:
<declare-styleable name="MyTextView">
<attr name="animations" format="reference" />
</declare-styleable>
Now i parse the referenced .xml file in the constructor of the MyTextView as described here: http://thedevelopersinfo.com/2009/12/14/using-xml-file-resources-in-android/
Maybe this helps somebody at some time.
Unless CustomTextView extends ViewGroup (or has it in it's class hierarchy) and Animation is a custom view you've defined, this will not work. Only Views and ViewGroups are allowed in layout XML files (and some special tags defined by Android like include and merge), and only ViewGroup elements can have child elements.
You can add custom XML attributes to your custom view like this:
<resources>
<declare-styleable name="YourCustomClass">
<attr name="someCustomAnimationAttribute" format="reference" />
</declare-styleable>
<resources>
How you obtain it is described here:
http://developer.android.com/training/custom-views/create-view.html#applyattr
In your layout you have to declare a namespace:
xmlns:app="http://schemas.android.com/apk/res-auto"
and then use it like this:
<com.xxx.yyy.CustomTextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/customTextView1"
android:layout_marginBottom="22dp"
android:layout_toRightOf="#+id/buttonBlack"
android:text="TextView"
app:someCustomAnimationAttribute="#drawable/someAnimation">
That way you can supply those animations via XML instead of adding them as as child elements which is not possible.
I am trying to use custom attributes in some Android layouts, but I am getting an error (from Eclipse) when I try to use a namespace prefix other than android: in a child element. Note that it works ok when I use the custom: namespace prefix in the root/parent element in the file, just not the child element.
For example, here's a simple layout with the custom namespace specified:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:orientation="vertical"
custom:my_tag1="whatever"> <!-- compiles fine -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
custom:my_tag2="true"/> <!-- generates an error -->
</LinearLayout>
The error that Eclipse gives (only on the second attempt to use the custom: prefix) is:
Unexpected namespace prefix "custom" found for tag ImageView.
If I make my root element an ImageView instead of a LinearLayout, the prefix is accepted. So it seems to be just a problem using the namespace prefix in a child element.
Also, if I try to add another xmlns:custom="http://schemas.android.com/apk/res-auto" attribute to the ImageView, it complains as well.
If it helps, here is the attrs.xml file I'm using with the above:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="my_tag1" format="string"/>
<attr name="my_tag2" format="boolean"/>
</resources>
I've seen some stuff online that leads me to believe what I want to do should be possible. For example, in the accepted answer here, Qberticus uses the prefix "whatever" in a child class. Similarly in the post here.
I don't get it. Is using a non-android namespace prefix just not allowed for child elements, or am I doing something wrong?
It can be ignored, I always did it and I didn't encounter any problems.
To make it go away you need to set the following:
add xmlns:tools="http://schemas.android.com/tools" to your root view
add tools:ignore="MissingPrefix" to your text view
On a side note, however, I usually use custom attributes with custom views :-)
I would like my application to be available under different brandings - this means that it must be possible to easily change background bitmaps in few places, but also change text resources.
My plan is to use themes and styles, I know they can be used for switching bitmaps but will they allow me to change also texts in TextViews for example?
Is it also possible to specify in style or theme a text identifier and later dynamically read it in code?
[EDIT]
After some investigation, of course texts can be substituted with styles. Another problem that comes with application branding is the need to change package name - otherwise Google Play wont accept our branded application.
[EDIT]
After more investigation, below I include small sample on how to add two switchable themes that will allow to substitude drawable in activity layout, and text resource in textview. Whats left is to call setTheme(R.style.Theme1); or setTheme(R.style.Theme2); in onCreate before setContentView.
<-- attrs.xml />
<resources>
<attr name="ProductName" format="reference"/>
<attr name="ProductBackground" format="integer"/>
</resources>
<-- styles.xml />
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme1" parent="android:Theme.Light">
<item name="ProductName">#string/s_product_1_name</item>
<item name="ProductBackground">#drawable/back_1_vga</item>
</style>
<style name="Theme2" parent="android:Theme.Light" >
<item name="ProductName">#string/s_product_2_name</item>
<item name="ProductBackground">#drawable/back_2_vga</item>
</style>
</resources>
<-- my activity layout />
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?ProductBackground"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
tools:context=".MainActivity"
android:background="#ff0000"
android:text="?ProductName"
/>
</RelativeLayout>
There are two aproaches to make different brandings of you app:
1) Split your app into multiple library projects, common code is in lets say common_lib library project, and all your brandings are in separate projects using common_lib but changing some of the resources, like strings, some drawables, also package name. This is the aproach we have choosen in our app.
2) Use gradle product flavors: http://developer.android.com/sdk/installing/studio-build.html, I think this should now be the prefered solution.