Why isn't Eclipse accepting valid Android IDs in nextFocusForward? - android

I have some EditText views in a RelativeLayout. The first one receives focus correctly, but when the user clicks "Finished" on the keyboard, it usually doesn't send focus to the view the user expects. Assuming that the "Finished" button uses the FOCUS_FORWARD ID, I have tried to fix this behaviour by using the android:nextFocusForward attribute like so:
<EditText
android:id="#+id/editTextName"
...
android:nextFocusForward="#id/editTextNameColour" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editTextNameColour"
...
android:nextFocusForward="#id/editTextBackgroundColour" />
<EditText
android:id="#+id/editTextBackgroundColour"
... />
It doesn't compile because Eclipse gives me an error message like: "error: Error: No resource found that matches the given name (at 'nextFocusForward' with value '#id/editTextNameColour')".
I know the name is correct because I selected it from a dropdown list in Eclipse and all files have been saved.
Android Developers Reference says that EditText is the right type (a View).
If there's a better way than using android:nextFocusXxx attributes, including doing it in the Java code, that's fine too.
I'm not open to solving this by using a LinearLayout.
Also, am I right that the "Finished" button uses the FOCUS_FORWARD?
Thanks
Solution: I need to use #+id... rather than #id because I am referencing objects declared later in the code; and the keyboard appears to use FOCUS_DOWN rather than FOCUS_FORWARD.

It's because of #id vs #+id. Just use #+id. You're trying to use an ID before its been assigned a resource. You can also switch the order around that you're declaring stuff, if its in relativeLayout.

If that is the order, then you are referencing elements that hasn't been defined yet. You should do something like:
<EditText
android:id="#+id/editTextName"
...
android:nextFocusForward="#+id/editTextNameColour" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editTextNameColour"
...
android:nextFocusForward="#+id/editTextBackgroundColour" />
<EditText
android:id="#+id/editTextBackgroundColour"
... />

Related

text/hint in XML changed back from #string to hardcode

After some time my xml files declaration are changing. sometimes when I open it my textvalues are changing from my #string values to regular texts. In this case:
android:id="MAC Adress" Can someone explain why?
<EditText
android:layout_width="330dp"
android:layout_height="wrap_content"
android:hint="#string/mac" <!-- <-- THIS -->
android:id="#+id/editText_mac"
android:maxLength="17"
android:paddingLeft="15dp"
android:paddingRight="15dp" />
it is a nice feature of AndroidStudio. It shows the content pointed by the id. But you are still using the reference to the localized value. As matter of fact, if you click on the text, you will see again #string/ instead of the value pointed by it
try clicking on it, you'll see the previous string path. It just hides to make it clear and easy to access the string , instead of the path to string. It's the same with every one...

Android layout reference xml element later in file

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"
... />

Two views referencing each other

I have two textviews declared as below. My intention is to have two views side by side, where left view (displaying user name) has bigger text size, right view displays time of last message send and should be always visible (even if user has really long name, that's why I'm using android:layout_toLeftOf). However, left view is smaller and I want to align its baseline to right view. It's really nice dependency where and I'm not able to solve it.
Partially acceptable solution is to use "android:layout_toRightOf" in right view, but if user has really long name, then time (right view) will be ellipsized (it's declared in AppTheme.TextView.SingleLine).
So basically, my questions is, is it possible for two views to reference each other? I understand why I'm getting this error, but I'm not able to solve it.
I remember from my C/C++ times that it was possible to declare function in the top of the file and then define it somewhere else (so the compiler doesn't complain) and I think it's something what I need here.
<TextView
android:id="#+id/fragment_messages_item_sender_name"
style="#style/AppTheme.TextView.SingleLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/fragment_messages_item_last_msg_time"
android:textSize="#dimen/global_text_large"/>
<TextView
android:id="#+id/fragment_messages_item_last_msg_time"
style="#style/AppTheme.TextView.SingleLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#id/fragment_messages_item_sender_name"
android:layout_alignParentEnd="true"
android:gravity="right"/>
All I'm getting is
Error:(27, 38) No resource found that matches the given name (at 'layout_toLeftOf' with value '#id/fragment_messages_item_last_msg_time').
in R class id like
fragment_messages_item_last_msg_time
not exist
for avoid that problem need to use "+" before declaration field with id relation
android:layout_toLeftOf="+#id/fragment_messages_item_last_msg_time"
you could move the android:layout_alignBaseline in the other TextView. Be aware of id loops, that usually generated nasty crashes.
About your issue, you have to remember the entries inside R are marked as public static final, and that the + generates a new entry for the specify id, if it does not exists, So you can have:
android:layout_toLeftOf="#+id/fragment_messages_item_last_msg_time"
in the first TextView, and
android:id="#id/fragment_messages_item_last_msg_time"
to the second one. As I mentioned before, loops in RelativeLayout are not allowed, and those will make your app crash
Hi use below code :
<LinearLayout 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:orientation="horizontal" >
<TextView
android:id="#+id/fragment_messages_item_sender_name"
style="#style/AppTheme.TextView.SingleLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Manish" />
<TextView
android:id="#+id/fragment_messages_item_last_msg_time"
style="#style/AppTheme.TextView.SingleLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Khamar" />
</LinearLayout>

Meaning of "No label views point to this text field" warning message

What is the meaning of this warning?
No label views point to this text field with an android:labelFor="#
id/# id/editText1" attribute
Note that the double id (#id/#id) is a problem with the error message text and does not reflect the XML content (which is the correct syntax).
The labelFor is an attribute for accessibility options. You assign this to a label so that if, on a form , user clicks a textedit field , android can know what to read (TalkBack) to user.
The id you assigned to it doesn't seem to be a valid one. why there are two #id in the id? Use ids like this: #id/editText1
I've had the same warning message. It disappeared, when I added a hint to my EditText
android:hint="Some explanation about the input..."
Although I am not familiar with the exact error you have posted. But it definitely sounds like you have done something wrong with the id in the textView. Use id like following in your textView.
android:id="#+id/editText1"
And if you want to set labelFor then use :
android:labelFor="#+id/editText1"
It means that you probably should define a label for this edit text and link them using a labelFor inside that labels definition.
example code:
<TextView
android:id="#+id/my_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="#+id/my_editText" <!--the plus sign goes first in the code-->
android:text="I'm a label" />
<EditText
android:id="#id/my_editText" <!--no plus sign if not the first-->
android:layout_width="wrap_content"
android:inputType="text"
android:layout_height="wrap_content" />
and it's not only for text views.
Remove th first '#id/' , use like
android:id="#+id/editText1"
which is the correct format. Keep going.. Best wishes.. :)
I solved it by writing both attributes:
android:id="#+id/editText1"
android:labelFor="#+id/editText1"
Select the editText, go to Properties, then Label for and enter #id/EditText1
If the XML looks correct and you're in a Graphical Layout mode then it's probably using a later version of the Android rendering layout that doesn't support EditText.
In Eclipse and Android Studio there should be a green Android icon with what API version is rendering the layout. Make sure you're using a non W or Wearable API as Android W APIs don't support the EditText element. (EditText is most likely not supported because virtual keyboard space is limited on those devices).
The rendered preview should support EditText in any API 4.X version without a trailing W.

RelativeLayout id references

These two views are inside of RelativeLayout. The IDE throws an error there is no #id/et_pass, but if I set #+id/et_pass it is OK. Why is that?
<ImageView
android:id="#+id/devider_zero"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/et_pass" <!-- Error is here -->
android:src="#drawable/registration_line" />
<EditText
android:id="#+id/et_pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/devider_first"
android:background="#android:color/transparent"
android:layout_gravity="left"
android:ellipsize="start"
android:ems="8"
android:hint="#string/password"
android:inputType="textPassword"
android:layout_marginTop="#dimen/register_layout_edittext_margin_top"
android:maxLines="1" />
The difference between #+id/something and #id/something is that the first one is creating an id, and the second one is referencing an id that has already been created. The first time that you mention an id you have to create it using #+id/, and anything after that can use #id/.
When you give a view the attribute android:id you do not have to use #+id/ if you have already used that somewhere earlier in your file.
Because of the way android compiles XML files, it reads your image view first, reaches the point where you write #id/ searches for an id in the R file, and can't find it. But if you call #+id/ the eclipse searches for the id in the R file, can't find it, and adds it.
Also, this is not specific to RelativeLayouts, if you put the same code in a linear layout, you would also get that error
#+id instructs the parser to create the ID if it does not exist. #id is used to refer to an existing ID.

Categories

Resources