I read the answer on Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified? and wanted to make sure i understood what attach to root does.
Basically if you do
inflater.inflate(int idOfLayoutFile, ViewGroup parent, boolean AttachToRoot)
and lets say parent is not null
From what I got out of that answer was that attach to root just affects what the return type is of the inflate method. That is if attachToRoot is true, method will return parent, and if it is false, the method will return the root view of the XML file as specified by the resource id. Do I have the right idea here or am I missing something?
No, something is missed!
When you pass true as 'attach to root', inflater will inflate specified layout (represented by its ID) and then attach it to root of parent and finally return the parent
But when you left 'attach to root' to false. the parent hierarchy won't changed and only inflated layout will be returned.
Yes you are correct :: In short terms
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(
R.layout.your_layout, null);
return view;
}
Now as per above code view reference will hold the root element for
the layout your_layout
You can use this view reference to find all the child views of this
parent layout
You can refer the child views here even though the activity is not
created yet
If you read this you'll find that you should NOT pass null as value of root ViewGroup if you do not want to attach it but rather should use the 3-parameter version of inflater.inflate with 3rd parameter (attach to root) set to false. I.e., do this:
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View view = LayoutInflater.from(getActivity()).inflate
(
R.layout.your_layout,
container,
false
);
return view;
}
And from the docs:
root Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
And this is really good.
Related
Let's say I have a view object:
View elem = getLayoutInflater().inflate(R.layout.element_activity, null);
I do some editing to this view dynamically and need to pass it as an argument to a function that takes a resource (ex. R.layout.element_activity). Is it possible to pass this edited view into that function?
Thanks in advance.
Is it possible to pass this edited view into that function?
No, there is no overloaded version of inflate method in LayoutInflater class, which accepts the View as parameter.
View inflateinflate(int resource, ViewGroup root)
View inflate(XmlPullParser parser, ViewGroup root)
View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
View inflate(int resource, ViewGroup root, boolean attachToRoot)
Note: if you have the view instance then simply use it, no need to inflate new view from resources or anything
What is difference between inflating layout with false attachtoroot and true attachtoroot(boolean)?
Here is a code:
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_3, container, false);
and:
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_3, container, true);
The root and attachToRoot parameters work together.
If you tell inflate() to attach the inflated View to the root View, then the layout that you inflate will be added as a child to the root.
Here is a simplification of what the inflate() method does:
public View inflate (int resource, ViewGroup root, boolean attachToRoot) {
View inflatedView = inflate(resource); // Inflate the desired view
if (attachToRoot) {
root.addView(inflatedView);
}
}
This is useful if you are inflating Views that are going to be attached to a parent view eventually anyway, for example if you are inflating a number of Views with the same layout to dynamically populate a ListView.
When attachToRoot = false :
- the returned rootView will be the top ViewGroup from R.layout.fragment_screen_3 and rootView still doesn't add into container yet.(Can be added to another view group parent)
- It'll raise an Exception if the top tag in R.layout.fragment_screen_3 is <merge>.
When attachToRoot = true :
- the return rootView will be the container.
- the content of R.layout.fragment_screen_3 will be added as a part of container (like when you use attachToRoot = false, then call container.addView(rootView);
- can use with <merge> tag in R.layout.fragment_screen_3
When to use which?
Use attachToRoot = true when you want to add the childView to
parent right now.
Use attachToRoot = false when you want to add the childView to parent
at later point.
You should also use attachToRoot = false When you are not
responsible for adding the childView.
Eg. While adding Fragments
public View onCreateView(LayoutInflater inflater,ViewGroup parent,Bundle bundle)
{
super.onCreateView(inflater,parent,bundle);
View view = inflater.inflate(R.layout.image_fragment,parent,false);
.....
return view;
}
If you pass third parameter as true you will get IllegalStateException because of this guy.
getSupportFragmentManager()
.beginTransaction()
.add(parent, childFragment)
.commit();
Since you have already added the child fragment in onCreateView() by mistake. Calling add(parent, childFragment) will throw IllegalStateException because the child view was already added.
Here you are not responsible for adding childView, FragmentManager is responsible. So always pass false in this case.
Is it possible/recommanded to let different fragments inherit from each other in Android?
What would be the best way to initialize things that are already initialized in the superclass and add things to it ? (-> for example like the normal subclasses that use super() in their constructor and then initializing other objects )
I looked on the internet but i didn't found much information on this.
I know that it's possible to do return super.onCreateView() but you can't initialize other objects/views after that....
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView()???
//initialize other objects here
//you have to return a view ...
}
Yes, it is allowed. Why not? For example, if you have a number of Fragments, that display lists, you could put all common methods in FragmentList, and then inherit other fragments, adding only unique methods or overriding the ones from super if needed.
But overriding onCreateView() could raise difficulties in layouts handling. In my recent project I instead created a method inflateFragment() in the super class as follows:
BaseFragment.java
protected View inflateFragment(int resId, LayoutInflater inflater, ViewGroup container) {
View view = inflater.inflate(resId, container, false);
FrameLayout layout = (FrameLayout)view.findViewById(R.id.fragment_layout);
/*
* Inflate shared layouts here
*/
. . .
setHasOptionsMenu(true);
return view;
}
Because of the structure, each and every fragment layout resource is wrapped in a FrameLayout with id = fragment_layout. But you're free to use LinearLayout or whatever parent view you need.
And then in inherited fragments:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflateFragment(R.layout.my_fragment, inflater, container);
/*
* Do things related to this fragment
*/
...
return view;
}
This code is from https://developers.facebook.com/docs/android/login-with-facebook/v2.1.
Code:
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
return view;
}
Basically this code is to create the ui layout for the fragment button that will be injected into the main activity layout. My question is for the parameter attachtoroot, why is it false in this case? I know the onCreateView method sets up and returns a view containing the fragment's user interface and gives this view to the hosting activity so the host activity can install the view in its view hierarchy(notes I have). Going off the answer I got here Clarification about layout inflater -attach to root?, attachtoroot being true will attach the fragment layout to its parent layout, in this case main activity layout. Can anyone clarify why its false?
Using Fragments in android
I am trying to learn fragments
public class FirstFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.first_fragment,
container, false);
Button nextButton = (Button) view.findViewById(R.id.button_first);
nextButton.setOnClickListener(this);
return view;
}
}
In the line ::
View view = inflater.inflate(R.layout.first_fragment,container, false);
why are we giving false
what is this about container
Can someone explain in laymen terms, in simplest terms
Please go easy on answers ... i am a newbie
You can check it all in the documentation: Android Developer Reference
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
And the parameters you're asking about are:
root Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
attachToRoot Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.
Also, mind the return value as it depends on those parameters:
Returns
The root View of the inflated hierarchy. If root was supplied and attachToRoot is true, this is root; otherwise it is the root of the inflated XML file.