Вопрос

As a new-bee I am again in trouble understanding some basics of inflate().

here is my xml file -

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity" 
   android:id="@+id/linearlayout"
   android:orientation="vertical">

 <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="@string/hello_world"
   android:id="@+id/textview" />

</LinearLayout>

below is little basic code -

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    LinearLayout ly = (LinearLayout)findViewById(R.id.linearlayout);

    Log.i("System.out ","linear layout = " + ly);

    View view=getLayoutInflater().inflate(R.layout.activity_main,null);

    LinearLayout ly1 = (LinearLayout)findViewById(R.id.linearlayout);

    Log.i("System.out ","linear layout = " + view);
    Log.i("System.out ","linear layout = " + ly1);      
}

and the output:

05-10 14:30:33.446: I/System.out(26806): linear layout = android.widget.LinearLayout@41e28848

05-10 14:30:33.446: I/System.out(26806): linear layout = android.widget.LinearLayout@41e29740

05-10 14:30:33.446: I/System.out(26806): linear layout = android.widget.LinearLayout@41e28848

What I understand from the 1st and 3rd line of output that once we call setContentView() it does inflating and hence the view object will be in memory after call to this method. Therefore on calling findViewById(), it return same object of linearlayout View both time in code block. (ly isequalto ly1)

But, why the address of LinearLayout object in 2nd line of output different, linear layout = android.widget.LinearLayout@41e29740 ?

code responsible for this is -

View view=getLayoutInflater().inflate(R.layout.activity_main,null);

I thought this will return root View, which in this case is LinearLayout.

If R.layout.activity_main is already inflated and there is no change in Layout(neither addition or removal of any View/ViewGroup), then why address of object(view & ly1) does not match?

I tried this -

View view=getLayoutInflater().inflate(R.layout.activity_main,null);
setContentView(view); 
LinearLayout ly1 = (LinearLayout)findViewById(R.id.linearlayout); 
Log.i("System.out ","linear layout = " + view); 
Log.i("System.out ","linear layout = " + ly1);

and got this -

I/System.out(2603): linear layout = android.widget.LinearLayout@41e09e10

I/System.out(2603): linear layout = android.widget.LinearLayout@41e09e10

why is ly1 and view object represent same address in this case ?

Это было полезно?

Решение 2

This is what I tested -

            View view=getLayoutInflater().inflate(R.layout.activity_main,null);
    Log.i("System.out ","view = " + view + "id = "+ view.getId());
    setContentView(view);
    ly = (LinearLayout)findViewById(R.id.linearlayout);
    Log.i("System.out ","linear layout = " + ly + "id="+ly.getId());


    View view1=getLayoutInflater().inflate(R.layout.activity_main,null);
    Log.i("System.out ","view1 = " + view1 + "id = "+ view1.getId());
    setContentView(view1);
    ly = (LinearLayout)findViewById(R.id.linearlayout);
    Log.i("System.out ","linear layout = " + ly + "id="+ly.getId());

In both cases ly object has different address -

05-10 19:00:36.486: I/System.out(27233): view = android.widget.LinearLayout@41e0ef70id = 2131230720
05-10 19:00:36.731: I/System.out(27233): linear layout = android.widget.LinearLayout@41e0ef70id=2131230720

and

05-10 19:00:36.731: I/System.out(27233): view1 = android.widget.LinearLayout@41e2a5d0id = 2131230720
05-10 19:00:36.736: I/System.out(27233): linear layout = android.widget.LinearLayout@41e2a5d0id=2131230720

So, the above Output will Infer following conclusions :-

[1.] inflate() method will always return new root view object representing the xml hierarchy

[2.] On calling setContentView(view), 'view' will be associated with activity.

So, Now based on these relations , lets understand the output of question in this thread.

On calling - setContentView(R.layout.activity_main),

android system will do inflation. This means that it will create view objects for all elements in xml. Then these views are shown on screen. So, at this point view object in memory is LinearLayout@41e28848. As this represents root view(a Linear layout) hence on calling -

LinearLayout ly = (LinearLayout)findViewById(R.id.linearlayout)

ly will also points to same view LinearLayout@41e28848, which was created on calling setContentView(). So, ly=LinearLayout@41e28848.

This proves the first output line.

Moving on to View view=getLayoutInflater().inflate(R.layout.activity_main,null), this will again create a new view with some different address location (LinearLayout@41e29740).This is manual inflation of xml. But this view object is not associated with current activity as we have not called setContentView(view). Here view=LinearLayout@41e29740

next line - LinearLayout ly1 = (LinearLayout)findViewById(R.id.linearlayout), again gets the view which is active for current activity. This is (LinearLayout@41e28848) which is also the root view. This was actually created inside setContentView() method. Hence, ly1=LinearLayout@41e28848.

And, The next two print statements just print the object they represent i.e, view and ly1.

Thanks.

Другие советы

inflate() will always return a new View object. ly and ly1 are the same object . Why you are expecting differently?

From inflate doc

Inflate a new view hierarchy from the specified xml resource.

Your test procedure seems invalid. because you are not comparing the objects correctly. Perhaps your ly1 should be retrieved as below:

LinearLayout ly1 = (LinearLayout)view.findViewById(R.id.linearlayout);

and i believe it should return you the same log output as view.

Anyhow, inflating a view would return you a new object and there's no way that it is equal to the view defined under setContentView.

View inflate(int resource, ViewGroup root) will return the root View of the inflated hierarchy. If root was supplied, this is the root View; otherwise it is the root of the inflated XML file.

I think the second lines it's returning the View memory direction, not the Layout it self.

They are different things.

I think you are misunderstanding things. There's an Hierarchy, following this general scheme: "View -> ViewGroup -> Layout".

One thing is to refer to View (it's the Activity parent), that contains ViewGroup -> LayoutView, other thing is referring to LayoutView, that is child of View -> ViewGroup.

So, they are different things, stored apart, thought View will point LayoutView.

That's the explanation to line 2.

Lines 1 and 3 show the same direction because the are defined as the same object.

Since you have setContentView(R.layout.activity_main); and referring (R.id.linearlayout) in the same view hierarchy ly and ly1 initialized to the same LinearLayout. Thanks to @laalto for clarification

     View view=getLayoutInflater().inflate(R.layout.activity_main,null);

public View inflate (int resource, ViewGroup root)

Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error.

Parameters

   resource ID for an XML layout resource to load (e.g., R.layout.main_page)

   root Optional view to be the parent of the generated hierarchy.

Returns

The root View of the inflated hierarchy. If root was supplied, this is the root View; otherwise it is the root of the inflated XML file.

So getLayoutInflater().inflate(R.layout.activity_main,null); returns a new view object.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top