New resource id declaration without the plus sign - android

This documentation always puzzles me:
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. For example:
<TextView android:id="#+id/nameTextbox"/>
I've been programming for quite a while now. However, I've never encountered any case wherein I have to use the ID declaration without the plus sign. It is also counter-intuitive. IDs are supposed to be unique!
Any good use-case for this? Why would one want to re-use the same resource id name?

#+id/name When you create a new id
"#id/" When you link to existing id
Use-case example 1:
Let's say you created your own resource in XML:
<resources>
<item name="plusIcon" type="id"/>
</resources>
Now you can use this resource at multiple places without creating a new resource using #+id. Say layout_one.xml:
<TextView android:id="#id/plusIcon"/>
Same resource in layout_two.xml:
<TextView android:id="#id/plusIcon"/>
Use-case example 2:
There are a number of other ID resources that are offered by the Android framework. If you want to referencing an Android resource ID in that case you can use #android you don't need to create your own new resource ID

It means if you have declared a view in a layout_one.xml like
<TextView
android:text="Sample Text"
android:id="#+id/text_view_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And if you have similar textView into layout_two.xml like
<TextView
android:text="Sample Text2"
android:id="#+id/text_view_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
In both cases there will be only one id created into R.java and it will be reused into another xml (whichever will be called after).
SO here you can live with (in layout_two.xml)
<TextView
android:text="Sample Text2"
android:id="#id/text_view_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
here Android will reuse id as it was created before from layout_one.xml.
You should also read Difference between "#id/" and "#+id/" in Android and What is the difference between #id and #+id?

Firstly
we use + when we're referencing a id for the first time(in top to down order) in a particular xml file, not when we create some id for the first time.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/another_button"
android:layout_alignParentTop="true"
android:text="#string/button" />
<Button
android:id="#id/another_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/another_button" />
</RelativeLayout>
Secondly
when someone is working with RelativeLayout or ConstraintLayout i.e. some relative parent view they need to use same id multiple times in order to define the activity or some view in the activity etc.
Thirdly
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).
So every time we use #+id/some_id, it triggers the creation of a new resource reference to the same view, i.e., redundant.
Example(for the second use case)
<RelativeLayout
android:id="#+id/final_order_activity_order_rl"
android:layout_margin="5dp"
android:background="#drawable/gradient_for_btns"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_centerInParent="true"
android:layout_marginStart="8dp"
android:textStyle="bold"
android:textSize="18dp"
android:text="$2000"
android:textColor="#android:color/white"
android:maxLines="1"
android:layout_toLeftOf="#+id/final_order_activity_place_order_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/final_order_activity_total_tv" />
<Button
android:paddingStart="6dp"
android:paddingEnd="6dp"
android:layout_marginEnd="8dp"
android:text="Place Order"
android:background="#drawable/ripple_effect"
android:textColor="#color/baseColorBright"
android:layout_alignParentEnd="true"
android:layout_width="wrap_content"
android:layout_height="28dp"
android:id="#id/final_order_activity_place_order_btn"/>
</RelativeLayout>

Defining the constraints within a RelativeLayout might be a good example.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Top"/>
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Bottom"/>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/textView3"
android:layout_below="#id/textView1"
android:text="Center"/>
</RelativeLayout>
On the last TextView android:layout_above and android:layout_below don't require the plus symbol because textView1 and textView2 are already defined IDs.

Related

Why don't I get an error when I reference a id that hasn't been flagged with "#+id"?

I'm referencing #id/action_profile before assigning #+id/action_profile. Why doesn't this give me an error? Is it because the ids are assigned in R.java and the attributes are assigned at runtime?
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/action_profile"/>
<LinearLayout
android:id="#+id/action_profile"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true">
<ImageView android:id="#+id/profile_icon"
android:layout_height="25dp"
android:layout_width="25dp"/>
<TextView android:id="#+id/profile_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>
In order to talk about this topic, we need to have a solid foundation of understanding about what the android:id and android:layout_toLeftOf attributes (and any other attribute that expects an id resource) actually "do".
They only set int fields on their View (or their View's LayoutParams object).
These int fields can then later be used to specify behavior, but as far as the <TextView> tag is concerned, all that android:layout_toLeftOf="#id/action_profile" means is "store R.id.action_profile as the id of the view I should position myself to the left of". There is no top-down parsing of the text file to look for whether or not a view tag with that id was already previously declared. The TextView is just saving an int for later.
In fact, taking it to an extreme, the following is perfectly legal:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/some_other_id"
android:text="hello world"/>
</RelativeLayout>
There's nothing in this layout with the id some_other_id, so how could my TextView be below it? Well, if you run this app, it just positions itself at the top-left, because it couldn't find the view I was referring to.
The reason this compiles is that I have a different layout file in my project:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/some_other_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I'm hiding!"/>
This layout file isn't used in my activity. It has nothing to do with the first example at all. But all that matters is that it has #+id/some_other_id in it. This causes R.id.some_other_id to be created, and then my first layout is quite happy to use it.

#id is not working inside Relative Layout

As far as I know, the difference between #+id and #id is to create a resource id first time and reuse that already existed resource id in different places. For instance, If we have a Relative layout having two textViews one below another, we shall use #resourceId for the second textView which refers to the first TextView.
The problem is, after updating the android studio to 3.0, #resourceId is not working anymore.To place second textView below the first one, I need to use #+firstTextViewId instead of #firstTextViewId. More specifically I need to use,
android:layout_below="#+id/totalQty"
instead of
android:layout_below="#id/totalQty"
Here is the code
<RelativeLayout
android:id="#+id/relBottomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:id="#+id/totalQty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="abcdef"/>
<TextView
android:id="#+id/totalPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/totalQty"
android:text="saasdfdsdfsdf"/>
<TextView
android:id="#+id/totalNetPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/totalPrice"
android:text="abcdsadfsafddgfdgfgdef"
/>
</RelativeLayout>
Is it an understanding issue? or a problem from any end? Can anyone please explain?
I just remove + sign at #+id from your code. Here's the updated code
<RelativeLayout android:id="#+id/relBottomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/totalQty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="abcdef"/>
<TextView
android:id="#+id/totalPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/totalQty"
android:text="saasdfdsdfsdf"/>
<TextView
android:id="#+id/totalNetPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/totalPrice"
android:text="abcdsadfsafddgfdgfgdef"
/>
</RelativeLayout>

No resource found that matches the given name (at 'id' with value '#android:id/kish')

I want give id as #android:id/kish but it shows
No resource found that matches the given name (at 'id' with value '#android:id/kish').
but the above #android:id/text1 works
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Dummy content. -->
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView android:id="#android:id/text1"
style="?android:textAppearanceLarge"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />
<TextView android:id="#android:id/kish"
style="?android:textAppearanceLarge"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp" />
</LinearLayout>
</ScrollView>
IMAGES
#android:id/text1 is already defined in ids.xml.
ids.xml is generally used to declare the id's that you use for the views in the layouts.
So, you have to declare your #android:id/kish in ids.xml
Or you can declare like that android:id="#+id/kish"
When creating views dynamically, predefined id's in ids.xml gives the possibility to reference a newly created view. After you use the setId(id) method you can access the view as if it had been defined in XML. This is default ids of Android which you can find from this path "USER_DIRECTORY/android-sdk/platforms/android-23/data/res/values/ids.xml" where #android:id/text1 is also part of that. So,if you want to give id to any view then instead of using that, use like below to assign id.
android:id="#+id/textView"

RelativeLayout textviews overlapping

I have a rather simple ListView row:
<?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"
android:orientation="horizontal" >
<TextView
android:id="#+id/tournament_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textSize="25dp" />
<TextView
android:id="#+id/tournament_winner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="25dp" />
</RelativeLayout>
When the text of "#+id/tournament_name"is long - it overlaps with the one from "#+id/tournament_winner" and I don't understand why.
I tried using android:singleLine="false"to no avail. I also tried using android:inputType="textMultiLine"as the docu says android:singleLine="false" is deprecated but then I get the warning: Attribute android:inputType should not be used with <TextView>: Change element type to
<EditText> ? so no good here as well.
I also tried using android:ellipsize="end" but this doesn't work. I assume it is because the text in the left TextView ("#+id/tournament_name") is NOT long enough to fill up the full width of the ListView (which code is not sowing here).
I was sure that if I use android:layout_width="wrap_content"the two TextView fields shouldn't overlap.
Here is an example (see the second line):
Any further ideas how this could be fixed?
android:layout_toLeftOf="#id/tournament_winner" in First TextView.
Also set android:maxLines="1" and Fix width for tournament winner because when it gets long tournament name cant see...
row.xml
<?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"
android:orientation="horizontal" >
<TextView
android:id="#+id/tournament_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/tournament_winner"
android:maxLines="1"
android:text="NAMEEEEEEEEEEEEEEEEEEEEEEEEEEE"
android:textSize="25dp" />
<TextView
android:id="#+id/tournament_winner"
android:layout_width="wrap_content" android:layout_marginLeft="10dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="WINER"
android:textSize="25dp" />
</RelativeLayout>
Thank you very much for your answer - sorry it took me some time to respond. I ended up using your android:layout_toLeftOf="#+id/tournament_winner" but left the single line and the margin to the left unused, as the result seemed perfect to me (hope this is also the case for other devices).
One thing though - in the first text view (tournament_name) I had to use android:layout_toLeftOf="#+id/tournament_winner"and not android:layout_toLeftOf="#id/tournament_winner" - pay attention to the added +. For some reason I get an error using android:layout_toLeftOf="#id/tournament_winner": Error: No resource found that matches the given name... so it seems that it is possible and NEEDED to define the resource in the time of calling it because the system doesn't know it before it was defined.
<?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"
android:orientation="horizontal" >
<TextView
android:id="#+id/tournament_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/tournament_winner"
android:layout_alignParentLeft="true"
android:textSize="25dp" />
<TextView
android:id="#+id/tournament_winner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="25dp" />
</RelativeLayout>
You can use single text view in place of two and simply display both strings in one text view !!

Why TextViews running into each other in RelativeLayout

I have a problem with two Textviews on the same height in a RelativeLayout running into each other.
I use the following Layout.
<?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="fill_parent">
<ImageView
android:id="#+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="#drawable/icon" />
<TextView
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="NameNameNameNameNameNameName"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/logo"
android:gravity="clip_horizontal"
android:lines="1" />
<TextView
android:id="#+id/information"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Distance"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
<TextView
android:id="#+id/nrcoupons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number"
android:layout_alignRight="#id/information"
android:layout_alignBottom="#id/logo" />
<TextView
android:id="#+id/subcategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subcategory"
android:layout_alignLeft="#id/name"
android:layout_alignBottom="#id/logo" />
</RelativeLayout>
This gives me this view:
alt text http://janusz.de/~janusz/view.png
Everything is as I need it except the two textviews name and information are displayed on the same screen space with the one on top of the other.
How can I avoid this?
For your #+id/name TextView, add android:layout_toLeftOf="..." for whatever TextView is on the right. The screenshot and the XML do not seem to line up (screenshot appears to have "Distance" in the overwritten TextView, but the XML does not), so I'm not completely certain which widget this is.
If you are targeting Android 1.5, you will need to order the widgets in the XML such that the widgets are defined before they are referenced from android:layout_toLeftOf or android:layout_toRightOf. If you are targeting Android 1.6 and newer only, you can have them be in any order, but the first occurrence of any distinct ID must have the + sign, even if that first occurrence is in an android:layout_toLeftOf attribute instead of an android:id attribute.
Your namenamename textview is set with width = fill_parent so you can't put anything to its right ;)

Categories

Resources