I sometime get an Exception with the following message:
onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager
My full stacktrace (which is using CompositeAndroid as the parent fragment) :
Fatal Exception: java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.
at android.support.v4.app.Fragment.getLayoutInflater(Fragment.java:1151)
at com.pascalwelsch.compositeandroid.fragment.CompositeFragment.super_getLayoutInflater(CompositeFragment.java:1310)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$7.call(FragmentDelegate.java:204)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$7.call(FragmentDelegate.java:197)
at com.pascalwelsch.compositeandroid.fragment.FragmentPlugin.getLayoutInflater(FragmentPlugin.java:149)
at com.pascalwelsch.compositeandroid.fragment.FragmentPlugin.getLayoutInflater(FragmentPlugin.java:1269)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$7.call(FragmentDelegate.java:202)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$7.call(FragmentDelegate.java:197)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate.getLayoutInflater(FragmentDelegate.java:208)
at com.pascalwelsch.compositeandroid.fragment.CompositeFragment.getLayoutInflater(CompositeFragment.java:163)
at android.support.v4.app.Fragment.onGetLayoutInflater(Fragment.java:1101)
at com.pascalwelsch.compositeandroid.fragment.CompositeFragment.super_onGetLayoutInflater(CompositeFragment.java:1710)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$32.call(FragmentDelegate.java:769)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$32.call(FragmentDelegate.java:762)
at com.pascalwelsch.compositeandroid.fragment.FragmentPlugin.onGetLayoutInflater(FragmentPlugin.java:528)
at com.pascalwelsch.compositeandroid.fragment.FragmentPlugin.onGetLayoutInflater(FragmentPlugin.java:1456)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$32.call(FragmentDelegate.java:767)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate$32.call(FragmentDelegate.java:762)
at com.pascalwelsch.compositeandroid.fragment.FragmentDelegate.onGetLayoutInflater(FragmentDelegate.java:773)
at com.pascalwelsch.compositeandroid.fragment.CompositeFragment.onGetLayoutInflater(CompositeFragment.java:538)
at android.support.v4.app.Fragment.performGetLayoutInflater(Fragment.java:1132)
at android.support.v4.app.Fragment.getLayoutInflater(Fragment.java:1117)
at com.my.app.features.event.EventDetailFragment.attachHeader(EventDetailFragment.java:66)
...
We can see here that we first call the method getLayoutInflater()
at line 1117 and then the one at line 1151.
The first one is this one:
/**
* Returns the cached LayoutInflater used to inflate Views of this Fragment. If
* {@link #onGetLayoutInflater(Bundle)} has not been called {@link #onGetLayoutInflater(Bundle)}
* will be called with a {@code null} argument and that value will be cached.
* <p>
* The cached LayoutInflater will be replaced immediately prior to
* {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} and cleared immediately after
* {@link #onDetach()}.
*
* @return The LayoutInflater used to inflate Views of this Fragment.
*/
public final LayoutInflater getLayoutInflater() {
if (mLayoutInflater == null) {
return performGetLayoutInflater(null);
}
return mLayoutInflater;
}
And the second one is the one that throws the Exception
and that is marked as deprecated
:
/**
* Override {@link #onGetLayoutInflater(Bundle)} when you need to change the
* LayoutInflater or call {@link #getLayoutInflater()} when you want to
* retrieve the current LayoutInflater.
*
* @hide
* @deprecated Override {@link #onGetLayoutInflater(Bundle)} or call
* {@link #getLayoutInflater()} instead of this method.
*/
@Deprecated
@NonNull
@RestrictTo(LIBRARY_GROUP)
public LayoutInflater getLayoutInflater(@Nullable Bundle savedFragmentState) {
if (mHost == null) {
throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
+ "Fragment is attached to the FragmentManager.");
}
LayoutInflater result = mHost.onGetLayoutInflater();
getChildFragmentManager(); // Init if needed; use raw implementation below.
LayoutInflaterCompat.setFactory2(result, mChildFragmentManager.getLayoutInflaterFactory());
return result;
}
Is it normal that their is a call to a deprecated
function here?
And I think it shouldn't throw the Exception
because I'm checking for isAdded()
before calling getLayoutInflater()
:
private void init () {
if(isAdded()) {
attachHeader();
updateHeader();
}
}
private void attachHeader() {
headerBinding = DataBindingUtil.inflate(getLayoutInflater(), layout.event_detail_header,
binding.formsContainer, false);
binding.formsContainer.addView(headerBinding.getRoot(), 0);
}
You must first make sure that the Fragment is attached to the FragmentManager before the mHost.onGetLayoutInflater() use this to check the fragment is attached:
Activity activity = getActivity();
if (isAdded() && activity != null){ // Check the fragment status
LayoutInflater result = mHost.onGetLayoutInflater();
getChildFragmentManager(); // Init if needed; use raw implementation below.
LayoutInflaterCompat.setFactory2(result,
mChildFragmentManager.getLayoutInflaterFactory());
}else{
LayoutInflater result = null;
}
For future readers . In my case . I was using getLayoutInflater
in Fragment inside Api response and when I try to change the fragment , I was getting this error
Fatal Exception: java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.
So I Solved this issue by just Cancelling my Api call onDestroy
of fragment
@Override
public void onDestroy() {
super.onDestroy();
disposable.dispose(); //RxJava
}
Might be helpful to other user.
I feel this may still help somebody. Use of inflater from the onCreateView whilst binding views seems to solve this error - Fatal Exception: java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
render(inflater);
}
private void render(LayoutInflater inflater) {
GenericViewBinding genericViewBinding = GenericViewBinding .inflate(inflater);
}
In my case, this error occurred inside(Using Google firestore which has offline cache turned on by default which makes responses feel instantaneous) documentReference.addSnapshotListener(new EventListener() { } when I tried to inflate views when my fragment wasn't yet attached to the FragmentManager.
With all humility I write, please don't be bashful. I am just trying to help. Perhaps there is something I still don't understand. I would still love to hear from you. Thank you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With