我正在制作一个碎片更改助手类,但遇到了一些问题。
我称其为FragmentChanger
它有一个fragmentContainer
,这是一个ViewGroup
,它包含所有我想要显示的片段。
我已经制作了自己的replace(Fragment fragmentToChange, boolean needSaveToBackStack)
函数:
- 从fragmentContainer中删除旧片段
- 向fragmentContainer添加新片段
- 根据需要保存到backStack,无论
needSaveToBackStack
是true
还是false
.
错误如下:
如果我使用保存到backStack的替换功能,则可以正常工作,我可以使用设备的后退按钮跨越步骤并返回到先前添加的片段,它的效果就像魅力一样。
但是当我想要替换一个不保存到backStack的片段时,我的代码出了问题,因为当我后退时,我可以在屏幕上看到我没有添加到backStack的片段,而且同时我也可以看到另一个之前添加的片段!
所以我可以同时看到2个片段,就像这样:
这是我的代码:
//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);
}
}
这是我的MainActivity,我在这里测试我的片段助手类:
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();
}
提示:如果我在用我的辅助类替换片段时每次记录堆栈,我可以清楚地看到fragmentB从未出现在后备堆栈中。那么为什么按下返回按钮它会出现呢?
非常感谢任何建议,这是我第一次尝试使用自己的帮助类和碎片,并且我希望能够使它更加易于使用。