How does android use R.id.id_name to find views after inflating the XML?
1.Suppose I have two XML's with one button each with same id.
2.I have inflated them and converted them into views
3.In R.id class only one int will be created for both the buttons.
How does android differentiate these buttons with same id Using same Resource name(R.id.id_name) .
The ID is not a unique reference.
However, in practice, you differentiate by using the parent view.
If we consider that 'this' is an Activity, set up with a layout that contains your buttons, then:
Button button = (Button) this.findViewById( R.id.id_name );
will return the first one it finds in the layout (I think - not sure the actual behaviour is defined).
However what you might do is call findViewById on some parent view that contains only one such instance with that ID.
LinearLayout okParent = (LinearLayout) this.findViewById( R.id.okLayout );
LinearLayout cancelParent = (LinearLayout) this.findViewById( R.id.cancelLayout );
Button okButton = (Button) okParent.findViewById( R.id.id_name );
Button cancelButton = (Button) cancelParent.findViewById( R.id.id_name );
Conceptually, this is a sort of path based lookup. You should be careful to design your layouts such that this is possible.
Android takes the easy road: IDs are not application-wide unique, but layout-wide unique.
The value of R.id.foo is the same across two different layouts holding a control with foo id. Since they are not competing for uniqueness, it doesn't matter.
It knows which View should it use, because it looks for View with this specific id in a XML file that is currently set as content view (or is inflated).
Related
I have the following hierarchy:
Do you have any idea how to interact with the second ToggleButton - The one that exists under the second LinearLayout(8)?
Please note that the 2 ToggleButtons have the same id/class. The only difference is the text on the buttons.
Thank you for your help.
You can assign a different tag to each ToggleButton so that you can use findViewWithTag()
to access the buttons separately.
It is best to fetch the enclosing element first:
LinearLayout enclosingLayout = (LinearLayout) view.findViewById(R.id.enclosungElement1);
Then find the child view also by using findViewById:
ToggleButton button = (ToggleButton) enclosingLayout.findViewById(R.id.yourToggleButton);
If i follow it correct..
You can use SetTag for the views and find later with fiViewByTag(Tag of the view).
OR
Just find the parent linear layout like findViewById(LinearLayout(8)).
and get the chield as parent.findViewById(toggle Button.)
So I have a layout that gets added to the main layout every time the user presses a button. I got that working fine, but that layout happens to consist of several EditTexts. What would be the best way to get the text from the EditText? I only have the id of the layout itself, not the EditTexts inside the layout.
I thought of just adding EditTexts dynamically one by one, but is there a more efficient way of doing it? I'd much rather just inflate an xml layout every the button is clicked.
I assume you're adding new views by inflating them and then adding them to the main view similar to below.
LinearLayout newView = (LinearLayout)this.getLayoutInflater().inflate(R.layout.my_layout, null);
LinearLayout mainView = (LinearLayout)this.findViewById(R.id.mainLayout);
mainView.addView(newView);
You can use findViewById() on the newView to access each EditText as required.
EditText editText = (EditText) newView.findViewById(R.id.myButton);
String text = editText.getText().toString();
Since it's a fixed layout you inflate from a particular XML file, you can also use getChildAt(int index) to find a particular view of the ViewGroup.
I have multiple XML files that need to be used by one Activity for its view, the Activity will load an XML file from the name passed to it when its created. These XML files will contain a set of UI elements such as buttons that will have a standardised name (ie UpBtn, DownBtn).
The views will be different (containing different button names) but I want to be able to check if a button of a specific name exists within the XML so that I can perform a specific action in the Activity.
Is there a way of doing this or will I have to resort to having an Activity per XML?
In your xml, provide your views with an unique id
<Button
android:id="#+id/upBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
In your activity, provided that you have already called setContentView() with one of the XML files, you can call findViewById() to find a particular view by its id:
Button upBtnView = (Button) findViewById(R.id.upBtn);
If this view is present in the xml you provided, upBtnView will be the button you want; otherwise, upBtnView will be null, and you will know that it is not there in your layout.
You can use findViewById( id ) and if it returns null then the id you specified doesn't exist.
Short Story:
I have a layout "layout.xml", which gets replaced by another layout "success.xml" after a successful web request. Both layouts have an ImageView that provides the backgrounds to the layouts. These 2 backgrounds both need to be the same, and both are dependent on a user preference.
Longer Story: This all happens in a Fragmnet with an AsyncTask replacing the contentView with "success.xml" in onPostExecute after the web request. This happens as follows:
View view = getView();
view = null;
view = View.inflate(context, R.layout.success, null);
What I tried to do is give both ImageViews the following android:id="#+id/background_image" and then call
ImageView background = (ImageView)view.findViewById(R.id.background_image);
background.setImageResource(R.drawable.bg1);
This background-setting works for the initial view (layout.xml), but on trying to change to "success.xml", I get a NullPointException because background is null.
I've checked and the View's id is set to -1 while the original view's background_image id is set to something sensible and valid.
I've also tried setting the second view's background id like this: android:id="#id/background_image", i.e. without the '+', but still no luck.
The added complication is that it's not just 2 layouts, but about 5 that I need to do this for, so it would be really handy to recycle view id's.
Any help would be greatly appreciated.
Your code for replacing the fragment's view will not do what you want, the original view will remain the same as you change only a reference to that view and not the actual object.
To replace the view of the fragment with the new layout you could have another ViewGroup(for example a FrameLayout) in the basic layout (layout.xml) wrapping your current content(don't forget to give it an id) of layouts.xml(as I understand this is the basic layout). Then, when it's time to replace the layout you could simply do:
// remove the current content
((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)).removeAllViews();
// add the new content
View.inflate(context, R.layout.success, ((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)));
You could avoid adding an extra layout if, by any chance, all your five layouts have the same type for the root view(like a LinearLayout etc). In this case you would use the same code as above but you'll modify the other layouts file to use a merge tag. Also, you'll be looking for the id of the root in the layout.xml layout into which you'll add the content of the other files.
Then you could have the same ids, but you'll have to reinitialize any reference to the views(meaning that you'll have to search for the view again if you store a reference to the view(like a Button field in the fragment class)).
For an Android App, I'm using a GridView and extending BaseAdapter to organize its contents. For the function getView that I override in my extended BaseAdapter class, I create a LinearLayout, which I attach an ImageView and 3 TextViews to. Now, I need to implement convertView, but because I created my views programmatically, I didn't think I can use findViewById to find these child views to change their properties (like text and bitmaps).
I had the idea of assigning a unique ID pertaining to different types of views for each one when I create them (example: give my name textview the id of 1, description textview the id of 2, etc), but I was not sure if the ids have to be unique among every view, whether they're the same kind of view or not.
Ultimately, how do I find a child view that's part of a linearlayout view which were all created programmatically?
You can get children of LinearLayout via getChildAt() but it's hard to distinguish what child exactly you get.
I think assigning IDs is better way. You can assign IDs to your views and later get views via findViewById(). IDs doesn't need to be unique for each LinearLayout.
Something like this:
// Give more sensible names to ID's
int IMAGEVIEW_ID = 0;
int TEXTVIEW1_ID = 1;
int TEXTVIEW2_ID = 2;
int TEXTVIEW3_ID = 3;
imageView.setId(IMAGEVIEW_ID);
textView1.setId(TEXTVIEW1_ID);
textView2.setId(TEXTVIEW2_ID);
textView3.setId(TEXTVIEW3_ID);
...
// somewhere later
ImageView imageView = (ImageView) convertView.findViewById(IMAGEVIEW_ID);