0

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 ?

Vipul
  • 35
  • 2
  • 7
  • you can change `LinearLayout ly1 = (LinearLayout)findViewById(R.id.linearlayout);` to `LinearLayout ly1 = (LinearLayout)view.findViewById(R.id.linearlayout);`, and see what happen – tesla1984 May 10 '13 at 09:32
  • 1
    inflat()ion must not return the same object, as it is supposed to CREATE a new view hierarchy, can be used for instance, to dynamically create fragments of views, like in list-adapters, where you have different data but want to populate a view of the same kind (list-item) – comeGetSome May 10 '13 at 09:34
  • check the comment by @comeGetSome. View view=getLayoutInflater().inflate(R.layout.activity_main,null); creates a new view object. – Raghunandan May 10 '13 at 10:37

6 Answers6

3

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.

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • will you comment on last line - why is ly1 and view object represent same address in this case ? – Vipul May 10 '13 at 10:34
  • the object already exists . It has been already created. you can think about findViewById like a key of a dictionary that returns a View object – Blackbelt May 10 '13 at 10:39
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.

Vipul
  • 35
  • 2
  • 7
1

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.

waqaslam
  • 67,549
  • 16
  • 165
  • 178
1

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.

fishtrees
  • 231
  • 3
  • 6
0

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.

Akryllax
  • 140
  • 1
  • 1
  • 6
0

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.

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • The identifier explanation is misleading. Different view objects can have the same id. The reason why the views are the same is that `findViewById()` is called on the same view hierarchy (namely, that set with `setContentView()`). – laalto May 10 '13 at 09:49
  • @Raghunandan I got this that inflate() will return a root view which in this case is LinearLayout. is this correct ? – Vipul May 10 '13 at 09:49
  • @laalto "Different view objects can have the same id " can you make this point clear. Will help me edit my answer accordingly – Raghunandan May 10 '13 at 09:52
  • @Raghunandan Nothing stops you from using the same `android:id` value more than once. Of course, `findViewById()` will only return the first id match in a hierarchy. – laalto May 10 '13 at 09:56
  • @laalto i get it same id in a different xml layout. yup you are right. I will edit my answer – Raghunandan May 10 '13 at 09:56