I have a poll of ID's (ids.xml), and I assign id's for views I create dynamically. Now my question is pretty simple - assume I create a new view and assign it an id with setId() in conjuction with R.id.uniqueId. Later on, can I access the view with findViewById(R.id.uniqueId)?
If so, what could be the reason it returns null?
Here is a toy example: UPDATED
LinearLayout l = new LinearLayout(this);
l.setId(R.id.mId);
setContentView(l); //i see on screen the views added to 'l'
l = (LinearLayout) findViewById(R.id.mId); //it returns null :(
How come it does not register\map the assgined ID to the view it was assigned?
Does your desired view have a parent view that you could use to call parent.findViewById on? That may help narrow your problem down.
One thing I noticed that's missing from your brief example: you need to make sure you're adding the new LinearLayout to the view hierarchy before you will be able to find it with findViewById:
findViewById(R.id.parent).addView(l)
You can also use the hierarchy viewer to take a look and see if everything's being set up properly.
encountered this many times, try cleaning your project by making a clean, Also check findViewById() returns null for custom component in layout XML, not for other components
From what you have given us it appears that the view is never added to the Activity's view. This is necessary as findViewById uses the activity's view as a parent to find a child view with that Id.
If you are creating the view you can always create it as a member variable and refer to it that way if you are going to be adding it to a view at a later time. Please note that the view must be added after the id has been set.
Related
I have seen in Snackbars being passed this findViewById(android.R.id.content) argument. We can't pass getContext() method as it demands a View parameter. I have seen on internet that programmers pass this argument inside Snackbar, what does it really mean?
Also, since it asks a View argument can i pass like any view that i have in my xml file, for example, any imageview or any videoView. If i pass these as an arguments, would my code still work? If yes, isn't it a little unexplanatory in code about what's really going on?
what does it really mean?
It asks the hosting activity to find a widget whose ID is android.R.id.content. All activities have one of these, set up by the framework Activity implementation and its associated Window. It represents the main content area of the activity.
isn't it a little unexplanatory in code about what's really going on?
You are certainly welcome to add comments to your code to explain your choice.
The Snackbar documentation explains the role of the View:
Snackbar will try and find a parent view to hold Snackbar's view from the value given to view. Snackbar will walk up the view tree trying to find a suitable parent, which is defined as a CoordinatorLayout or the window decor's content view, whichever comes first.
Having a CoordinatorLayout in your view hierarchy allows Snackbar to enable certain features, such as swipe-to-dismiss and automatically moving of widgets.
With that in mind...
can i pass like any view that i have in my xml file, for example, any imageview or any videoView. If i pass these as an arguments, would my code still work?
Perhaps. It depends a bit on the UI of your app. If there is a particular CoordinatorLayout that you want to use with the Snackbar, pass it (or a child) to make(). Otherwise, any widget should work.
I know that we need to place setContentView() in the onCreate() method before initializing any view otherwise it will throw a null pointer exception.
But what is the reason for it?Is the setContentView() similar to the inflate() method?
before initializing any view
I do not know for certain what you mean by "initializing any view". Given the rest of your question, I am going to interpret this as meaning "call findViewById() on the activity".
You need to call setContentView() before calling findViewById(), because otherwise there are no widgets to find.
Is the setContentView() similar to the inflate() method?
setContentView() will use a LayoutInflater and inflate() under the covers, if you pass a layout resource ID into the setContentView() method.
If no content View is set then from where you will reference the views like EditText,TextView,ListVIew and all other components which you have used in your layout.
It is like you have items in your bucket and its cover is locked for safety, you came in house without bucket and forgot it in the car and your mom asked you to put items 1 by 1 on Kitchen counter , but you don't have bucket?? so first you will get bucket then you will take out items from it.
Simply first you have to have a Container in your activity so that you can reference its items by using their ID which are assigned in layout xml.
Hope it is clear to you.!
Ok. Agree with #CommonsWare. In some details, let say if you have some views defined in your xml layout file and you want to use those views in you activity, so in this case you have to call setContentView(<R.layout.xml_layout_name>) and after that to inititlalize view using findViewById(R.id.<view_name>) with resource name as your xml layout defined name.
Ok but why we have to call setContentView() ?
So when you call setContentView() application activity means android nutshell will render views and prepare view hierarchy for your activity from layout file. Just remember you have defined views in layout using xml file and you are using those views in Java code, so for that all works to preparing views for you will do setContentView() that's why when you call findViewById() without setContentView() then your application can not find views from view hierarchy and it will throw NullPointerException.
setContentView() similar to the inflate() method ?
Some how, because both are doing the same thing, rendering views from given xml layout files but scope of works is different. setContentView() provides views throughout your activity scope while inflate() will only gives you a view from the layout file, that's why whenever you have used inflate() you have to always use reference of return view to call findViewById() like
pseudo code only for your understanding,
View view = infalter.inflate(<R.layout.<file_name>>);
TextView mextView = view.findViewById(R.id.textView);
And yes, setContentView() uses the same inflater.inflate() method too.
And when setContentView() and inflate() not required?
If you are creating dynamically views, in java code then you don't have to required call either setContentView() or inflate().
Note: In old android version when you create a dynamically views using java code and you pass it to some ListView's header or footer it won't work. For this views must be inflated before set to the ListView.
We are creating an app with two main views: sView and sViewSettings. If the Android Back button is pressed we want an if statment to check if the current view is set to sView settings, if it is then call the sView.
Already have a listener setup for the back button just need it to call the if statement to check the current view.
Have already tried
if (this.findViewById(android.R.id.content) == sViewSettings)
Any ideas on this?
Thank you for Reading,
Travis
The view with id android.R.id.content is a FrameLayout holding your content view. Try this:
ViewGroup contentFrame = (ViewGroup) findViewById(android.R.id.content);
if (contentFrame.getChild(0) == sViewSettings) { ... }
However, I suggest a slightly different approach: use a ViewSwitcher (or any kind of ViewAnimator) to flip between the two main views and keep track in your code of which one is on display.
EDIT: If you want to keep your layouts loaded separately, you can assign an id (the same one) to the root view of each layout and then retrieve the content view directly using findViewById.
1) Why, when I create my custom compound view from Java code it is wrapped in another view which creates another level of view hierarchy? If I use the <include> tag in the XML to create the view, this does not happened. (see the attached image from hierarchy manager). Any reason for that?
2) The image shows (the part where the view is created by <include> tag) another interesting behavior – that it is easily possible to have the views with the same android:id on the same hierarchy level. When the findByViewId() method is used then, the first view reference is returned.
Any reason for that?
Because that's the way you wrote the code If you do not want that behavior, fix your code.
that it is easily possible to have the views with the same android:id on the same hierarchy level
Of course. You see this all the time with subclasses of AdapterView, such as ListView.
In my app I have 3 radiobuttons on top of the view. When i choose one the 'body' underneath that changes to the XML-view i defined.
(If you want more information + pics, I asked a question about this earlier: Dynamically change view inside view in Android)
Now i want to call and change the text of the buttons and edittext's from the different views.
When I do btnAutopech = (Button) findViewById(R.id.btnAutopech); it's gives an NullPointerException.
How can I do this?
Try this.......
LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout ll= new LinearLayout(context);
ll=(LinearLayout)layoutInflater.inflate(R.layout.gegevens_verzekeringen, ll);
btnAutopech = (Button) ll.findViewById(R.id.btnAutopech);
Thanks.........
Depends on how you solved the last question you linked to. If your inflating new views into the area you want to change then you won't be able to retreive a reference to them using finViewById. I.e. they don't actually exist.
When you re-display your view, within which you want to display text based, on your other views outcome, you would have to re-assign the text when you re-attach/display your view. You could then assign text from a member variable of the class, or perhaps from sharedPreferences or a contentProvider.
EIther way, this sort of all depends on how you've solved the issue of your original question and when you attach/remove your views.
To summerise:
It looks like your removing your other views when you visit other views, so store your data in a member variable that persists.
attach view A
got to view B
Click button or something in view B and update member variable used by view A
Go to view A (Removing view B and attaching view A)
set text on view A from member variable (updated as a result of clicking button in view B for example)