【发布时间】:2014-01-28 13:58:59
【问题描述】:
我正在制作我的片段更换器助手类,但我遇到了一些问题。
我叫它FragmentChanger
它有一个fragmentContainer,它是一个ViewGroup,它包含我想展示的所有片段。
我自己做了replace(Fragment fragmentToChange, boolean needSaveToBackStack)
函数是:
- 从 fragmentContainer 中删除旧片段
- 向 fragmentContainer 添加新片段
- 可选择保存到 backStack,
needSaveToBackStack是true还是false。
错误如下:
如果我使用替换功能并保存到 backStack,它可以正常工作,我可以使用设备的后退按钮来回退并返回到以前添加的片段,这就像一个魅力。
但是当我想替换一个片段 withOUT 保存到 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();
}
}
Ps:如果我每次用我的帮助类替换 Fragment 时都记录堆栈,我可以清楚地看到 FragmentB 永远不会在 backStack 上。 那为什么如果我按下后退按钮会出现?
非常感谢任何建议,这是我第一次尝试将片段与我自己的帮助类一起使用,我想让它变得非常有用。
【问题讨论】:
-
您是否只在示例中单击了 AddB 按钮?您的活动已开始,您只点击了“添加 B”?
-
不,我按随机顺序推送所有这些。