Domanda

I want deeper understanding of how Android works, and I need someone to explain how Views are actually working "under the hood".

In normal procedure we would inflate (is this the correct word?) views from XML in onCreate method of our extended Activity with method "setContentView(R.layout.ourlayoutfile)". Then we would find Views from that XML.

Quick example: If we need to find a button we need first call "setContentVIew()" and then, "findViewById" on our button. Then we can work with this button / view respectively.

I've started to play with LayoutInflater recently, because I came to the point which I couldn't help myself with "setContentView" method, and on my surprise I found out that my Android knowledge sucks very good. I couldn't even manage LayoutInflater to work. I was embarassed.

After a day I manage to inflate views with LayoutInflater. Actually it's not very hard, I was very close already from the start BUT there was one parameter which I didn't know what to pass in. Please look at this code: ( This is all happening in onCreate method of Activity )

View v = getLayoutInflater().inflate(R.layout.activity_main, (ViewGroup) getWindow().getDecorView());



    final Button b = (Button) v.findViewById(R.id.button1);
    final TextView tv = (TextView) v.findViewById(R.id.textView1);

    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {


            tv.setText("Just random text");
        }
    });

}

This code works fine, but the problem I was facing was actually this line of code:

getLayoutInflater().inflate(R.layout.activity_main, null);

I was always passing "null" parameter, and of course it didn't worked. Even tho in documentation it says that this parameter is OPTIONAL! ( Why ? , if it's needed) ?

I've made simple layout. Please look at it and how it looks with HiearchyViewer:

enter image description here

What is the second parameter in picture above, and why do we need it in there? Is maybe connecting my layout ( R.layout.activity_main ), with View provided by Android ( First view from left to right - parent view ). If that's the case, WHY doesn't android connect these two automatically?!

enter image description here

If there is also something useful I need to know regarding Views I will be very glad if someone could tell me ( or post a link ). Additionally would be nice if I could get some links to some websites of How Views work.. etc. Useful stuff.

If someone will downvote my question, please explain. Thank you very much everyone!

È stato utile?

Soluzione

As you might already know by now that every visible component in Android is a View. That includes Button, Spinner, TextView, EditText and the likes. You are also right about the way we access the Views that are defined in a xml file in our program, by inflating it and then finding the view by using it's id. The usual way to do this is by using setContentView() method.

But there is this pretty useful class called LayoutInflater that can be used to "inflate" a layout. Now consider the scenario where you have a ListView in your xml file that you inflated using setContentView() method. In this ListView you want the items to contain an ImageView and a TextView. The default list-item just have a TextView. So you decided to write up a custom adapter in which you'll be using a new listitems.xml in which you have a TextView and ImageView defined. Now you can't use setContentView() in this case as it will inflate this layout on the whole activity which obviously you don't want. So you use LayoutInflater in this case to help you out. You temporarily inflate a layout using inflate() method. The first argument takes the layout file which is needed to be inflated. The second argument is the root of this newly inflated layout. In our case it can be set to the ListView in which the layout is going to be actually inflated.

So when you use this inflate() method, a View is returned containing the views that are inside the inflated xml. Now with this returned view instance you can call findViewById() to get the contained views to set text to the TextView and image source to the ImageView.

More often than not, you'll end up using LayoutInflater as it's use cases are wider than the scope of this discussion.

Altri suggerimenti

Please look at this code

That is a rather unusual use of LayoutInflater. In particular, I would expect it to seriously mess up your use of action bars and related "chrome" outside the main content area.

I was always passing "null" parameter, and of course it didn't worked

null is a perfectly reasonable value for the second parameter of the two-parameter inflate() method. Doing so implies that you will add the inflated View hierarchy to your UI yourself at some point (e.g., via a call to addView() on the desired parent).

Even tho in documentation it says that this parameter is OPTIONAL!

That is because the parameter is optional.

( Why ? , if it's needed) ?

It is not needed.

What is the second parameter in picture above

It is the PhoneWindow$DecorView.

and why do we need it in there?

You do not need it in there, and your choice of the getDecorView() is atypical, to say the least.

Is maybe connecting my layout ( R.layout.activity_main ), with View provided by Android ( First view from left to right - parent view ).

Yes. Quoting the documentation, the second parameter to the two-parameter inflate() is the "Optional view to be the parent of the generated hierarchy".

If that's the case, WHY doesn't android connect these two automatically?!

Why would it? After all, there are five total views beyond the three that you inflated, as you can tell by counting the bubbles in your Hierarchy View screenshot. Why would it randomly choose that one, rather than one of the others? Furthermore, for all Android knows, the parent you want to use does not even exist yet, because you will be creating it in a later step.

So, either pass in your desired parent as the second parameter to inflate() (in which case, Android will add the inflated layout as children to that parent), or pass in null (in which case, adding the child to the parent is your job to do yourself at some suitable point).

Note that having Android not automatically add the child to the parent is the norm for the two primary uses of LayoutInflater:

  • for children of an AdapterView (e.g., rows in a ListView)
  • for the contents of fragments (i.e., inflated in onCreateView())
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top