Activity.setContentView, View.setContentView? - android

I noticed that the Activity class has a setContentView method where an xml resource file can be loaded. I wanted to do the same thing with a class that inherits ultimately from View. This seemed to be a dead end because the setContentView method does not exist for the View class.
This leads to a couple of questions:
1) Is it possible for View's to load layouts created in the Visual Layout Editor?
2) If not, why? It seems like not allowing users to load an xml layout directly into a View is a limitation. I expect that there is a reason why the setContentView method (or a method similar) is not provided in the API.
Thanks in advance!

I think that LayoutInflator is what you are looking for http://developer.android.com/reference/android/view/LayoutInflater.html
And here is a code sample:
View view = (View)inflater.inflate(R.layout.abc, null);
view_group.add(view);

Related

Confusion regarding android app development

I was following an android development course and the instructor created an layout file named activity_youtube.xml and also gave the id to the layout as activity_youtube, later in the .java file the code he wrote was
setContentView(R.layout.activity_youtube)
ConstraintLayout constraintLayout = findViewById(R.id.activity_youtube)
I am really confused between this naming convention.
What are we refering to when we call R.layout.activity_youtube and what are we refering to when we call R.id.activity_youtube
When you are calling R.layout.activity_youtube you are referring to the layout xml file, so to everything that's inside.
While when calling R.id.activity_youtube you are referring to a specific component inside that file (a layout, a Button, a textView... ) that has the id property assigned to that name.
I will admit that it might be a little misleading calling the layout. xml file and its layout component the same.
R is a public final class in Android which extends Object class. It is purely there as a mechanism to allow you to easily reference the contents of your res hierarchy from your code. As such, you cannot create sub-hierarchies.
R.id is a nested class file created in android programming its also auto-generated file. It is used to refer to a UI component. Let us suppose you have two buttons in your UI(R.laoyout.your_layout_name) you can distinguish them and decide which action to be performed on the click of each button by using R.id.button1 and R.id.button2. These buttons lie in the layout file which you have used in the activity using R.layout.
setContentView() sets the View to be displayed as the main content view. The method is overloaded, so you can either pass an object of View class (or it's a subclass, such as LinearLayout, TextView, etc.), or you can provide the XML layout resource by using R.layout.your_layoutname.xml.
Thus, R.layout. references any layout resource you have created, usually in /res/layout. So if you created an activity layout called activity_main.xml, you can then use the reference in R.layout.activity_main to access it.

Is there a way for a view to know when it's fully inflated?

In iOS, when "inflating" a view from a nib file (the iOS equivalent of an Android layout.xml file), the view's 'awakeFromNib' method is called. It's only called one time, unlike measure, etc.
Is there an equivalent of awakeFromNib in Android?
Our need is to be able to assign child views loaded from the layout to member variables on the View subclass. Yes, we can do this externally, but we're trying to make the views self-manage its own members.
Try overriding onFinishInflate().

Reason for NullPointerException if setContentView() is not used

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.

View within View (Android)

So I can pass a custom View to the setContentView() and it fills the users screen by default(right?), but if I define a TextField within my custom views constructor it won't display. Even if I change my custom View to a custom ViewGroup and use its addView() method.
So what am I missing here?
Also, whats the equivalent of System.out.println() in android to get some feedback?
for print statements, used Log.d("Name of the filter", "Text to be printed here"). Also, why aren't you defining your view in an XML file and adding the textview inside there? it is usually not a good idea to use addview because it makes laying things out more difficult (not as many options for location and size, etc.)

How can I allow multiple activities to share the same inflated "included" view?

I see this question here, and it makes me wonder if what I'm asking isn't really possible:
How to share a view across various activities
Basically, I have a common footer view that I'm inflating (including) in all of my views. However, it uses the same repetitive code to do that. My thought was to create a parent activity class to do this, but it doesn't seem correct to have one activity render the view of another. So should I just create a utility class of some sort, or is there a better way?
You can include other layout XML files directly in another layout file. So whenever you set content to a layout file, along comes your footer for the ride.
If your footer needs code to drive it, just create a custom class for it along with the layout file. Then perhaps during instantiation you can drive the code that needs to execute.
This is a blog of how to do it.
include is very useful while reusing View components.
But remember, if any problem occurs while using include tag, wrap the included view by an arbitrary layout.
If I understand your question, another way of having multiple Activities use the same View instance is by doing something like creating your own Application class (it's seriously easy).
MyApplication extends Application ...
#Override
public void onCreate(), onConfigurationChanged(), onLowMemory(), onTerminate(), getIstance().
As there is only a single intance of "Application" that is statically available it makes it a good place to store and share various objects that need to be passed around.

Categories

Resources