0

I've been stuck on this for a while now and will appreciate any guidance on this. Also not sure if my title is accurate. Inside my adapter I create a new fragment:

Adapter code:

cardAdoptDetailsFrag nextFrag = new cardAdoptDetailsFrag();

android.support.v4.app.Fragment callingFrag = ((FragmentActivity)context).getSupportFragmentManager().findFragmentByTag("TagFeedFragment");
FragmentTransaction ft = ((FragmentActivity)context).getSupportFragmentManager().beginTransaction();
ft.hide(callingFrag);
ft.add(R.id.fram, nextFrag,"cardAdoptDetailsFrag");
ft.addToBackStack("TagFeedFragment");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();

Then inside my Main Activity where I manage all the fragments, I'm trying to check if the "cardAdoptDetailsFrag" isAdded. For some reason I cannot do it as per the below.

Get Fragment by tag. The below is where it fails with null object reference.

Fragment frag = getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag");
Log.d(TAG, "Check if added: "+frag.isAdded());

Now I know I can just add it inside a method and do a null check and return a boolean, but I know I'm doing something wrong here. Because with my other fragments the isAdded and remove works, but they get initiated inside the Main Activity where "cardAdoptDetailsFrag" gets initiated inside the adapter.

Example of Main Activity:

public class MainActivity extends AppCompatActivity implements adoptFeedFragment.OnFragmentInteractionListener,
        lostAndFoundFragment.OnFragmentInteractionListener,
        servicesFragment.OnFragmentInteractionListener,
        userMenuFragment.OnFragmentInteractionListener,
        showUserAdoptPostsFrag.OnFragmentInteractionListener{

    adoptFeedFragment adoptFeedFragment;
    lostAndFoundFragment lostAndFoundFragment;
    servicesFragment servicesFragment;
    userMenuFragment userMenuFragment;  


    ....

            @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
            adoptFeedFragment = new adoptFeedFragment();
            lostAndFoundFragment = new lostAndFoundFragment();
            servicesFragment = new servicesFragment();
            userMenuFragment = new userMenuFragment();

    ....

    //Here I can do for example:

    adoptFeedFragment.isAdded(); //Will simply return a boolean.

    //Or I can do a remove:

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.remove(adoptFeedFragment);

   //But I cannot do the below:

   Fragment frag = getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag");
   Log.d(TAG, "frag.isAdded(): "+frag.isAdded());

*****Edited Post. Ok lets say the frag is added. Why can I not remove it using the below.

public boolean isAdoptDetailsFragAdded() {
    Fragment frag = getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag");
    if(frag == null){
        return false;
    } else {
        return true;
    }
}

public Fragment getAdoptDetailsFrag() {
    return getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag");
}

//I'm unable to remove the fragment using the below:

Log.d(TAG, "showFeedFragment: "+isAdoptDetailsFragAdded()); <--returns true
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if(isAdoptDetailsFragAdded()) {
        ft.remove(getAdoptDetailsFrag());
    }
    ft.commit();
//Now I check again wether it is still added. And still returns true even though I just removed it.
Log.d(TAG, "showFeedFragment: "+isAdoptDetailsFragAdded()); <-- Still returns true.

    }  
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
Dean Lambrechts
  • 53
  • 1
  • 10

3 Answers3

0

This is my fragment adding or replacing method which i am using in 13 projects. You can use it and get rid of managing fragments.

/**
     * replace or add fragment to the container
     *
     * @param fragment pass android.support.v4.app.Fragment
     * @param bundle pass your extra bundle if any
     * @param popBackStack if true it will clear back stack
     * @param findInStack if true it will load old fragment if found
     */
    public void replaceFragment(Fragment fragment, @Nullable Bundle bundle, boolean popBackStack, boolean findInStack) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        String tag = fragment.getClass().getName();
        Fragment parentFragment;
        if (findInStack && fm.findFragmentByTag(tag) != null) {
            parentFragment = fm.findFragmentByTag(tag);
        } else {
            parentFragment = fragment;
        }
        // if user passes the @bundle in not null, then can be added to the fragment
        if (bundle != null)
            parentFragment.setArguments(bundle);
        else parentFragment.setArguments(null);
        // this is for the very first fragment not to be added into the back stack.
        if (popBackStack) {
            fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        } else {
            ft.addToBackStack(parentFragment.getClass().getName() + "");
        }
        ft.replace(R.id.main_frame_container, parentFragment, tag);
        ft.commit();
        fm.executePendingTransactions();
    }

Here R.id.main_frame_container is FrameLayout in activity layout on which fragment is placed.

Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
0

Here findFragmentByTag() is returning null when you do getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag").

findFragmentByTag() will return null in two cases.

  1. If fragment cardAdoptDetailsFrag is not yet attached to view (you did not call add or replace for this fragment)
  2. You added that fragment, but you are using different TAG, while searching that fragment.

Make sure if non of the case in your problem.

Now the solution is, you can modify your logic, like

Fragment frag = getSupportFragmentManager().findFragmentByTag("cardAdoptDetailsFrag");
if (frag != null && frag.isAdded()) {
   // Do you task. Fragment is added
} else {
   // Fragment is not added yet
}
Pankaj Kumar
  • 81,967
  • 29
  • 167
  • 186
0

I did not went through the long post but I read only this part.

Now I check again wether it is still added. And still returns true even though I just removed it.

And the reason behind that is FragmentTransaction.commit is not synchronous. Read the docs for commit method:

*Schedules a commit of this transaction. The commit does * not happen immediately; it will be scheduled as work on the main thread * to be done the next time that thread is ready.*

If you need that to be synchronous, use commitNow instead.

KR_Android
  • 1,149
  • 9
  • 19