Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain to me the magic behind FindViewById(1) or FindViewById(2)?

Tags:

android

[UPDATE] -- Just wanted to confirm to everyone that I agree it's ALWAYS a bad idea to use a hard coded number. My curiousity was when using the Maps API what is the 1, 2 constant value enumerated to. I would have felt more comfortable if I found something like R.id.my_current_location_view.

I see that code littered in this question and other questions. How do people know to use findViewById(1) etc? vs. findViewById(R.id.something);

Change position of Google Maps API's "My location" button

There seems to be some deep confusion in this question. I am wondering what the magic numbers findViewById(1) is.. If you click on the link you will see that no one has supplied the setId(1) value to the mapView but somehow people know to check the parent View and then findViewById(1) and findViewById(2)..

I asked the question there as well so the context wouldn't be lost but it seems no one can explain this.

like image 421
reidisaki Avatar asked Sep 17 '14 06:09

reidisaki


2 Answers

View ids are just positive, non-zero integers.

If you've set the view id in XML using the @+id/name syntax, the integer is generated in R.java and you need to refer to it as R.id.name in code.

If you've set the view id in code using setId(value), you can retrieve a view with that id from a hierarchy with findViewById(value) where the id value can well be a hardcoded positive, non-zero integer such as 1 or 2.

Generally when writing code, try to avoid using magic number constants like that.

like image 85
laalto Avatar answered Sep 28 '22 10:09

laalto


It is an overall bad idea to use this approach with hard coded ids especially if you are not the one who set them as they are subject to change.

However, to answer the question to figure out the id to use, one option is to do a lot of guess and check work using the Android Studio debugger to manually traverse the view hierarchy. That would likely take a lot of time so a much easier approach is to just use the Hierarchy Viewer which is available in both Android Studio and Eclipse.

Here is what the portion of the layout looks like that we are interested in. I cropped the full layout to show the relevant part.

enter image description here

We are now able to break down the following code:

View locationButton = ((View) mapView.findViewById(1).getParent()).findViewById(2);
  1. findViewById(1) will return the LinearLayout (Red Outline) since its id is 1.
  2. getParent() will return the RelativeLayout that is the parent of the LinearLayout (Blue Outline).
  3. findViewById(2) will find the child View of the RelativeLayout with the given id. Based on the image we see that the ImageView (Green Outline) we want has that id.

Based on this it is interesting to note that we could have just used mapView.findViewById(2) to get access to the ImageView directly and avoid the other calls.

Not sure if that was the case in previous versions but it works when using the current MapFragment. If it doesn't work on previous versions then that helps proves the point that this is a bad practice as it can change between releases.

like image 36
George Mulligan Avatar answered Sep 28 '22 10:09

George Mulligan