Android: View.setID(int id) programmatically - how to avoid ID conflicts?
According to View
documentation
The identifier does not have to be unique in this view's hierarchy. The identifier should be a positive number.
So you can use any positive integer you like, but in this case there can be some views with equivalent id's. If you want to search for some view in hierarchy calling to setTag
with some key objects may be handy.
How can I assign an ID to a view programmatically?
Android id
overview
An Android id
is an integer commonly used to identify views; this id
can be assigned via XML (when possible) and via code (programmatically.) The id
is most useful for getting references for XML-defined View
s generated by an Inflater
(such as by using setContentView
.)
Assign id
via XML
- Add an attribute of
android:id="@+id/
somename"
to your view. - When your application is built, the
android:id
will be assigned a uniqueint
for use in code. - Reference your
android:id
'sint
value in code using "R.id.
somename" (effectively a constant.) - this
int
can change from build to build so never copy an id fromgen/
package.name/R.java
, just use "R.id.
somename". - (Also, an
id
assigned to aPreference
in XML is not used when thePreference
generates itsView
.)
Assign id
via code (programmatically)
- Manually set
id
s usingsomeView.setId(
int);
- The
int
must be positive, but is otherwise arbitrary- it can be whatever you want (keep reading if this is frightful.) - For example, if creating and numbering several views representing items, you could use their item number.
Uniqueness of id
s
XML
-assignedid
s will be unique.- Code-assigned
id
s do not have to be unique - Code-assigned
id
s can (theoretically) conflict withXML
-assignedid
s. - These conflicting
id
s won't matter if queried correctly (keep reading).
When (and why) conflicting id
s don't matter
findViewById(int)
will iterate depth-first recursively through the view hierarchy from the View you specify and return the firstView
it finds with a matchingid
.- As long as there are no code-assigned
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
s
- In layout XML, define an empty
ViewGroup
withid
. - Such as a
LinearLayout
withandroid:id="@+id/placeholder"
. - Use code to populate the placeholder
ViewGroup
withView
s. - If you need or want, assign any
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 in onDestroy
. Apparently leaking the Activity
(hanging onto it after is is destroyed) is wasteful.. :)
Reserve an XML android:id
for use in code
API 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
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="reservedNamedId" type="id"/>
</resources>
Then once the ViewGroup or View has been created, you can attach the custom id
myViewGroup.setId(R.id.reservedNamedId);
Conflicting id
example
For clarity by way of obfuscating example, lets examine what happens when there is an id
conflict behind the scenes.
layout/mylayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
To simulate a conflict, lets say our latest build assigned R.id.placeholder
(@+id/placeholder
) an int
value of 12
..
Next, MyActivity.java defines some adds views programmatically (via code):
int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
TextView tv = new TextView(this.getApplicationContext());
// One new TextView will also be assigned an id==12:
tv.setId(i);
placeholder.addView(tv);
}
So placeholder
and one of our new TextView
s both have an id
of 12! But this isn't really a problem if we query placeholder's child views:
// Will return a generated TextView:
placeholder.findViewById(12);
// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12:
Activity.this.findViewById(12);
*Not so bad
android - set ID to the view programmatically
According to the API it's not forbidden or deprecated. Here is the best way of using it.
Create
res/values/ids.xml
and define<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="button1" />
<item type="id" name="button2" />
</resources>once you have that, you can than use
setId
button1.setId(R.id.button1);
button2.setId(R.id.button2);
Assign a view ID programmatically in Android
Found it:
view.setId(View.generateViewId());
Dynamically set id of a view
You can just use the View.setId(int)
for this. According to documentation id
need not to be unique in a tree heirarchy, you can use any (positive) Integer for the Views
you add programmatically.
Doc says
The identifier does not have to be unique in this view's hierarchy. The identifier should be a positive number.
if you want some other info attached with the View
you can tag objects to view using setTag()
, and look by findViewWithTag("obj");
see more about creating ids here https://stackoverflow.com/a/13241629/5235032
How to set id for each item in a view dynamically?
As @Rasoul Miri said, you can use View.generateViewId()
to set id for newly inserted views, and you should use a list to record them. And also you should set the id for those three items.
like these:
for the inserted view
<EditText
android:id="@+id/one_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number"/>
<EditText
android:id="@+id/two_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number"/>
<EditText
android:id="@+id/three_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number"/>
for the MainActivity
public ArrayList<InsertedView> list;
public void addView() {
View new_view = layoutInflater.inflate(R.layout.new_layout,insertPoint, false);
insertPoint.addView(new_view);
index_num++;
InsertedView insertedView = new InsertedView(View.generateViewId(), View.generateViewId(), View.generateViewId());
new_view.findViewById(R.id.one_view).setId(insertedView.firstId);
new_view.findViewById(R.id.two_view).setId(insertedView.secondId);
new_view.findViewById(R.id.three_view).setId(insertedView.thirdId);
list.add(insertedView);
}
class InsertedView {
public int firstId;
public int secondId;
public int thirdId;
public InsertedView(int one, int two, int three) {
firstId = one;
secondId = two;
thirdId = three;
}
}
How can I define an ID for my EditText field programmatically?
You can set it with TextView.setId(int id).
Try to see this question for more details.
Android: View.setID(int id) programmatically - how to avoid ID conflicts?
Related Topics
Android Asynctask Sending Callbacks to Ui
How to Change an Application Icon Programmatically in Android
How to Make Links in a Textview Clickable
Maintain/Save/Restore Scroll Position When Returning to a Listview
Communicating Between a Fragment and an Activity - Best Practices
Viewpager and Fragments - What's the Right Way to Store Fragment'S State
Android: Listview Elements With Multiple Clickable Buttons
Open Another Application from Your Own (Intent)
How Do We Use Runonuithread in Android
How to Detect When an Android App Goes to the Background and Come Back to the Foreground
Saving and Reading Bitmaps/Images from Internal Memory in Android
How to Draw a Path on a Map Using Kml File
Getting the Absolute File Path from Content Uri For Searched Images
How to Send Emails from My Android Application
How to Start My App When the Phone Starts on Android
Activity Has Leaked Window That Was Originally Added