Link to the xML element for Android hereinafter in the file

How to reference a later XML element?

Here is a specific use case. Let's say I have a form with a root LinearLayout containing LinearLayouts for multiple lines, each line has one or more text input areas.

It shows what I'm going to do. The first pic is from a Venmo application, the second is rendering the following XML.

Venmo example Layout

Such a layout may 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 case, the use of a direct link is not required to set the next focus element. Thus, when you press the next button on the keyboard, it will go to the correct view. In this example, xml without nextFocusDown s, pressing the next one will go from name to month and never go to year.

However, if you try to compile this, you will receive an error message:

Error: (18, 36) A resource was not found that matches the specified name (in 'nextFocusDown' with the value '@ id / month').

This is because id month has not yet been initialized when I try to reference it, since this is later in the file. How can I refer to the id in xml that appears later in the file?

+5
source share
2 answers

The easiest solution is to simply replace

android:nextFocusDown="@id/month"

with

android:nextFocusDown="@+id/month"

When the compiler parses your XML to add id to R.java, it just reads from top to bottom. When you have @id/month , it scans existing identifiers and does not find it.

However, if you do @+id/month , it creates a new identifier and refers to it. When it comes to android: id=@ +id/month in the current view of the month, it associates it with the same identifier that we have already created.


The question arises: if you can replace @id/ with @+id/ , and @+id/ will work regardless of the order of the elements, why even use @id/ ?

The reason for this is that the identifier does not exist, @id/ will throw a compiler error, and @+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"/> 

The analysis creates a new id element SOME_RANDOM_ID . However, when Android tries to apply it at runtime, it cannot find an element with this identifier. If you look at Logcat, you will see the following:

W / View: Could not find view with id 2131689604

This log message is hard to find and hard to debug. One small typo in @+id/ and you will have an error that could be incredibly difficult to debug. However, if we did:

android:nextFocusDown="@id/SOME_RANDOM_ID"

Then we would get a compiler error, for example:

Error: (18, 36) A resource was not found that matches the specified name (in 'nextFocusDown' with the value '@ id / SOME_RANDOM_ID').

It is much easier to find and debug.


tl; dr: you can use @+id/ instead of @id/ and you can redirect the link, but note that this can make small typos incredibly difficult to debug.

You might be able to use RelativeLayout to make all views in reverse order in xml, but to me that seems redundant.

+11
source

I had the same problem recently, and I used @ + id / my_new_id when I first accessed the element, and then in the XML in the element definition, I assigned @ id / my_new_id to the android: id attribute. It seems to work fine and there is no need to write @ + id with the same identifier more than once, avoiding possible warnings.

For instance:

 <LinearLayout ... android:layout_toLeftOf="@+id/my_new_id" ... > ... </LinearLayout> <ImageButton android:id="@id/my_new_id" ... /> 
0
source

All Articles