Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the scope of android:id? [duplicate]

Tags:

android

Possible Duplicate:
Scope of R.id values

Could someone please clarify the scope of resource id's in Android? Recently I was making a custom title bar which contained a RelativeLayout called "header". I was invoking this title bar in the onCreate() handlers of each of my Activities thusly:

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_layout);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);  

One of my Activities had a TextView in its layout with the id of "header" and in that Activity's onCreate() I do a

TextView tv1 = (TextView)findViewById(R.id.header); 

. . . which blew up at runtime with ClassCastException, apparently because it thought I was trying to cast a RelativeLayout to a TextView. Changing the name of the RelativeLayout in the title bar fixed it.

But I don't really understand this. Are Android resource id's global? If so why wouldn't this collision be caught at build-time?

Note that this question has been asked before on SO: Scope of R.id values . . . Where the OP said "as far as I can tell" R.id's are global but my question is not a duplicate because neither of my questions is really addressed in that one.

like image 454
user316117 Avatar asked Aug 16 '12 13:08

user316117


People also ask

What is the use of ID in android?

android:id. Resource ID. A unique resource name for the element, which you can use to obtain a reference to the View from your application.

Can we change Android ID?

You'll have to fully format your device data to change your Android phone's device ID. As the device ID is generated when you first set up the device, resetting the phone will change the Android device ID automatically.

What is the benefit of using tag over ID in Android Studio?

Unlike IDs, tags are not used to identify views. Tags are essentially an extra piece of information that can be associated with a view.

What does findViewById return?

findViewById returns an instance of View , which is then cast to the target class. All good so far. To setup the view, findViewById constructs an AttributeSet from the parameters in the associated XML declaration which it passes to the constructor of View . We then cast the View instance to Button .


2 Answers

R.* values are global to their own type. So you can have a R.string and an R.id with the same name, but not two IDs with the same name. In your case, I feel that doing a build clean would have fixed your problem as well. For example, take a look at the R.java file contents:

    public static final class drawable {
    public static final int icon=0x7f020000;
    public static final int info=0x7f020001;
    public static final int menu=0x7f020002;
    public static final int splash1=0x7f020003;
}
public static final class id {
    public static final int ImageView02=0x7f070008;
    public static final int bestTimeTextView=0x7f070005;
    public static final int infoButton=0x7f070003;
    public static final int infoImageView=0x7f070000;
    public static final int levelSpinner=0x7f070002;
    public static final int menuImageView=0x7f070001;
    public static final int selectLevelTextView=0x7f070004;
    public static final int startButton=0x7f070006;
    public static final int timeTextView=0x7f070007;
}
public static final class layout {
    public static final int info=0x7f030000;
    public static final int menu=0x7f030001;
    public static final int splash=0x7f030002;
}
public static final class raw {
    public static final int down=0x7f040000;
    public static final int up=0x7f040001;
}
public static final class string {
    public static final int appname=0x7f060000;
    public static final int besttime=0x7f060002;
    public static final int help=0x7f060004;
    public static final int selectlevel=0x7f060001;
    public static final int start=0x7f060003;
}

Here I have the info name used in both drawable and layout parts, and the app functions perfectly. However, if I try adding two resources with the same ID, or two drawables with the same name, or two strings with the same name etc. it will not function properly.

like image 27
Raghav Sood Avatar answered Oct 10 '22 06:10

Raghav Sood


Are Android resource id's global?

They are "global" within an activity. The title bar is in the activity. The layout is in the activity. Widgets from both will be in the activity. Widgets with the same ID from both will be in the activity and will represent a point of conflict for findViewById() calls.

If so why wouldn't this collision be caught at build-time?

First, why would it? How is the build system supposed to know that you are are going to take res/layout/title_bar.xml and res/layout/whatever_the_heck_you_called_it.xml and use them both in the same activity?

Second, there is nothing wrong with having duplicate IDs. Your job, as a developer, is to call findViewById() on whatever will give you a unique result. For example, you could have done:

TextView tv1 = (TextView)(findViewById(android.R.id.content).findViewById(R.id.header));

and kept the duplicate IDs. Going the route you did, of having distinct IDs, is a better choice here for maintainability. But there will be plenty of cases where you will intentionally have duplicate IDs, such as every AdapterView you ever implement (e.g., ListView), as their contents will tend to have duplicate IDs (e.g., each row in the ListView is stamped out from the same row layout resource).

like image 151
CommonsWare Avatar answered Oct 10 '22 07:10

CommonsWare