I making my fragment changer helper class and i have some issue with it.
I call it FragmentChanger
It has a fragmentContainer
, which is a ViewGroup
, that holds all the fragments i would like to show.
I have made my own replace(Fragment fragmentToChange, boolean needSaveToBackStack)
function which is:
- Removing the old fragment fom the fragmentContainer
- Adding a new fragment to the fragmentContainer
- Optionally saves to backStack, wether
needSaveToBackStack
istrue
orfalse
.
The error is the follwowing:
If i use my replace function with saving to backStack it is works properly, i can use my device's back button to stepping back and back to previsiously added fragments it is works like a charm.
But when i would like to replace a fragment withOUT saving to backStack, there is something wrong in my code because when i stepping back, i can see on the screen the fragment that i NOT added to the backStack, and ALSO i can see an other previsiously added fragment at the same time!
So i can see 2 fragments at the very same time, like this:
This is my code:
//It is my helper class to handle replacing fragments.
public class FragmentChanger {
// fragmentTransaction
FragmentTransaction fragmentTransaction;
// the container for fragments
ViewGroup fragmentContainer;
// activity ofc
Activity act;
// Ctr: adding a default fragment to be the first so we can see it at app
// start
public FragmentChanger(Activity act, ViewGroup container, Fragment startingFragment) {
this.act = act;
this.fragmentContainer = container;
fragmentTransaction = act.getFragmentManager().beginTransaction();
fragmentTransaction.add(container.getId(), startingFragment, startingFragment.getClass().getSimpleName());
fragmentTransaction.addToBackStack(startingFragment.getClass().getSimpleName());
fragmentTransaction.commit();
}
// Replacing a fragment with an other one
public void replace(Fragment fragmentToChange, boolean needSaveToBackStack) {
fragmentTransaction = act.getFragmentManager().beginTransaction();
// replacing old fragment to the new one!
fragmentTransaction.replace(fragmentContainer.getId(), fragmentToChange, fragmentToChange.getClass().getSimpleName());
// Some null checking, and if the new fragment is NOT equals the current
// fragment
if (getCurrentFragment() != null && getCurrentFragment() != fragmentToChange) {
/*** Important** because something here is wrong ***/
// only addToBackStack when i want it, when needSaveToBackStack =
// true!
if (needSaveToBackStack) {
fragmentTransaction.addToBackStack(fragmentToChange.getClass().getSimpleName());
}
}
// commiting changes
fragmentTransaction.commit();
}
// getting current Fragment
private Fragment getCurrentFragment() {
try {
FragmentManager fragmentManager = act.getFragmentManager();
String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
Fragment currentFragment = act.getFragmentManager().findFragmentByTag(fragmentTag);
return currentFragment;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
// Logging the back stack
public void logBackStack() {
Log("Logging back stack:", "=============");
FragmentManager fragmentManager = act.getFragmentManager();
int stackSize = fragmentManager.getBackStackEntryCount();
Log("Fragments count on the stack: ", stackSize + "");
for (int i = 0; i < stackSize; i++) {
String fragmentTag = fragmentManager.getBackStackEntryAt(i).getName();
Log("Fragment on the stack: ", fragmentTag);
}
}
private void Log(String str, String msg) {
Log.i(str, msg);
}
}
And this is my MainActivity where i test my fragment helper class:
public class MainActivity extends Activity implements OnClickListener {
// My 3 Fragment Classes, could be N other type,
// in this example I only got 3
FragmentA fragmentA;
FragmentB fragmentB;
FragmentC fragmentC;
// Button to add the fragments manually
Button addA, addB, addC;
// This is my activity's container, its a simple viewGroup
// could be anything that can hold fragments
ViewGroup fragmentContainer;
// This is my fragment changer helper class that need some revision by you
// guys
FragmentChanger fragmentChanger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//defining my adding buttons
addA = (Button)findViewById(R.id.addAbtn);
addB = (Button)findViewById(R.id.addBbtn);
addC = (Button)findViewById(R.id.addCbtn);
//setting onclicklistenrs
addA.setOnClickListener(this);
addB.setOnClickListener(this);
addC.setOnClickListener(this);
// defining my main container, this will holds fragments
fragmentContainer = (ViewGroup) findViewById(R.id.fragmentContainer);
// defining my fragments, each of them got an Activity (this), a
// Container (mainContainer), and a Layout ofc.
fragmentA = new FragmentA(this, fragmentContainer, R.layout.fragment_a_layout);
fragmentB = new FragmentB(this, fragmentContainer, R.layout.fragment_b_layout);
fragmentC = new FragmentC(this, fragmentContainer, R.layout.fragment_c_layout);
// defining my fragment changer with an activity(this), a
// container(mainContent) and a starting fragment to show!
fragmentChanger = new FragmentChanger(this, fragmentContainer, fragmentA);
}
@Override
public void onClick(View view) {
if (view.equals(addA)) {
//When adding fragmentA, i always want to save it to backstack
fragmentChanger.replace(fragmentA, true);
} else if (view.equals(addB)) {
//I dont want to save to back stack when adding B
//So if i press back button, i dont want to see fragmentB ever again.
//(But i do see, this is the error.)
fragmentChanger.replace(fragmentB, false);
} else if (view.equals(addC)) {
//When adding fragmentC, i always want to save it to backstack
fragmentChanger.replace(fragmentC, true);
}
//After any modification on fragments, i log the backstack
fragmentChanger.logBackStack();
}
}
Ps: I can clearly see that fragmentB is never on the backStack if i logging the stack each time i replace a Fragment with my helper class. Then why is it appears if i push back button?
I greatly appreciate any advice, this is my first attempt with using fragments with my own helper class and i would like to make it greatly usable.