我正在处理以下tutorial,它有问题:它会在每次屏幕旋转后重新创建片段。
我通过在 QuoteViewerActivity 中添加 if(savedInstanceState == null)修复了 TitlesFragment 类:
mFragmentManager = getFragmentManager();
//ADDED THIS CONDITION
if(savedInstanceState == null){
FragmentTransaction fragmentTransaction = mFragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.title_fragment_container, mTitlesFragment);
fragmentTransaction.commit();
}
它修复了Fragment TitlesFragment 但是对于Fragment QuoteFragment ,它仍然会在每次屏幕方向更改时重新创建它,因为在本教程中该片段是在onclick事件中创建的:
@Override
public void onListSelection(int index) {
if (!mDetailsFragment.isAdded()) {
FragmentTransaction fragmentTransaction = mFragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.quote_fragment_container, mDetailsFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
mFragmentManager.executePendingTransactions();
}
if (mDetailsFragment.getShownIndex() != index) {
mDetailsFragment.showIndex(index);
}
}
请注意,setCetainInstance(true)在两个片段中都设置了onCreate()。
我尝试添加此检查,但它没有修复它:
@Override
public void onListSelection(int index) {
//ADDED THE FOLLOWING TWO LINES
Fragment f = mFragmentManager.findFragmentById(R.id.quote_fragment_container);
if(f == null)
//===============================
if (!mDetailsFragment.isAdded()) {
FragmentTransaction fragmentTransaction = mFragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.quote_fragment_container, mDetailsFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
mFragmentManager.executePendingTransactions();
}
if (mDetailsFragment.getShownIndex() != index) {
mDetailsFragment.showIndex(index);
}
}
==>每次旋转屏幕并复制现有菜单时,它都会重新创建此片段(在此快照中说明):
答案 0 :(得分:1)
此行无法找到您尝试查找的片段:
Fragment f = mFragmentManager.findFragmentById(R.id.quote_fragment_container);
您提供了容器(布局)ID。此方法可用于查找从XML布局中膨胀的片段。
如果您想从代码管理片段,请使用tag
。使用FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
添加片段。提供tag
您可以稍后使用FragmentManager.findFragmentByTag(String tag)
找到该片段。让tag
某种static final String
不变是一个好主意,使自动重构变得轻而易举。
您可能也对方法FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
感兴趣 - 它使片段替换更容易。
答案 1 :(得分:0)
在本特定教程中,此问题的解决方案通过以下方式解决:
以下是我在代码中添加/更改的内容:
.....
private QuoteFragment mDetailsFragment = new QuoteFragment();//REMOVED final attribute
......
//ADDED
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(mFragmentManager.findFragmentByTag(quote_fragment_tag)!=null)
getFragmentManager().putFragment(outState, QuoteFragment.class.getName(), mDetailsFragment);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TitleArray = getResources().getStringArray(R.array.Titles);
QuoteArray = getResources().getStringArray(R.array.Quotes);
setContentView(R.layout.main);
mFragmentManager = getFragmentManager();
// ADDED
if(savedInstanceState == null){
FragmentTransaction fragmentTransaction = mFragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.title_fragment_container, mTitlesFragment);
fragmentTransaction.commit();
}
else{//ADDED
mDetailsFragment = (QuoteFragment) getFragmentManager()
.getFragment(savedInstanceState, QuoteFragment.class.getName());
if(mDetailsFragment == null){
mDetailsFragment = new QuoteFragment();
mFragmentManager.beginTransaction()
.add(R.id.quote_fragment_container, mDetailsFragment,quote_fragment_tag)
.addToBackStack(null)
.commit();
mFragmentManager.executePendingTransactions();
}
}
}
答案 2 :(得分:0)
另一个简单的解决方案。添加
menu.clear()
在片段
中的onCreateOptionsMenu方法中膨胀菜单之前 @Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu_main, menu);
}