This page in the Android documentation defines an element id as follows:
<TextView android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Type here:" />
However this page defines it as:
<EditText id="text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:textColor="#color/opaque_red"
android:text="Hello, World!" />
I thought I had a decent understanding of what was going on until I saw this second example. In the first case, you need the + character so that id 'label' is added to the R file, correct? In the second case, would the EditText's id not be added to the R file because it does not contain the + character?
Also, the second example does not include the android namespace on the id. Does having or not having the Android namespace affect whether that id will be added to the R file?
Thanks for any clarification.
This format without the android: namespace
id="text"
is from an earlier version of the Android SDK.
You are correct in your initial assessment. It's worth noting that the second id tag
<EditText id="text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:textColor="#color/opaque_red"
android:text="Hello, World!" />
Is missing the android: namespace so it actually isn't an android xml tag. The first one is an example of how to add that view's id to the R file so you can access it in your code. To be honest, I'm not sure what the purpose of the id in the second example is*, but I know that android wouldn't know what to do with it. The first one is the correct syntax.
*This is just speculation, but I'm willing to bet it was a typo somebody didn't notice or didn't care to fix because they were trying to illustrate something else.
The plus-symbol (+) means that this is a new resource name that must be created and added to our resources (in the R.java file). There are a number of other ID resources that are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, but must add the android package namespace, like so:
android:id="#android:id/empty"
Taken from Declaring Layout | Android Developers in the ID section.
However, in your second example there is no #android:id/ provided before the id text so to be brutally honest, I have never seen that notation before and wonder if that could be a typo on the author's part.
The second example is wrong. The attribute is always android:id and the value should be either #+id/myId (to create a new id called "myId") or #id/myId (to use an already defined id called "myId".) Using #android:id/theId lets you use ids defined by the android platform.
Related
How do I reference a later XML element?
Here's a specific use case. Let's say I have a form with a root LinearLayout, containing LinearLayouts for multiple rows, each row having one or more text input areas.
Here's a visual of what I'm going for. First pic is from Venmo's app, second is a rendering of the following XML.
Such a layout could look like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/row_card_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="#+id/card_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nextFocusDown="#id/month"/>
</LinearLayout>
<LinearLayout
android:id="#+id/row_date"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="#+id/month"
android:layout_height="wrap_content"
android:layout_width="100dp"
android:nextFocusDown="#id/year"/>
<EditText
android:id="#+id/year"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>
</LinearLayout>
In this use case, forward referencing is necassary in order to set the next focus element. That way, when you press the next button on the keyboard, it'll go to the correct view. In this sample xml, without the nextFocusDowns, pressing next would go from name to month, and never go to year.
However, if you try to compile this, you'll get an error:
Error:(18, 36) No resource found that matches the given name (at 'nextFocusDown' with value '#id/month').
This is because the id month hasn't yet been initialized when I'm trying to reference it, since that's later in the file. How can I reference an id in xml that appears later in the file?
The simplest solution is just to replace
android:nextFocusDown="#id/month"
with
android:nextFocusDown="#+id/month"
When the compiler is parsing your XML to add the id's to R.java, it just reads top to bottom. When you have #id/month, it searches through the existing id's, and fails to find it.
However, if you do #+id/month, it creates a new id, and links to that. When it gets to android:id=#+id/month in the actual month view, it links it to the same id that we already created.
This brings up the question: If you can replace #id/ with #+id/, and #+id/ will work regardless of the order of elements, why even bother to use #id/?
The reason for this is if the id doesn't exist, #id/ will throw a compiler error, while #+id/ will log a warning at runtime.
Consider this XML:
<EditText
android:id="#+id/month"
android:layout_height="wrap_content"
android:layout_width="100dp"
android:nextFocusDown="#+id/SOME_RANDOM_ID"/>
<EditText
android:id="#+id/year"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
When this is parsed, a new id element SOME_RANDOM_ID is created. However, when Android tries to apply it at runtime, it can't find an element with that id. If you look at Logcat, you'll see this:
W/View﹕ couldn't find view with id 2131689604
This log message is both hard to find and hard to debug. One small typo in a #+id/ and you'll have a bug that could be incredibly difficult to debug. However, if we had done:
android:nextFocusDown="#id/SOME_RANDOM_ID"
Then we'd get a compiler error, something like:
Error:(18, 36) No resource found that matches the given name (at 'nextFocusDown' with value '#id/SOME_RANDOM_ID').
This is much easier to find and debug.
tl;dr: You can use #+id/ instead of #id/ and you'll be able to forward reference, but note that that can make small typos incredibly difficult to debug.
You might be able to use a RelativeLayout to make all the Views exist in reverse order in the xml, but that seems like overkill to me.
I had the same issue recently and I used #+id/my_new_id the first time I referenced the element and later in the XML in the element definition, I assigned #id/my_new_id to the android:id attribute. It seems it works fine and it's not necessary write #+id with the same id more than one time avoiding possible warnings.
For example:
<LinearLayout
...
android:layout_toLeftOf="#+id/my_new_id"
... >
...
</LinearLayout>
<ImageButton
android:id="#id/my_new_id"
... />
So I'm trying to decide whether it would be worth it to refactor out my current use of id's in all of my android layouts to an ids.xml file, or to just leave my view code the way it is (with multiple views sharing ids and both views using "#+id/id_name).
Is there a significant compile/runtime performance benefit to refactoring out the ids to the ids.xml file? How about if the application gets bigger?
Related resources:
http://developer.android.com/guide/topics/resources/more-resources.html#Id
Thank you for your time.
I used <item type="id"> resources in my app because I have TextEdit views that serve a similar purpose in more than one Activity.
ids.xml has the following advantage: all ids were declared, so compiler can recognize them. If something like this:
<TextView
android:id="#+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBelow="#id/text2"
android:text="...."/>
<TextView
android:id="#+id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="...."/>
Can result in compiling error because text2 was refered before declared
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between “#id/” and “#+id/” in Android
When you create a layout XML file for Android applications, you usually declare the ID of each layout element as:
#+id/elementID
Don't you? I guess the "+" means that this element's ID is just created and therefore you need the plus, right?
But what do you have to do when you refer to a layout element before it is created? Do you refer to it with "+" and then create it without "+"? Simply put, is the following code correct (in a RelativeLayout container)?
<ImageButton
android:id="#+id/helpButton"
android:layout_toLeftOf="#+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageButton
android:id="#id/moreButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
I guess the "+" means that this element's ID is just created and therefore you need the plus, right?
Yes.
Do you refer to it with "+" and then create it without "+"?
Yes. The first occurrence of the ID gets the +. Second and subsequent occurrences can leave it off.
Simply put, is the following code correct (in a RelativeLayout container)?
Well, your ImageButtons are missing images... :-)
That being said, your use of the + sign there seems fine.
I have noticed in my main.xml layout, I'm creating a Tab Layout, that the declaration of "android:id" is different from what I've used for button, textview, etc.
For example:
<TabWidget android:id="#android:id/tabs" />
and example on Buttons:
<Button
android:id="#+id/button_next" />
What is the difference of the two declarations?
When you assign an ID like so:
<Button
android:id="#+id/button_next" />
You are creating a new resource ID in your project's resources in the R.java file.
When you assign an id that is prefixed with #android:id, you are referencing a resource that exists in the android namespace.
I.e:
<TabWidget android:id="#android:id/tabs" />
In this case, you assign the id #android:id/tabs to the TabWidget, because it allows for your instance of TabWidget to inherit from an existing resource in the android namespace.
See this page for more info on the different ID assignments (scroll to the Attributes section)
Certain id's are used by the android framework. Like tabwidget,list etc. When the activity is launched it finds its required elements by searching the layout for these id's.
But when you are setting and id to a view for your own apps purpose, you only use id/yourid.
This is only going to be used by your application code.
blessenm is right. While we load the application it will search for the default id that are created by the android framework. and second one is the is that we use to define it just for our application purpose only.
The first one is use for all the application but the second one is use only for that perticular application.
Hope you got the point.
Thanks.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is different between #+id/android:list and #id/android:list ??
What is the difference between #id/.. and #+id/..? I am not referring to the difference between
#android:id/.. and #id/..
Code Example:
<Button
android:id ="#id/add_button"
/>
<Button
android:id ="#+id/remove_button"
/>
What is the difference between the two id definitions above?
You must use the #+ notation on the first occurrence of the ID within an XML file. The second and subsequent times you can -- and should -- drop off the + sign. This will help catch typos.
For example, suppose that you have a RelativeLayout. You have a TextView in that RelativeLayout whose android:id is #+id/label. Later on in the layout XML file, you want to refer to that TextView from another one for positioning purposes (e.g., for android:layout_below).
If you typed in android:layout_below="#+id/labbel" (note the typo), at compile time, this will be considered OK. However, at runtime, things will not work, ranging from the widget being positioned incorrectly to an outright crash, depending on Android version.
If you typed in android:layout_below="#id/labbel" (note the typo and the missing + sign), then you would get a compile error.
UPDATE
Since I wasn't clear enough the first time, apparently, let's try again.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="URL:"
android:layout_alignBaseline="#+id/entry"
android:layout_alignParentLeft="true"/>
<EditText
android:id="#id/entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/label"
android:layout_alignParentTop="true"/>
<Button
android:id="#+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/entry"
android:layout_alignRight="#id/entry"
android:text="OK" />
<Button
android:id="#+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/ok"
android:layout_alignTop="#id/ok"
android:text="Cancel" />
</RelativeLayout>
Above, you will see a RelativeLayout. You will notice that the first occurrences of each ID get the + sign. The second and subsequent occurrences of each ID do not get the + sign.
You could use the + sign on all of them, but then if you make a typo, the compiler will not catch the problem.
The + sign effectively states "allocate a new ID". Not having the + sign states "use a previously-allocated ID, or fail at compile time if there is no such ID".
In the Android layout resource XML source files :
"#+id/anyId" : to add new id
"#id/anyId" : to refer existing id
You should use "#id/anyId" only when "anyId" is already added to R.java class using "#+id/anyId"
From Android Guide
For the ID value, you should usually
use this syntax form: "#+id/name". The
plus symbol, +, indicates that this is
a new resource ID and the aapt tool
will create a new resource integer in
the R.java class, if it doesn't
already exist.
So + is for assigning a new id, it will also work when using existed id but it is not necessary there.
The second one:
<Button android:id ="#+id/remove_button" />
defines a new id. You would use the first one, when you want to reference the layout element. For example, in a relative layout:
android:layout_below="#id/remove_button"