Confusion regarding documentation for Android Inflator.

I am researching fragments from this link: http://developer.android.com/guide/components/fragments.html

There is a code snippet here:

public static class ExampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.example_fragment, container, false);
}

      

}

I was confused about the attachToRoot parameter, so I searched Stack Overflow for some help and found good answers for a similar problem. So my understanding is that if you set it to true, the fragment binds to the layout of the activity root and outputs its layoutparams from there. If false, it will just return the root of the inflated layout and act as a separate kind of fragment (getting layout parameters from passed in container).

I have now read further in the documentation regarding attachToRoot for the above example:

A boolean value indicating whether to attach the bloated layout to the ViewGroup (second parameter) during inflation. (In this case, this is incorrect, because the system is already inserting an inflated layout in the container passing true, will create a redundant group representation in the final layout.)

I don't get the last parenthesis statement that says it should be false because we are already inserting the layout into the container. What does it mean that we are already inserting into the container without attachToRoot as true? If true, how redundant view groups will be in the final layout. An example for developing this part would be of great help. Thank you.

+3


source to share


5 answers


I don't usually answer my own questions, but after doing a little more research on this, I thought that maybe it would help someone else. While Marcin's answer is correct, I'm just answering in a little more detail.

According to the code:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.example_fragment, container, false);
}

      

The second parameter container is a frameelayout with the id fragment_container, which it uses to add the fragment to the layout.

Now if we dive deeper into the inflating method of the LayoutInflater class, this is the code (I'm just highlighting the relevant parts of the code, not all of it):

// The view that would be returned from this method.
View result = root;

// Temp is the root view that was found in the xml.                     
final View temp = createViewFromTag(root, name, attrs, false);

      

First, it creates a temporary view from the provided root.

In case attachToRoot is true, it does the following:

if (root != null && attachToRoot) {
    root.addView(temp, params);
}

      

It adds the temporary view created above to the root view (i.e. container).



In case attachToRoot is false, it does the following:

if (root == null || !attachToRoot) {
   result = temp;   
}

      

As is quite obvious, in case attachToRoot is true, it simply returns root (fragment_container, that is, the activity id uses to place the fragment inside it.) After adding a temporary view to it (the root representation in example_fragment in this case)).

In case attachToRoot is false, it just returns the root of the fragment xml, that is, the container parameter is only used to get the layoutParams for the root view of the fragment (since it has no root, so it needs parameters from somewhere).

The problem if true arises in the above example because the return value is the root (fragment_container with added time view, and the fragment_container instance already has a parent by default.). Now, if you try to do a fragment transaction, you are trying to add a child fragment_container (which already has a parent to another xml (the frame you defined to add the fragment).

Due to this, Android throws the following exception:

if (child.getParent() != null) {
            throw new IllegalStateException("The specified child already has a parent. " + 
"You must call removeView() on the child parent first.");
    }

      

The problem with setting it to true and return is that the returned image already has a parent, so it cannot be used otherwise. Another way: you can create a separate view group inside onCreateView (maybe LinearLayout), set the parameter to true and return the view. Then it will work fine because there will be no existing parent in the view group.

This is my understanding of the above problem, maybe I am wrong, in which case I would like any Android expert to fix it.

+5


source


This means that in case the onCreateView()

returned View

will be bound to the view of the container anyway, so setting it in true

in yours onCreateView()

will add it twice to the container layout, which isn 'what you usually want. And setting the root view is not null and still attachToRoot

false, which allows the oversized view to get from the root, without adding.



+4


source


check it

View v =getLayoutInflater.inflate(R.layout.example_fragment, viewgroup);

      

and also this

View v =getLayoutInflater.inflate(R.layout.example_fragment, null);

      

now if you call this for the first scenario

Log.v("testing",String.valueOf(v.getParent() == null));

      

you get false

as output, but when you check what on the second line you get true

.

The simple understanding is to specify the parent (ViewGroup) to which it is attached, but if you add the last parameter, you say the inflator does not skip the attachment of the View, so your returned View has no parent, but if you specify null, who will it attach to? NOBODY, so the View returned has no parent, and also as you stated, it outputs layoutParameters for the view.

If you don't add the last parameter, the View will have its parent as an Activity View

and hence will be returned in your OncreateView which already has a parent before it is added, which will cause some Exceptions as a view to fail have different dads, and the Fragment will not be able to control the view itself.

if you add true return null from your oncreateView

+1


source


The view returned from the onCreateView () method of the fragment will be attached to the fragment container by the system. Thus, the third parameter of the inflate () method must be false in this case. If you set it to true it will be anchored to the root twice. Therefore, in this case, you must set it to false.

Inflate now inflates layout parameters from the second parameter of the inflate () method not from the third boolean parameter.

-2


source


ok from official android documentation Android documentation

What is a Fragment?

A Fragment represents a behavior or a piece of UI in an Activity. You can combine multiple fragments in a single activity to create a layered UI and reuse the fragment in multiple activities. You can think of a snippet as a modular activity section that has its own lifecycle, receives its own input events, and which you can add or remove at runtime (sort of like a "helper activity" that you can reuse across activities).

How do I use a snippet in action?

A fragment should always be inlined in an activity, and the life cycle of a fragment is directly dependent on the life cycle of the host. For example, when an activity is suspended, that is, all fragments in it, and when the activity is destroyed, so are all fragments. However, while the activity is in progress (it is in a resumed lifecycle state), you can manage each piece yourself, such as adding or removing them.

What is a fragment transaction

you can independently manipulate each fragment, for example add or remove them. When you do such a fragment transaction, you can also add it to the back stack, which is activity-driven - each entry in the previous stack in the activity represents a record of the fragment transaction that occurred. The back stack allows the user to undo the chunk transaction (go backward) by clicking the Back button.

How fragment and activity interact with each other

When you add a fragment as part of your activity layout, it lives in a ViewGroup within the activity hierarchy, and the fragment defines its own view layout. You can insert a fragment into your activity layout by declaring the fragment in the activity layout file as an element, or from your application code by adding it to an existing ViewGroup.

Fragment lifecycle methods onCreateView () OnCreate () OnPause ()

And your question

What does it mean that we already insert into the container without attachToRoot as true? If true, how would the final layout have redundant view groups

and here's answar suppose you have already added your activity layout, then you do not need to specify the last parameter in true.because every time you perform adding or removing a fragment, it is a fragment transaction. However, if you haven't added the snippet to your layout yet, you can set it to true.

read it in the doc

You can insert a fragment into the layout of your activity by declaring the fragment in the activity layout file as an element or application code by adding it to an existing ViewGroup. However, the fragment is not required to be part of the activity layout; you can also use a snippet without its own UI as an invisible worker for an activity.

the whole chunk transaction is added to the previous activity stack

-2


source







All Articles