41

Below is my code. What i am trying to achieve is that i am displaying viewholder inside my Recycler view. Inside view pager i am displaying one fragment and on swipe left i am displaying another fragment. But when i run the app. App is crashing.Don't know where i am going wrong. I think it's some where in fragment's concept. Please do help me

 @Override
 public void onBindViewHolder(ManageCustomerViewHolder holder, int position) 
 {
     holder.viewPager.setAdapter(new MyPageAdapter(fragmentManager, fragments));
 }

 private List<Fragment> getFragments() 
 {
     List<Fragment> fList = new ArrayList<Fragment>();
     fList.add(MyFragment.newInstance("Fragment 1"));
     fList.add(Myfragment1.newInstance("Fragment 2"));

     return fList;
 }

 public class ManageCustomerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
 {
    ViewPager viewPager;
    viewPager = (ViewPager) itemView.findViewById(R.id.viewpager);

    itemView.setOnClickListener(this);
 }

This is what the error is :

java.lang.IllegalStateException: Fragment has not been attached yet.

Newtron Labs
  • 809
  • 1
  • 5
  • 17
Srikanth G
  • 461
  • 1
  • 4
  • 11

6 Answers6

59

I was facing the same issue in my app.

Stack Trace:

java.lang.IllegalStateException: Fragment has not been attached yet. android.support.v4.app.Fragment.instantiateChildFragmentManager(Fragment.java:2154)
android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:704)

The app was crashing at this line:

function performSomeActionInChildFragments() {
    List<Fragment> fragments = getChildFragmentManager().getFragments();
    ...
}

This happens when the fragment is no longer attached to its parent activity/fragment. So a simple isAdded() check should resolve this issue for you.

Fix:

function performSomeActionInChildFragments() {
    if (!isAdded()) return;
    List<Fragment> fragments = getChildFragmentManager().getFragments();
    ...
}

From documentation:

isAdded() - Return true if the fragment is currently added to its activity.

gmetax
  • 3,853
  • 2
  • 31
  • 45
Akshay Goyal
  • 941
  • 9
  • 11
  • This worked for when I had a fragment and a DialogFragment within it was nulling out when coming back to this from another fragment. But I am a little confuse, why does return !isAdded() return; allow the rest of the code to be executed and not crash if the childFragmentManager is still null? Or how does this method not allow the getChildFragmentManager to not be null? – Adam Gardner Jul 31 '17 at 19:14
  • @AdamGardner If you check the android source code for isAdded() you'll see it internally checks if childFragmentManager is null or not, if it's null then isAdded if false. Therefore we return early and don't need an explicit null check for getChildFragmentManager() – Akshay Goyal Aug 02 '17 at 05:54
12

Update the Support Library Revision to 27.0.2 to solve the problem. See changelog.

Floern
  • 33,559
  • 24
  • 104
  • 119
C.BY
  • 129
  • 1
  • 2
10

you can do this

FragmentManager childFragmentManager ;

in onCreate :

childFragmentManager = getChildFragmentManager();

then you can use childFragmentManager in

ViewPagerAdapter adapter = new ViewPagerAdapter(childFragmentManager);
adapter.addFragment(tabLlegadaFragment, "Llegada");
adapter.addFragment(tabIngresoFragment, "Ingreso");
viewPager.setAdapter(adapter);

`

and don't forget before do that you have to check your activity was added or not. you can try this way:

if(getActivity()!=null && isAdded()) //do now
mostafa tayebi
  • 315
  • 2
  • 9
8

I faced this exception today. After looking for answer I noticed that all are related with ViewPager and getFragmentManger() or in my case getChildFragmentManager().

Well sometimes this things happen when there is no fragment so nothing can be attached or shown. Therefore when my fragment was created I now save in a variable the fragment manager, then I use that manager in my Viewpager instance so there will allways be a manager saved in the class. To clarify what I'm saying here's my code:

Before

    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
    adapter.addFragment(tabLlegadaFragment, "Llegada");
    adapter.addFragment(tabIngresoFragment, "Ingreso");
    viewPager.setAdapter(adapter);

Here I faced the error because I recreated the view with some method and I also pressed the back button. So when that happened Android is looking for a getChildFragmentManager() from a Fragment that no longer exists or is gone (because I pressed the back button)

Now

    FragmentManager                 childFragMang;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       View view = inflater.inflate(R.layout.fragment_tab_main, container, false);
       ..
       childFragMang= getChildFragmentManager();
       ..
       return view;

    }

and when I call Viewpager I use that manager

    ViewPagerAdapter adapter = new ViewPagerAdapter(childFragMang);
    adapter.addFragment(tabLlegadaFragment, "Llegada");
    adapter.addFragment(tabIngresoFragment, "Ingreso");
    viewPager.setAdapter(adapter);

I did not face that exception again so it was because my fragment had dissapeared when I pressed back and there were no getChildFragmentManager() to call

Hanako
  • 1,637
  • 1
  • 13
  • 16
5

In all cases,when you using getChildFragmentManager, add isAdded() will beneficial to our application.

BertKing
  • 513
  • 5
  • 13
0

You shouldn't be trying to instantiate Fragments. Fragments are created and have lifecycles that are controlled by the Android system. You respond to lifecycle events by overriding callback methods like onAttached (called when the fragment is attached to its Activity)

G. Blake Meike
  • 6,615
  • 3
  • 24
  • 40