0

I have written a code where I try to navigate in between fragments 1, 2 ,3 ,4. The navigation is like: 1->2->3->4->2.

Each fragment has a button whose onClickListener calls the method in interface which is implemented by the mainactivity, wherein position is passed as parameter.

e.g. onClick on the button in 4th fragment calls the method wherein I pass the position parameter as '2' to call the second fragment.

Now, I have added the transaction 1->2 to the backstack, Using a backstack name "second". When, I try to go from 4>2, I use the function popBackStackImmediate("second", 0). But, the boolean response is false and nothing is popped from the stack.

My questions are :

  1. Why is popBackStackImmediate returning false?
  2. What is the use of second parameter in the same function i.e flag ?
  3. When we add the transaction in the backstack, the transaction is saved and not the fragment. So, where is the fragment object getting saved actually as the backstack saves the transaction?

The MainActivity in my code is :

`

    public class MainActivity extends AppCompatActivity implements Frag1.OnFragmentInteractionListener, Frag2.OnFragmentInteractionListener, Frag3.OnFragmentInteractionListener, Frag4.OnFragmentInteractionListener {

LinearLayout layout;
Frag1 frag1;
Frag2 frag2;
Frag3 frag3;
Frag4 frag4;
android.support.v4.app.FragmentTransaction transaction;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i("I", "Main Act");
    layout = (LinearLayout) findViewById(R.id.frag);
    frag1 = Frag1.newInstance();

    transaction = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.add(R.id.frag, frag1, "first");
  //  frag1 = Frag1.newInstance();
   // transaction.add(R.id.frag, frag1, "first1");
  //  transaction.add(R.id.frag, frag2, "second");
   // transaction.add(R.id.frag, frag2, "second");
 //  transaction.add(R.id.frag, frag3, "third");
    // Commit the transaction
  //  transaction.add(R.id.frag, frag3, "third");

  //  transaction.replace(R.id.frag, frag2, "second");

    transaction.commit();



}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

// Fragment to activity interface implementation

@Override
public void onFragmentInteraction(int pos) {

    if (pos == 2) {
       // Fragment f = getSupportFragmentManager().findFragmentByTag("second");
        FragmentManager manager = getSupportFragmentManager();

        boolean isAvail =  manager.popBackStackImmediate("second", 0);

        if (isAvail) {
           // frag2 = (Frag2) f;
            Log.i("MainAct", "Instance of 2 yes");
        }else{
            transaction = getSupportFragmentManager().beginTransaction();
           frag2 = Frag2.newInstance();
            Log.i("MainAct", "Instance of 2 No");
            transaction.replace(R.id.frag, frag2, "second");
            transaction.addToBackStack("second");
            transaction.commit();
        }



    } else if (pos == 3) {
        Fragment f = getSupportFragmentManager().findFragmentByTag("third");
        transaction = getSupportFragmentManager().beginTransaction();
        if (f instanceof Frag3) {
            frag3 = (Frag3) f;
            Log.i("MainAct", "Instance of 3 yes");
        }else{
            frag3 = Frag3.newInstance();
            Log.i("MainAct", "Instance of 3 No");
        }
        transaction.replace(R.id.frag, frag3, "third");

        transaction.commit();
        }

    else if (pos == 4) {
        Fragment f = getSupportFragmentManager().findFragmentByTag("four");
        transaction = getSupportFragmentManager().beginTransaction();
        if (f instanceof Frag3) {
            frag4 = (Frag4) f;
            Log.i("MainAct", "Instance of 4 yes");
        }else{
            frag4 = Frag4.newInstance();
            Log.i("MainAct", "Instance of 4 No");
        }
        transaction.replace(R.id.frag, frag4, "four");
        transaction.commit();
    }

    }

}`
Amarjit
  • 4,327
  • 2
  • 34
  • 51
Ayush
  • 121
  • 2
  • 12

1 Answers1

0

You are trying to call popBackStackImmediate("second", 0); instead replace the fragment.

Try this,

  1. Create Interface PageTraveller and implement in MainActivity

    public interface PageTraveller {
        public void openPage(int pageNo);
    }
    
  2. override the method openPage()

         @Override
        public void openPage(int pageNo) {
            android.support.v4.app.Fragment fragment;
            switch (pageNo){
                case 1:
                    fragment = getSupportFragmentManager().findFragmentByTag("fragmentOne");
                    fragmentManager.beginTransaction().replace(R.id.pageContainer,fragment).addToBackStack("fragmentOne").commit();
                    break;
                case 2:
                    fragment = getSupportFragmentManager().findFragmentByTag("fragmentTwo");
                    if (fragment instanceof FragmentTwo)
                        fragmentTwo = (FragmentTwo)fragment;
                    else
                        fragmentTwo = new FragmentTwo();
                    fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentTwo).addToBackStack("fragmentTwo").commit();
                    break;
                case 3:
                    fragment = getSupportFragmentManager().findFragmentByTag("fragmentThree");
                    if (fragment instanceof FragmentTwo)
                        fragmentThree = (FragmentThree)fragment;
                    else
                        fragmentThree = new FragmentThree();
                    fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentThree).addToBackStack("fragmentThree").commit();
                    break;
                case 4:
                    fragment = getSupportFragmentManager().findFragmentByTag("fragmentFour");
                    if (fragment instanceof FragmentTwo)
                        fragmentFour = (FragmentFour)fragment;
                    else
                        fragmentFour = new FragmentFour();
                    fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentFour).addToBackStack("fragmentFour").commit();
                    break;
            }
        }
    
    1. Create First fragment FragmentOne

      public class FragmentOne extends Fragment{ PageTraveller pageTraveller; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View viewOne = inflater.inflate(R.layout.fragment_one,null); Button btnOne = (Button)viewOne.findViewById(R.id.text1); btnOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pageTraveller.openPage(2); } }); return viewOne; } @Override public void onAttach(Context context) { super.onAttach(context); pageTraveller = (PageTraveller) context; } }

    in XML fragment_one add

    <Button
        android:id="@+id/btnOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        android:layout_gravity="center|center_horizontal|center_vertical"
        android:text="Fragment 1"/>
    

    1. Create FragmentTwo, FragmentThree, FragmentFour same way as above. but in your FragmentFour call pageTraveller.openPage(2);

For more reference try 1. go back to the previous fragment in the backstack

  1. Fragments official Android Developer website

Its work for me, try it may help you.

Community
  • 1
  • 1
  • Your answer is correct about replacing fragments, but I my doubt is reagrding the pop method. What is the use of it.. the three questions that I wrote. – Ayush Jan 09 '16 at 13:45
  • `popBackStackImmediate(String name, int flags)` will Pop all back stack states up to the one with the given identifier. If you really want to use your own code for pop the fragment then use `getFragmentManager().popBackStack() `. For more reference refer 1. http://stackoverflow.com/questions/10863572/programmatically-go-back-to-the-previous-fragment-in-the-backstack –  Jan 10 '16 at 15:20