In an XML file, we can assign an ID to a view like android:id="@+id/something"
and then call findViewById()
, but when creating a view programmatically, how do I assign an ID?
I think setId()
is not the same as default assignment. setId()
is extra.
Can anybody correct me?
Android
id
overviewAn Android
id
is an integer commonly used to identify views; thisid
can be assigned via XML (when possible) and via code (programmatically.) Theid
is most useful for getting references for XML-definedView
s generated by anInflater
(such as by usingsetContentView
.)Assign
id
viaXML
android:id="@+id/
somename"
to your view.android:id
will be assigned a uniqueint
for use in code.android:id
'sint
value in code using "R.id.
somename" (effectively a constant.)int
can change from build to build so never copy an id fromgen/
package.name/R.java
, just use "R.id.
somename".id
assigned to aPreference
in XML is not used when thePreference
generates itsView
.)Assign
id
via code (programmatically)id
s usingsomeView.setId(
int);
int
must be positive, but is otherwise arbitrary- it can be whatever you want (keep reading if this is frightful.)Uniqueness of
id
sXML
-assignedid
s will be unique.id
s do not have to be uniqueid
s can (theoretically) conflict withXML
-assignedid
s.id
s won't matter if queried correctly (keep reading).When (and why) conflicting
id
s don't matterfindViewById(int)
will iterate depth-first recursively through the view hierarchy from the View you specify and return the firstView
it finds with a matchingid
.id
s assigned before an XML-definedid
in the hierarchy,findViewById(R.id.somename)
will always return the XML-defined View soid
'd.Dynamically Creating Views and Assigning
ID
sViewGroup
withid
.LinearLayout
withandroid:id="@+id/placeholder"
.ViewGroup
withView
s.id
s that are convenient to each view.Query these child views using placeholder.findViewById(convenientInt);
API 17 introduced
View.generateViewId()
which allows you to generate a unique ID.If you choose to keep references to your views around, be sure to instantiate them with
getApplicationContext()
and be sure to set each reference to null inonDestroy
. Apparently leaking theActivity
(hanging onto it after is is destroyed) is wasteful.. :)Reserve an XML
android:id
for use in codeAPI 17 introduced
View.generateViewId()
which generates a unique ID. (Thanks to take-chances-make-changes for pointing this out.)*If your
ViewGroup
cannot be defined via XML (or you don't want it to be) you can reserve the id via XML to ensure it remains unique:Here, values/ids.xml defines a custom
id
:Then once the ViewGroup or View has been created, you can attach the custom id
Conflicting
id
exampleFor clarity by way of obfuscating example, lets examine what happens when there is an
id
conflict behind the scenes.layout/mylayout.xml
To simulate a conflict, lets say our latest build assigned
R.id.placeholder
(@+id/placeholder
) anint
value of12
..Next, MyActivity.java defines some adds views programmatically (via code):
So
placeholder
and one of our newTextView
s both have anid
of 12! But this isn't really a problem if we query placeholder's child views:*Not so bad
Yes, you can call
setId(value)
in any view with any (positive) integer value that you like and then find it in the parent container usingfindViewById(value)
. Note that it is valid to callsetId()
with the same value for different sibling views, butfindViewById()
will return only the first one.You can just use the
View.setId(integer)
for this. In the XML, even though you're setting a String id, this gets converted into an integer. Due to this, you can use any (positive) Integer for theViews
you add programmatically.Credits to this answer.